npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@toystory/lotso

v2.2.8

Published

A framework of admin system, base on Vue3.

Downloads

36

Readme

后台管理系统脚手架

基于Vue3.0,使用Element Plus框架,Vite构建

安装

yarn add @toystory/lotso -S
# OR
npm i @toystory/lotso -S

使用

一、注册

在main.js中引入,示例如下:

import options from '@/config/setting'
import requestConfig from '@/config/request.config'

import { createFrameApp, useRouter, usePermission, useUserStore, useRoutesStore } from '@toystory/lotso'
import '@toystory/lotso/dist/style.css'

import { getUserInfo, getAuthData } from '@/api'
import App from './App.vue'


// 注册框架,传入项目配置和store,页面路径
const app = createFrameApp(App, {
  options,
  requestConfig,
  constantFile: import.meta.glob('./pages/**/index.vue'),
  constantConfig: import.meta.globEager('./pages/**/config.js'),
  // 若配置接管权限路由,无需引入asyncFile
  asyncFile: import.meta.glob('./views/**/index.vue'),
  asyncConfig: import.meta.globEager('./views/**/config.js')
})

app.mount('#app')

// 使用脚手架自带的守卫
const { router } = useRouter()
const { handlePermission } = usePermission({
  // 需要把获取用户信息的方法和获取数据权限的方法传递给Permission hooks
  getUserInfo: async () => {
    // ...
  },
  getAuthData: async () => {
    // ...
  }
})
router.beforeEach((to, from, next) => {
  handlePermission(to, from, next)
})

二、配置文件参考

  1. setting.js
export default {
  // 是否显示顶部进度条
  progressBar: true,
  // 菜单栏默认打开路由
  defaultOpeneds: [],
  // vertical布局时是否只保持一个子菜单的展开
  uniqueOpened: false,
  // token名称
  tokenName: 'accessToken',
  // 是否跳过登录
  skipLogin: true,
  // default language
  lang: 'zh-cn',
  // 标题
  title: '海通恒信后台管理系统',
  // 系统名称
  systemName: 'HTHX-ADMIN',
  // 版权信息
  copyrightZh: '版权所有 © 海通恒信国际融资租赁股份有限公司 未经许可不得复制、转载或摘编,违者必究!',
  copyrightEn: 'Copyright © Haitong Unitrust International Leasing CO.,LTD.All Rights Reserved',
  // 默认主题颜色
  themeColor: '#005BAC',
  // 默认左侧菜单背景颜色
  leftMenuBgColor: '#0d153c',
  // 默认顶部菜单背景颜色
  topMenuBgColor: '#ffffff',
  // 默认左侧菜单文字颜色
  leftMenuTextColor: '#FFF',
  // 默认顶部菜单文字颜色
  topMenuTextColor: '#333',
  // 是否显示用户名
  showName: false,
  // 头部工具栏布局
  showHeaderBar: false,
  // 是否显示页面底部自定义版权信息
  footerCopyright: true,
  // token失效回退到登录页时是否记录本次的路由
  recordRoute: true,
  // 是否显示全屏
  fullScreen: true,
  // 是否显示刷新
  refresh: true,
  // 是否显示通知
  notice: true,
  // 是否显示自定义主题
  hideTheme: false,
  // 是否隐藏头像
  hideAvatar: false,
  // 是否显示面包导航
  isBreadcrumb: true,
  // 是否显示logo
  isLogo: true,
  // logo图片 相对于public/static/image的路径
  logo: 'logo.png',
  // 菜单栏logo
  sideLogo: 'side-logo.png',
  // 是否显示标签
  tag: true,
  // 是否展开菜单
  collapse: false,
  // 路由白名单不经过token校验的路由
  routesWhiteList: ['/login', '/register', '/404', '/401'],
  // 权限信息白名单
  whiteAuthData: [
    {
      children: [
        {
          children: [],
          elements: [],
          menuType: 3,
          sort: 0,
          menu: 'homeIndex'
        }
      ],
      elements: [],
      menuType: 3,
      sort: 0,
      menu: 'home'
    }
  ],
  // 默认首页页面
  defaultPath: '/home',
  // 默认添加进路由表中的路由
  defaultRoutes: [],
  // 是否使用hash模式
  useHash: false,
  // base路径
  baseURL: '',
  // 登录页面路径,默认为'/login',可配置SSO路径,建议用环境变量
  loginPath: import.meta.env.VITE_APP_SSO_URL
  // px2rem基准单位,注意与vite配置中的基准单位保持一致
  remRootValue: 19.2,
  // 是否固定导航
  isFixedNav: true
}
  1. request.config.js
