👊 Vue3.4+Element-plus+Vite通用后台管理系统(自用)

网上的后台管理系统模版一大堆,删起来麻烦,xjy_admin是我自己搭建的通用后台管理模板,并不断完善中......

🔥 前言

经过一段时间的打磨(具体忘了),迎来管理系统的第一个版本, 相较于其他后台管理模板,本后台管理模版只包含基本的刷新,全屏以及暗黑模式效果。本模板只供学习使用,难免会存在一些bug,还请见谅。

😀 项目介绍

一个基于Vue3.4+Element-plus+Vite搭建的轻量级后台管理模板,本项目分一个登录接口和一个用户信息接口,并且采用mockjs模拟数据,有简单的权限划分。

✨ 效果展示

在线预览

xjy_admin

仓库地址Gitee

xjy_dmin

首页

🏅 技术栈

技术栈 描述 官网
Vue3 渐进式JavaScript框架 cn.vuejs.org/
Element-plus 基于 Vue 3,面向设计师和开发者的组件库 element-plus.org/zh-CN/
Vite 前端构建工具 vitejs.cn/vite3-cn/
Pinia 符合直觉的 Vue.js 状态管理库 pinia.web3doc.top/
tinymce 功能强大、所见即所得的富文本编辑器 tinymce.ax-z.cn/
Echarts 一个基于 JavaScript 的开源可视化图表库 echarts.apache.org/zh/index.ht...
VueUse 基于Vue组合式API的实用工具集 www.vueusejs.com/
animate.css 一个现成的跨浏览器动画库 animate.style/

🌈 项目基本配置

项目全局配置

代码统一规范

  • Eslint:语法规则和代码风格检查
  • Prettier:美化代码样式
  • Stylelint: CSS 统一规范和代码检测

.eslintrc.cjs

js 复制代码
// @see https://eslint.bootcss.com/docs/rules/
module.exports = {
    env: {
        browser: true,
        es2021: true,
        node: true,
        jest: true,
    },
    /* 指定如何解析语法 */
    parser: 'vue-eslint-parser',
    /** 优先级低于 parse 的语法解析配置 */
    parserOptions: {
        ecmaVersion: 'latest',
        sourceType: 'module',
        parser: '@typescript-eslint/parser',
        jsxPragma: 'React',
        ecmaFeatures: {
            jsx: true,
        },
    },
    /* 继承已有的规则 */
    extends: [
        'eslint:recommended',
        'plugin:vue/vue3-essential',
        'plugin:@typescript-eslint/recommended',
        'plugin:prettier/recommended',
    ],
    plugins: ['vue', '@typescript-eslint'],
    /*
     * "off" 或 0    ==>  关闭规则
     * "warn" 或 1   ==>  打开的规则作为警告(不影响代码执行)
     * "error" 或 2  ==>  规则作为一个错误(代码不能执行,界面报错)
     */
    rules: {
        // eslint(https://eslint.bootcss.com/docs/rules/)
        'no-var': 'error', // 要求使用 let 或 const 而不是 var
        'no-multiple-empty-lines': ['warn', { max: 1 }], // 不允许多个空行
        'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
        'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
        'no-unexpected-multiline': 'error', // 禁止空余的多行
        'no-useless-escape': 'off', // 禁止不必要的转义字符

        // typeScript (https://typescript-eslint.io/rules)
        '@typescript-eslint/no-unused-vars': 'off', // 禁止定义未使用的变量
        '@typescript-eslint/prefer-ts-expect-error': 'off', // 禁止使用 @ts-ignore
        '@typescript-eslint/no-explicit-any': 'off', // 禁止使用 any 类型
        '@typescript-eslint/no-non-null-assertion': 'off',
        '@typescript-eslint/no-namespace': 'off', // 禁止使用自定义 TypeScript 模块和命名空间。
        '@typescript-eslint/semi': 'off',

        // eslint-plugin-vue (https://eslint.vuejs.org/rules/)
        'vue/multi-word-component-names': 'off', // 要求组件名称始终为 "-" 链接的单词
        'vue/script-setup-uses-vars': 'error', // 防止<script setup>使用的变量<template>被标记为未使用
        'vue/no-mutating-props': 'off', // 不允许组件 prop的改变
        'vue/attribute-hyphenation': 'off', // 对模板中的自定义组件强制执行属性命名样式
    },
}

.prettierrc.json

js 复制代码
{
  "singleQuote": false,
  "semi": false,
  "bracketSpacing": true,
  "htmlWhitespaceSensitivity": "ignore",
  "endOfLine": "auto",
  "trailingComma": "all",
  "tabWidth": 2
}

.stylelintrc.cjs

js 复制代码
// @see https://stylelint.bootcss.com/
// 美化css书写的样式
module.exports = {
    extends: [
      'stylelint-config-standard', // 配置stylelint拓展插件
      'stylelint-config-html/vue', // 配置 vue 中 template 样式格式化
      'stylelint-config-standard-scss', // 配置stylelint scss插件
      'stylelint-config-recommended-vue/scss', // 配置 vue 中 scss 样式格式化
      'stylelint-config-recess-order', // 配置stylelint css属性书写顺序插件,
      'stylelint-config-prettier', // 配置stylelint和prettier兼容
    ],
    overrides: [
      {
        files: ['**/*.(scss|css|vue|html)'],
        customSyntax: 'postcss-scss',
      },
      {
        files: ['**/*.(html|vue)'],
        customSyntax: 'postcss-html',
      },
    ],
    ignoreFiles: [
      '**/*.js',
      '**/*.jsx',
      '**/*.tsx',
      '**/*.ts',
      '**/*.json',
      '**/*.md',
      '**/*.yaml',
    ],
    /**
     * null  => 关闭该规则
     * always => 必须
     */
    rules: {
      'value-keyword-case': null, // 在 css 中使用 v-bind,不报错
      'no-descending-specificity': null, // 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器
      'function-url-quotes': 'always', // 要求或禁止 URL 的引号 "always(必须加上引号)"|"never(没有引号)"
      'no-empty-source': null, // 关闭禁止空源码
      'selector-class-pattern': null, // 关闭强制选择器类名的格式
      'property-no-unknown': null, // 禁止未知的属性(true 为不允许)
      'block-opening-brace-space-before': 'always', //大括号之前必须有一个空格或不能有空白符
      'value-no-vendor-prefix': null, // 关闭 属性值前缀 --webkit-box
      'property-no-vendor-prefix': null, // 关闭 属性前缀 -webkit-mask
      'selector-pseudo-class-no-unknown': [
        // 不允许未知的选择器
        true,
        {
          ignorePseudoClasses: ['global', 'v-deep', 'deep'], // 忽略属性,修改element默认样式的时候能使用到
        },
      ],
    },
  }

