Skip to content

hooks

介绍模板项目中现有hooks内容。

useCheckPermission

通过函数的方式控制用户操作权限。

使用方式

vue
<template>
  <section class="page-container">
    <el-button
      v-if="useCheckPermission(['ALARM_PAGE.U'])"
      v-blur
      type="primary"
    >
      添加
    </el-button>
  </section>
</template>

<script setup lang="ts">
  // import { useCheckPermission } from '@/hooks/index'; // hooks中文件已被注入 hooks/index 中
  // 或者
  import { useCheckPermission } from '@/hooks/use-check-permission/index';
</script>

实现源码见src/hooks/use-check-permission/index

ts
/**
 * @description: 检查用户是否具有某一个权限(只校验菜单和组件的code,不包含操作code)
 * @param {string} code 校验权限的code
 * 使用方式:
 * useCheckPermission(['ALARM_PAGE'])
 * useCheckPermission(['ALARM_PAGE.U'])
 */
import { useUserStore } from '@/store/user';
import { intersection } from '@/utils/index';

export const useCheckPermission = (authCodes: string[]): boolean => {
  const userStore = useUserStore();
  const authKeys: string[] = userStore.authKeys;

  return intersection(authKeys, authCodes).length > 0;
};

useNamespace

定义符合BEM风格的类名。

使用方式

vue
<template>
  <section :class="ns.b('header')">
  <!-- 顶部导航内容 -->
  <!-- 添加类名符合BEM风格, ns.b(), ns.be(),ns.bem()等 -->
  </section>
</template>

<script setup lang="ts">
  // import { useNamespace } from '@/hooks/index'; // hooks中文件已被注入 hooks/index 中
  // 或者
  import { useNamespace } from '@/hooks/use-namespace/index';

  const ns = useNamespace('app');
</script>

实现源码见src/hooks/use-namespace/index

ts
export const defaultNamespace = 'lf';
const statePrefix = 'is-';

const _bem = (
  namespace: string,
  block: string,
  blockSuffix: string,
  element: string,
  modifier: string
) => {
  let cls = `${namespace}-${block}`;
  if (blockSuffix) {
    cls += `-${blockSuffix}`;
  }
  if (element) {
    cls += `__${element}`;
  }
  if (modifier) {
    cls += `--${modifier}`;
  }
  return cls;
};

export const useNamespace = (block: string) => {
  const namespace = defaultNamespace;

  const b = (blockSuffix = '') => _bem(namespace, block, blockSuffix, '', '');
  const e = (element?: string) => (element ? _bem(namespace, block, '', element, '') : '');
  const m = (modifier?: string) => (modifier ? _bem(namespace, block, '', '', modifier) : '');

  const be = (blockSuffix?: string, element?: string) => (blockSuffix && element
    ? _bem(namespace, block, blockSuffix, element, '')
    : '');
  const em = (element?: string, modifier?: string) => (element && modifier
    ? _bem(namespace, block, '', element, modifier)
    : '');
  const bm = (blockSuffix?: string, modifier?: string) => (blockSuffix && modifier
    ? _bem(namespace, block, blockSuffix, '', modifier)
    : '');
  const bem = (blockSuffix?: string, element?: string, modifier?: string) => (blockSuffix && element && modifier
    ? _bem(namespace, block, blockSuffix, element, modifier)
    : '');

  const is: {
    (name: string, state: boolean | undefined): string
    (name: string): string
  } = (name: string, ...args: [boolean | undefined] | []) => {
    const state = args.length >= 1 ? args[0]! : true; // '!' 后置为断言,表示args[0]不可能为undefined或者null
    return name && state ? `${statePrefix}${name}` : '';
  };

  /*
   * for css var
   * --el-xxx: value;
   */
  const cssVar = (object: Record<string, string>) => {
    const styles: Record<string, string> = {};
    for (const key in object) {
      if (object[key]) {
        styles[`--${namespace}-${key}`] = object[key];
      }
    }
    return styles;
  };
  // with block
  const cssVarBlock = (object: Record<string, string>) => {
    const styles: Record<string, string> = {};
    for (const key in object) {
      if (object[key]) {
        styles[`--${namespace}-${block}-${key}`] = object[key];
      }
    }
    return styles;
  };

  const cssVarName = (name: string) => `--${namespace}-${name}`;
  const cssVarBlockName = (name: string) => `--${namespace}-${block}-${name}`;

  return {
    namespace,
    b,
    e,
    m,
    be,
    em,
    bm,
    bem,
    is,

    // css
    cssVar,
    cssVarName,
    cssVarBlock,
    cssVarBlockName,
  };
};

useResize

自适应控制模板中左侧导航的显示与隐藏。

使用方式

vue
<script setup lang="ts">
  // import { useResize } from '@/hooks/index'; // hooks中文件已被注入 hooks/index 中
  // 或者
  import { useResize } from '@/hooks/use-resize/index';

  useResize()
</script>

实现源码见src/hooks/use-resize/index

ts
import { onBeforeMount, onBeforeUnmount, onMounted } from 'vue';
import { useAppStore } from '@/store/app';

const _width = 992;
export const useResize = () => {
  const isMobile = () => {
    const rect = document.body.getBoundingClientRect();
    return rect.width - 1 < _width;
  };

  const setDevice = () => {
    useAppStore().setDevice(isMobile() ? 'mobile' : 'desktop');
  };

  const setCollapseStatus = () => {
    const mobile = isMobile();
    if (mobile) {
      useAppStore().setCollapseStatus(true);
    } else {
      useAppStore().setCollapseStatus(false);
    }
  };

  const resizeHandler = () => {
    if (!document.hidden) {
      setDevice();
      setCollapseStatus();
    }
  };

  onBeforeMount(() => {
    window.addEventListener('resize', resizeHandler);
  });
  onBeforeUnmount(() => {
    window.removeEventListener('resize', resizeHandler);
  });
  onMounted(() => {
    setDevice();
    setCollapseStatus();
  });
};

内容由donymh提供,如有疑问,请微信联系lmingh6