export default {
  // axios 基础url地址
  baseURL: import.meta.env.VITE_APP_BASE_API,
  // 网关请求地址前缀:
  gatewayPrefix: import.meta.env.VITE_APP_GATEWAY,
  // 为开发服务器配置 CORS。默认启用并允许任何源,传递一个 选项对象 来调整行为或设为 false 表示禁用
  cors: true,
  // 根据后端定义配置
  contentType: 'application/json;charset=UTF-8',
  // 消息框消失时间
  messageDuration: 3000,
  // 最长请求时间
  requestTimeout: 60000,
  // 请求拦截自定义函数,接收config参数
  handleRequest: config => {
    // do something ...
  },
  // 返回成功拦截自定义函数,接收response参数
  handleResSuccess: undefined,
  // 返回成功拦截自定义函数,接收response error参数
  handleResError: undefined
}
  1. compile.config.js
export default {
  // 项目部署的基础路径
  base: '/',
  // 静态资源服务的文件夹 类型 string | false
  publicDir: 'public',
  // 存储缓存文件的目录
  cacheDir: 'node_modules/.vite',
  // 输出路径
  outDir: 'dist',
  // 为开发服务器配置 CORS。默认启用并允许任何源,传递一个 选项对象 来调整行为或设为 false 表示禁用
  cors: true,
  // 生成静态资源的存放路径
  assetsDir: 'static/',
  // 构建后是否生成 source map 文件
  sourcemap: process.env.NODE_ENV !== 'production',
  // chunk 大小警告的限制
  chunkSizeWarningLimit: 2000,
  // 启用/禁用 CSS 代码拆分
  // 压缩大型输出文件可能会很慢,因此禁用该功能可能会提高大型项目的构建性能。
  cssCodeSplit: true,
  // 启用/禁用 brotli 压缩大小报告
  brotliSize: false,
  // 指定服务器应该监听哪个 IP 地址
  host: '0.0.0.0',
  // 指定开发服务器端口
  port: '8899',
  // 设为 true 时若端口已被占用则会直接退出,而不是尝试下一个可用端口
  strictPort: false,
  // 服务器启动时自动在浏览器中打开应用程序 此值为字符串时,会被用作 URL 的路径名
  open: true,
  // 调整控制台输出的级别 'info' | 'warn' | 'error' | 'silent'
  logLevel: 'info',
  // 设为 false 可以避免 Vite 清屏而错过在终端中打印某些关键信息
  clearScreen: false,
  // 是否删除生产环境console
  dropConsole: process.env.NODE_ENV === 'production',
  // 是否删除生产环境debugger
  dropDebugger: process.env.NODE_ENV === 'production',
  // 代理后端地址
  proxy: {
    // 正则表达式写法
    '^/api/.*': {
      target: 'http://10.102.2.222:19005',
      changeOrigin: true,
      rewrite: (path) => path.replace(/^\/api/, '')
    }
  },
  // 是否使用mock数据
  useMock: true,
  // 是否使用图片压缩
  useImageMin: false,
  // 是否使用px2rem
  usePx2Rem: false
}

API

createFrameApp()

框架初始化注册函数,创建一个应用实例

createFrameApp(rootComponent: Component, options: object): App

有两个必传参数,其中第一个参数是根组件。第二个参数是要传递给框架的配置参数。

示例:

import options from '@/config/setting' // 配置文件,请参考上方说明
import requestConfig from '@/config/request.config' // 配置文件,请参考上方说明

import { createFrameApp } from '@toystory/lotso'
import '@toystory/lotso/dist/style.css'
import App from './App.vue'

// 注册框架,传入项目配置和store,页面路径
const app = createFrameApp(App, {
  options,
  requestConfig,
  constantFile: import.meta.glob('./pages/**/index.vue'),
  constantConfig: import.meta.globEager('./pages/**/config.js'),
  // 若配置接管权限路由,无需引入asyncFile
  asyncFile: import.meta.glob('./views/**/index.vue'),
  asyncConfig: import.meta.globEager('./views/**/config.js')
})
app.mount('#app')

useRouter()

脚手架已接管路由管理,可用此方法访问路由,类似于VueRouter提供的useRouter方法

返回对象包含四个值:

  1. constantRoutes

不参与权限校验管理生成的路由集合,即初始化时通过constantFileconstantConfig传入的文件

  1. asyncRoutes

参与权限校验管理的路由集合,即初始化时通过asyncFileasyncConfig传入的文件

  1. router

VueRouter提供的原生 router 对象

  1. resetRouter()

重置Router方法

useRoute()

可用此方法返回当前路由对象

示例:

import { useRouter, useRoute } from '@toystory/lotso'

const { constantRoutes, asyncRoutes, router, resetRouter } = useRouter()
const route = useRoute()