🏆 功能封装

Svg使用

js 复制代码
// <template>中
<SvgIcon icon="" width="15px" height="15px" color="#fff" />
    
js 复制代码
//vite中自行调整svg图标的储存位置
   createSvgIconsPlugin({
        iconDirs: [path.resolve(process.cwd(), "src/assets/svgs")],
        symbolId: "icon-[dir]-[name]",
    }),

WangEditor编辑器集成

官网

js 复制代码
// 父组件中
<template>
  <WangEditor v-model="editVal" height="calc(100vh - 180px)" />
</template>

<script setup lang="ts">
import { ref, watchEffect } from "vue"
//初始值
const editVal = ref("Hello! WangEditor")
watchEffect(() => {
  console.log(editVal.value)
})
</script>
js 复制代码
<template>
  <div class="wang_edit" :class="{ dark: useSetting.dark }">
    <Toolbar
      id="toolbar-container"
      :editor="editorRef"
      :defaultConfig="toolbarConfig"
      mode="default"
    />
    <Editor
      id="editor-container"
      v-model="valueHtml"
      :defaultConfig="editorConfig"
      mode="default"
      @onCreated="handleCreated"
    />
  </div>
</template>

<script setup lang="ts">
import { useSettingStore } from "@/stores/modules/setting"
import "@wangeditor/editor/dist/css/style.css" // 引入 css
import { onBeforeUnmount, ref, shallowRef, onMounted } from "vue"
import { Editor, Toolbar } from "@wangeditor/editor-for-vue"
const useSetting = useSettingStore()
const props = withDefaults(
  defineProps<{
    height: string
  }>(),
  {
    height: "560px",
  },
)

const valueHtml = defineModel()
// 编辑器实例,必须用 shallowRef
const editorRef = shallowRef()
const toolbarConfig = {}
const editorConfig = {
  placeholder: "请输入内容...",
  MENU_CONF: {
    uploadImage: {
      // 自定义图片上传
      async customUpload(file: any, insertFn: any) {
        console.log(file, insertFn)
        // 调用后端接口,上传图片
        // 拿到上传路劲插入编辑器
        // insertFn(url)
      },
    },
  },
}

// 组件销毁时,也及时销毁编辑器
onBeforeUnmount(() => {
  const editor = editorRef.value
  if (editor == null) return
  editor.destroy()
})

const handleCreated = (editor: any) => {
  editorRef.value = editor // 记录 editor 实例,重要!
}
</script>

<style scoped lang="scss">
.wang_edit {
  border: 1px var(--el-border-color-dark) solid;
  border-radius: 5px;
  &.dark {
    --w-e-textarea-bg-color: #333;
    --w-e-toolbar-bg-color: #333;
    --w-e-toolbar-color: gray;
    --w-e-textarea-color: #fff;
  }

  #toolbar-container {
    border-bottom: 1px solid var(--el-border-color-dark);
    border-top-right-radius: 5px;
    border-top-left-radius: 5px;
  }
  #editor-container {
    height: v-bind("props.height") !important;
    overflow: hidden;
    border-bottom-right-radius: 5px;
    border-bottom-left-radius: 5px;
  }
}
</style>

👻 项目运行

项目启动

js 复制代码
# 安装 
pnpm npm install pnpm -g 

# 安装依赖
pnpm install 

# 项目运行
pnpm run dev

项目语法检查

js 复制代码
#语法检查
pnpm run lint

#语法修复
pnpm run fix

#css美化
pnpm run format

项目打包

js 复制代码
pnpm run build

✍️ 写在最后

本篇从项目规范,项目运行,项目打包,详细讲述基于Vue3.4+Element-plus技术栈0到1搭建简洁,易懂的前端后台管理框架。如有问题欢迎指出。

相关推荐
学不会•17 分钟前
css数据不固定情况下,循环加不同背景颜色
前端·javascript·html
活宝小娜3 小时前
vue不刷新浏览器更新页面的方法
前端·javascript·vue.js
程序视点3 小时前
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
前端·javascript·vue.js·typescript·vue·ecmascript
coldriversnow3 小时前
在Vue中,vue document.onkeydown 无效
前端·javascript·vue.js
我开心就好o3 小时前
uniapp点左上角返回键, 重复来回跳转的问题 解决方案
前端·javascript·uni-app
开心工作室_kaic4 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
刚刚好ā4 小时前
js作用域超全介绍--全局作用域、局部作用、块级作用域
前端·javascript·vue.js·vue
沉默璇年5 小时前
react中useMemo的使用场景
前端·react.js·前端框架
yqcoder5 小时前
reactflow 中 useNodesState 模块作用
开发语言·前端·javascript
2401_882727575 小时前
BY组态-低代码web可视化组件
前端·后端·物联网·低代码·数学建模·前端框架