Access Control 
For frontend applications, "access control" refers to whether pages are accessible and whether page elements are visible.
Setup 
- Install the plugin
$ npm add @winner-fed/plugin-access -D$ yarn add @winner-fed/plugin-access -D$ pnpm add @winner-fed/plugin-access -D$ bun add @winner-fed/plugin-access -D- Enable the plugin in the .winrcconfiguration file
import { defineConfig } from 'win';
export default defineConfig({
  plugins: ['@winner-fed/plugin-access'],
  routes: [{
    path: '/',
    name: 'Home',
    component: 'index',
    routes: [
      {
        path: 'admin',
        name: 'Admin',
        component: '@/components/admin'
      },
      {
        path: 'normal',
        name: 'Normal',
        component: '@/components/normal'
      }
    ]
  }],
  /**
   * @name Access Control Plugin
   * @doc https://winjs-dev.github.io/winjs-docs/plugins/access.html
   */
  access: {
    roles: {
      admin: ['/admin'],
      normal: ['/normal']
    }
  }
});Introduction 
In this plugin design, one page permission corresponds to one route. For example, when accessing the '/admin' route, if the current role doesn't have permission for this route, the component will not be rendered.
export default {
  access: {
    roles: {
      admin: ['/admin'],
      normal: ['/normal']
    }
  }
};Usage example:
<template>
  <Access :id="accessId">Only visible to Admin</Access>
  <div v-access="accessId">Only visible to Admin</div>
</template>
<script setup lang="ts">
const accessId = '/admin';
</script>Note
We uniformly refer to pages and page elements as resources, and use resource IDs to identify and distinguish them:
- The resource ID of a page defaults to the page's route path. For example, the routepathof pagepages/a.vueis/a. When the page accesses/a, the current page will be rendered, and/ais the page'saccessId.
- Page elements' resource IDs have no default value and need to be customized.
Matching Rules 
Exact Matching 
The default matching rule for resources is exact matching. For example, if page pages/a.vue corresponds to route path /a, then /a is the page's resource ID. If we set:
access.setAccess(['/a']);Since the permission list contains /a, it indicates having permission for this page.
Fuzzy Matching 
Page @id.vue will be mapped to dynamic route /:id. There are two ways to match this page:
- access.setAccess(['/:id'])
- access.setAccess(['/*'])
The second is fuzzy matching, where * represents any path. For example, if role admin needs full permissions:
export default {
  access: {
    roles: {
      admin: ['*']
    }
  }
};Compile-time Configuration 
When executing win dev or win build, runtime code is generated through this configuration. Configure in the .winrc.js configuration file:
export default {
  access: {
    roles: {
      admin: ['/', '/admin', '/normal'],
    },
  },
};roles 
- Type: - Record<string, []>;
- Default: - {}
- Details: - Predefined role list. - keyis the role ID, and- valueis the resource list corresponding to the role ID.
Runtime Configuration 
Configure in app.js
unAccessHandler 
- Type: - Function
- Default: - null
- Details: When entering a route, if the page corresponding to the route doesn't belong to the visible resource list, entry will be paused and the - unAccessHandlerfunction will be called.
- Parameters - router: Router instance created by createRouter
- to: Route being navigated to
- from: Route being navigated away from
- next: next function
 
Example:
import { access as accessApi } from 'winjs';
export const access = {
  unAccessHandler ({ to, next }) {
    const accesssIds = accessApi.getAccess();
    if (to.path === '/404') {
      accessApi.setAccess(accesssIds.concat(['/404']));
      return next('/404');
    }
    if (!accesssIds.includes('/403')) {
      accessApi.setAccess(accesssIds.concat(['/403']));
    }
    next('/403');
  },
};noFoundHandler 
- Type: Function
- Default: null
- Details: When entering a route, if the page corresponding to the route doesn't exist, the noFoundHandlerfunction will be called.
- Parameters- router: Router instance created by createRouter
- to: Route being navigated to
- from: Route being navigated away from
- next: next function
 
Example:
import { access as accessApi } from 'winjs';
export const access = {
  noFoundHandler ({ next }) {
    const accesssIds = accessApi.getAccess();
    if (!accesssIds.includes('/404')) {
      accessApi.setAccess(accesssIds.concat(['/404']));
    }
    next('/404');
  },
};ignoreAccess 
- Type: Array<string>
- Default: null
- Details: Configure pages that should ignore access control validation.
Example:
export const access = {
  ignoreAccess: ['/login'],
};API 
WinJS uses custom directives, specifically the v-access directive, passing in the object returned by useAccess to control component rendering.
Plugin APIs are exported through winjs:
import { access } from 'winjs';access.hasAccess 
- Type: ( accessId: string | number ) => Promise\<boolean\>
- Details: Determine whether a resource is visible.
- Parameters: - accessId: Resource ID
 
- Returns: Whether access is granted
access.isDataReady 
- Type: () => boolean
- Details: Permissions can be set using asynchronous data. isDataReadyis used to determine whether asynchronous data has finished loading.
- Parameters: null
- Returns: Boolean
import { access } from 'winjs';
console.log(access.isDataReady());access.setRole 
- Type: Function
- Details: Set the current role.
- Parameters:
- roleId: Role ID, has two types: - String: Corresponds to the keyin therolesconfiguration object.
- Promise: The result of Promise resolve should correspond to the keyin therolesconfiguration object.
 
- String: Corresponds to the 
import { access } from 'winjs';
access.setRole('admin');access.getRole 
- Type: Function
- Details: Get the current role.
import { access } from 'winjs';
access.getRole();access.setAccess 
- Type: Function
- Details: Set the current access permissions.
- Parameters:
- accessIds: Array of resource IDs, has two types: - Array: Array items correspond to the keyin therolesconfiguration object.
- Promise: The result of Promise resolve should be Array<accessId>.
 
- Array: Array items correspond to the 
import { access } from 'winjs';
access.setAccess(['/a', '/b', '/c']);access.getAccess 
- Type: Function
- Details: Return the current list of visible resources.
- Parameters: null
import { access } from 'winjs';
access.getAccess();useAccess 
- Type: Composition function
- Details: Determine whether a resource is visible.
- Parameters: - accessId: Resource ID
 
- Returns: ref
<template>
  <div v-if="accessOnepicess">accessOnepicess</div>
</template>
<script>
import { useAccess } from 'winjs';
export default {
  setup () {
    const accessOnepicess = useAccess('/onepiece1');
    return {
      accessOnepicess,
    };
  },
};
</script>v-access 
Pass accessId into the v-access directive. When accessId has permission, the DOM will be displayed; when there's no permission, the DOM will be hidden.
<template>
  <div v-access="accessId">accessOnepicess</div>
</template>
<script>
export default {
  setup () {
    return {
      accessId: 'accessOnepicess',
    };
  },
};
</script>Access Component 
Pass accessId into the Access component. When accessId has permission, this component will be rendered; when there's no permission, this component will be hidden.
<template>
  <access :id="accessId"> accessOnepicess</access>
</template>
<script>
export default {
  setup () {
    return {
      accessId: 'accessOnepicess',
    };
  },
};
</script>