function pushWithQuery(query) {
    router.push({
      name: 'search',
      query: {
        ...route.query,
        ...query,
      },
    })
}

usePermission()

权限管理的钩子函数,必传对象参数getUserInfogetAuthData,分别为获取用户信息方法与获取权限数据方法,返回值必须分别为用户信息数据与权限数据,建议两个方法内为调用获取用户信息接口与调用权限数据接口

返回值为权限处理导航守卫方法,使用方式参考如下

示例:

import { useRouter, usePermission } from '@toystory/lotso'
import { getUserInfo, getAuthData } from '@/api'
import { ElMessage } from 'element-plus'

// 使用脚手架自带的守卫
const { router } = useRouter()
const { handlePermission } = usePermission({
  // 需要把获取用户信息的方法和获取数据权限的方法传递给Permission hooks
  getUserInfo: async () => {
    const { data, msg, message } = await getUserInfo()
    const userStore = useUserStore()
    if (data && Object.prototype.toString.call(data) === '[object Object]') {
      userStore.setUserInfo(data)
      const targetSystemName = options.systemName || 'HTHX'
      userStore.setSystemCode(targetSystemName)
      window.localStorage.setItem('systemCode', targetSystemName)
      if (data.staffName) {
        userStore.handlerUserName(data.staffName)
      }
    } else {
      const errorMsg = msg || message || '系统错误,请稍后重试'
      userStore.resetToken()
      ElMessage.error(errorMsg)
      throw new Error(errorMsg)
    }
  },
  getAuthData: async () => {
    const userStore = useUserStore()
    const routesStore = useRoutesStore()
    await getAuthData().then(response => {
      userStore.setAuthDataFlag(true)
      if (response.data && Object.prototype.toString.call(response.data) === '[object Object]') {
        const whiteAuthData = options.whiteAuthData
        const authData = response.data.data
        const { role } = response.data
        userStore.setRole(role || [])
        const data = [
          ...whiteAuthData,
          ...authData
        ]
        if (!data || !Array.isArray(data)) {
          console.error('权限数据错误')
        } else {
          userStore.setAuthData(data)
          routesStore.handleRoutes(data)
        }
      } else {
        const errorMsg = response.msg || response.message || '系统错误,请稍后重试'
        ElMessage.error(errorMsg)
        throw new Error(errorMsg)
      }
    }).catch(err => {
      userStore.setAuthDataFlag(true)
      throw new Error(err)
    })
  }
})
router.beforeEach((to, from, next) => {
  handlePermission(to, from, next)
})

useRequest()

脚手架中包装好的请求拦截器钩子函数,一般在包装api请求方法中使用

示例:

import { useRequest } from '@toystory/lotso'
import requestConfig from '@/config/request.config'

const request = useRequest(requestConfig)

export function createPoint(data) {
  return request({
    url: '/point/create'p
    method: 'post',
    data
  })
}

setConfig()

修改传入脚手架中的配置项

setConfig(options: object)

getConfig()

获取脚手架中的某个配置项

示例:

const copyrightZh = getConfig('copyrightZh')

setupStore()

脚手架封装的注册pinia实例的方法,已默认在脚手架中注册,正常情况无需重复注册

useUserStore()

调用该钩子函数可以使用脚手架内部注册的pinia模块:userStore,pinia使用方法可参考官方文档

  • state

    | key | 类型 | 描述 | | ------------ | ------- | -------------------- | | token | string | 登录秘钥 | | username | string | 用户名 | | userInfo | object | 用户信息 | | avatar | string | 头像 | | authDataFlag | boolean | 是否拉取权限数据标识 | | isChangeUser | boolean | 是否更换用户标识 | | systemCode | string | 系统编码 | | authData | Array | 权限数据 | | role | object | 角色信息 |

  • getters

    | 方法 | 返回值 | 描述 | | ------------------- | ------- | -------------------- | | getToken() | string | 获取登录秘钥 | | getUsername() | string | 获取用户名 | | getAvatar() | string | 获取头像 | | getUserInfo() | object | 获取用户信息 | | getAuthDataFlag() | boolean | 获取拉取权限数据标识 | | getIsChangeUser() | boolean | 获取更换用户标识 | | getSystemCode() | string | 获取系统编码 | | getAuthData() | Array | 获取权限数据 |

  • actions

    | 方法 | 入参类型 | 描述 | | --------------------------- | -------- | ---------------------------- | | setToken(val) | string | 存储登录秘钥 | | setUsername(val) | string | 存储用户名 | | setAvatar(val) | string | 存储头像 | | setSystemCode(val) | string | 存储系统编码 | | setAuthDataFlag(flag) | boolean | 设置拉取权限数据标识 | | setIsChangeUser(flag) | boolean | 设置更换用户标识 | | setUserInfo(data) | object | 存储用户信息 | | setAuthData(data) | Array | 存储权限数据 | | setRole(data) | object | 存储角色信息 | | handlerUserName(userName) | string | 处理用户名来判断用户是否变更 | | resetInfo() | \ | 清除用户信息 | | resetToken() | \ | 清除登录信息 |

useTabsBarStore()

  • state

    | key | 类型 | 描述 | | ------------- | ------- | --------------- | | visitedRoutes | Array | tabs的路由列表 | | isTabsShow | boolean | 是否显示tabsBar |

  • getters

    | 方法 | 返回值 | 描述 | | -------------------- | ------- | ------------------- | | getVisitedRoutes() | Array | 获取tabs的路由列表 | | getIsTabsShow() | boolean | 获取是否显示tabsBar |

  • actions

    | 方法 | 入参类型 | 描述 | | --------------------------- | --------- | --------------------- | | addVisitedRoute(route) | route对象 | 新增tab | | toggleTabsShow() | \ | 显示/隐藏tabsBar | | delRoute(route) | route对象 | 删除tab | | delOthersRoutes(route) | route对象 | 删除除此以外的所有tab | | delLeftRoutes(route) | route对象 | 删除左边的所有tab | | delRightRoutes(route) | route对象 | 删除右边的所有tab | | delAllRoutes() | \ | 删除所有tab | | updateVisitedRoute(route) | route对象 | 更新tab信息 |

useRoutesStore()

  • state

    | key | 类型 | 描述 | | -------------- | ----- | ---------------- | | routes | Array | 所有路由 | | asyncRoutes | Array | 已注册的动态路由 | | topMenuRoutes | Array | 顶部菜单路由 | | leftMenuRoutes | Array | 左边菜单路由 |

  • getters

    | 方法 | 返回值 | 描述 | | --------------------- | ------ | -------------------- | | getRoutes() | Array | 获取所有路由 | | getAsyncRoutes() | Array | 获取已注册的动态路由 | | getTopMenuRoutes() | Array | 获取顶部菜单路由 | | getLeftMenuRoutes() | Array | 获取左边菜单路由 |

  • actions

    | 方法 | 入参类型 | 描述 | | ------------------------ | -------- | -------------------- | | handleRoutes(authData) | 权限数据 | 根据权限数据注册路由 | | setAllRoutes() | \ | 注册所有路由 |

useNoticeStore()

  • state

    | key | 类型 | 描述 | | -------------- | -------- | ------------ | | noticeList | Array | 通知列表 | | messageList | Array | 消息列表 | | mailList | Array | 邮件列表 | | noticeCallback | Function | 通知回调函数 | | badge | String | 通知栏角标 |

  • getters

    | 方法 | 返回值 | 描述 | | ------------------ | ------ | ------------ | | getNoticeList() | Array | 获取通知列表 | | getMessageList() | Array | 获取消息列表 | | getMailList() | Array | 获取邮件列表 |

  • actions

    | 方法 | 入参类型 | 描述 | | -------------------------- | -------- | -------------------- | | setNoticeList(data) | Array | 设置通知列表 | | setMessageList(data) | Array | 设置消息列表 | | setMailList(data) | Array | 设置邮件列表 | | setNoticeCallback(cb) | Function | 设置通知点击回调函数 | | emitNoticeCallback(item) | Object | 执行通知点击回调函数 | | setBadge(data) | String | 设置通知栏角标 |

useSettingStore()

该store内的数据与方法主要为脚手架内部调用状态使用,请谨慎调用!

mitt

脚手架封装的mitt对象,用于监听脚手架广播出来的事件或自定义广播

包含on(监听),off(取消监听),emit(广播)三个方法

示例:

import { mitt } from '@toystory/lotso'

mitt.on('logout', () => {
  // ...
})

mitt.on('avatarClick', () => {
  // ...
})

vpermission

脚手架封装的指令方法,已默认在脚手架中注册,正常情况无需重复注册。

传入disabled参数可使无权限的按钮等禁用,避免被移除。

<el-button v-permission="'default'">Default</el-button>
<el-button v-permission:disabled="'default'" type="info">Info</el-button>

useAuth(name: string)

判断是否具有权限的钩子函数,返回布尔值

示例:

import { useAuth } from '@toystory/lotso'

const hasAuth = useAuth('elementName')

if (hasAuth) {
  // do something
}

store

pinia实例,脚手架内部注册完成后的暴露出来的pinia实例

layout

layout组件vue全局注册对象,已默认在脚手架中注册,正常情况无需重复注册

Layout

Layout vue组件模块,即包含菜单与工具栏的框架

ParentView

ParentView vue组件模块,即不包含菜单的框架