当前位置:   article > 正文

Vue 新手学习笔记:vue-element-admin 之 入门开发教程(v4.0.0 之后)_vue-element-admin教学

vue-element-admin教学

由于 vue-element-admin 的架构再 4.0.0 版本后做了重构,所以写这个文章,对改动比较大的部分做个讲解,方便大家入门学习。虽说项目做了重构,但是整体结构上和之前的还是很相似的,所以有些和之前差不多的我会直接放之前文章的链接

由于 Markdown 实在不太会用,这里手动列下目录,毕竟东西有点杂

  • 安装&准备工作&ESLint配置
  • 连接后台真数据
  • Mock 假数据
  • 不需要 Mock 虚拟数据怎么办?
  • 前端拦截器
  • 登陆功能
  • 自定义 vuex 参数
  • Mock 数据部分代码

安装&准备工作&ESLint配置

安装&准备工作&ESLint 部分:Vue 新手学习笔记:vue-element-admin 之安装,配置及入门开发(v4.0.0 之前)
这个就不多做讲解了,可以直接参考之前的文章,写的应该算详细了,这里只对下面 4 个内容做个说明

node&npm 版本要求:

都知道框架对这两点是有要求的,那么最低要求要达到哪呢?
最下面:package.json
这个是官方项目里的 package.json 文件,别人说的都不一定对,毕竟版本会迭代,自己看才是最实在的

i18n 国际化:

大部分人下的代码都是 master 分支的代码,照官方的说法国际化的功能被单独拿出来开了个分支,所以需要这个功能的要去下
i18n 分支的代码

要下分支代码的可以看这篇:Git 克隆指定分支的代码

命令:

新版本的命令和旧版本的略有不同,还加了些命令,有兴趣的可以试下,具体的可看 package.json 文件

  1. # 发布
  2. # 本地环境启动
  3. npm run dev
  4. # 构建测试环境
  5. npm run build:stage
  6. # 构建生产环境
  7. npm run build:prod
  8. # 其它
  9. # 预览发布环境效果
  10. npm run preview
  11. # 预览发布环境效果 + 静态资源分析
  12. npm run preview -- --report
  13. # 代码格式检查
  14. npm run lint
  15. # 代码格式检查并自动修复
  16. npm run lint -- --fix

启动访问报错 404:

我在新项目启动登陆报错,那是因为官方 mock 只在正式环境启用,我在 i18n 分支遇到的,缺心眼?
打开文件 src/main.js 把环境判断去掉

 

连接后台真数据

这个是很多人都关心的,我看了网上很多文章都是直接去 vue.config.js 去配 proxy,这并不是正确的配置方法。
还记得上个版本有分出各个环境的配置文件配置的,怎么可能这个版本就没有了?官方是有提供配置文件的

  • .env.development:本地
  • .env.staging:测试环境
  • .env.production:正式环境

PS:这里唯一注意的就是旧版本是用用冒号连接,这里是等于,写错了就拿不到路径
src/utils/request.js 在请求拦截器里打印看看

打印:拿到说明配置正确

PS:其他的静态配置都可以在这个文件里配置,比如一些静态文件路径之类的

 

Mock 假数据

为了更好的说明,这里使用的示例为自己写的,不是项目里带的,先大致列下项目对应文件,具体代码放文章结尾
这里 service 文件夹自己建的,就是个简单的分页列表示例

  • vue页面文件:/src/views/service/index.vue
  • api接口:/src/api/service/index.js
    PS:可能很多人觉得 api 文件多余,直接在页面写路径,但是用 api 文件在路径上更方便管理,这点在微服务中通过特定服务名去访问显得尤为明显,类似这种:
  • mock 虚拟数据文件:/mock/service/index.js
  • mock 数据加载文件(这个原来就有):/mock/index.js

流程说明:

页面接口先去请求 api 文件

vue页面文件

api接口

在 api 请求时会被 mock 拦截,先来看下 mock 数据

可以看到新版本在路径拦截方面做了优化,比之前的版本配置好理解

mock/index.js 中如果需要拦截就会被拦截

下拉可以看到,这里循环了 mocks 把这个页面里所有有配置的接口都进行了拦截

 

不需要 Mock 虚拟数据怎么办?

很简单,两个字:注掉,这样就不会拦截了

 

前端拦截器

路径:/src/utils/request.js

这个文件分为 3 个部分

  • axios 实例,所以不需要自己去写,引用下这个文件包下就好了,可以看下 api

  • service.interceptors.request.use 请求拦截器
    可以凭需要自己新增一些请求头之类的

  • service.interceptors.response.use 返回值拦截器
    这里的逻辑不多说不难

登陆功能

去除那些无关的东西,比如什么 rules 校验啊,默认的账号密码之类的东西,直接看核心登陆方法

/src/views/login/index.vue

逻辑很简单,登陆参数校验 ➡ 调用 store 里的 login 方法登陆 ➡ 成功跳到对应页面

  1. handleLogin() {
  2. // 登陆校验
  3. this.$refs.loginForm.validate(valid => {
  4. // 如果校验通过
  5. if (valid) {
  6. this.loading = true
  7. // 这里进行登陆请求 login 方法
  8. // 在 src/store/modules/user.js
  9. this.$store.dispatch('user/login', this.loginForm)
  10. .then(() => {
  11. // otherQuery 就是你从哪个页面退出的,帮你重定向回那个页面
  12. this.$router.push({ path: this.redirect || '/', query: this.otherQuery })
  13. this.loading = false
  14. })
  15. .catch((errorMsg) => {
  16. this.loading = false
  17. // 登陆失败提示
  18. Message({
  19. message: errorMsg,
  20. type: 'error',
  21. duration: 5 * 1000
  22. })
  23. })
  24. } else {
  25. console.log('error submit!!')
  26. return false
  27. }
  28. })
  29. },

/src/store/modules/user.js ➡ login方法

在登陆方法里建议不要做多于操作,就登陆就行了,因为缓存用的时 vuex 和之前版本一样刷新就没了,所以还需要走 getInfo 方法来获取需要的数据,如果你按照框架的来,建议必要权限数据在这取,然后放 vuex,那些准备直接放 localStorage 的请无视。

/src/views/permissions.js

和之前的版本一样,这个文件就是你路由走的逻辑,简单看下重要部分

PS:这里对比你自己的会发现,原本代码里写的是 const { roles } = await xxxxx,我这里直接把括号去了,按我的理解这个括号应该是只能接收数组类型的参数,但是我不管怎么传拿到的都是 null,要么报错,我就干脆改掉了

/src/store/modules/user.js ➡ getInfo方法

这里直接看下我改过的,可以对比下自己源代码,然后进行修改,至于这里调的 api 接口啥的就不多说了,没区别
commit 方法就是把值传到 vuex 里

  1. // get user info
  2. getInfo({ commit, state }) {
  3. return new Promise((resolve, reject) => {
  4. getInfo(state.token).then(response => {
  5. const data = response.data
  6. // 设置按钮权限到 vuex
  7. commit('SET_BUTTON', data.retData.button)
  8. if (data.retData.module && data.retData.module.length > 0) { // 验证返回的roles是否是一个非空数组
  9. commit('SET_ROLES', data.retData.module)
  10. } else {
  11. // 当用户无任何权限时设置
  12. commit('SET_ROLES', ['普通用户'])
  13. }
  14. commit('SET_NAME', data.retData.username)
  15. commit('SET_AVATAR', 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif')
  16. commit('SET_INTRODUCTION', data.retData.username)
  17. resolve(data.retData.module)
  18. }).catch(error => {
  19. reject(error)
  20. })
  21. })
  22. },

/src/store/modules/permission.js ➡ generateRoutes方法

这里就是,目录加载了,这个部分和之前差不多一样,就不多说了

目录权限部分:Vue 新手学习笔记:vue-element-admin 之登陆及目录权限控制

PS:旧版本的 filterAsyncRoute 方法在新版里叫 filterAsyncRoutes 多了个 s 注意下

自定义 vuex 参数

比如我自定义的 button 参数

使用 commit 之前上面对应的也是要的

Mock 数据部分代码

vue页面文件:/src/views/service/index.vue

  1. <template>
  2. <div class="app-container">
  3. <el-table :data="list" border fit highlight-current-row style="width: 100%;" height="611px">
  4. <el-table-column :show-overflow-tooltip="true" aellign="center" label="服务单号">
  5. <template slot-scope="scope">
  6. <span>{{ scope.row.data1 }}</span>
  7. </template>
  8. </el-table-column>
  9. <el-table-column :show-overflow-tooltip="true" align="center" label="性质">
  10. <template slot-scope="scope">
  11. <span>{{ scope.row.data2 }}</span>
  12. </template>
  13. </el-table-column>
  14. <el-table-column :show-overflow-tooltip="true" align="center" label="客户">
  15. <template slot-scope="scope">
  16. <span>{{ scope.row.data3 }}</span>
  17. </template>
  18. </el-table-column>
  19. <el-table-column :show-overflow-tooltip="true" align="center" label="联系人">
  20. <template slot-scope="scope">
  21. <span>{{ scope.row.data4 }}</span>
  22. </template>
  23. </el-table-column>
  24. <el-table-column :show-overflow-tooltip="true" align="center" label="工程师">
  25. <template slot-scope="scope">
  26. <span>{{ scope.row.data5 }}</span>
  27. </template>
  28. </el-table-column>
  29. <el-table-column :show-overflow-tooltip="true" align="center" label="送修/上门时间">
  30. <template slot-scope="scope">
  31. <span>{{ scope.row.data7 }}</span>
  32. </template>
  33. </el-table-column>
  34. <el-table-column :show-overflow-tooltip="true" align="center" label="修复/结束时间">
  35. <template slot-scope="scope">
  36. <span>{{ scope.row.data8 }}</span>
  37. </template>
  38. </el-table-column>
  39. <el-table-column :show-overflow-tooltip="true" align="center" class-name="status-col" label="部门">
  40. <template slot-scope="scope">
  41. <span>{{ scope.row.data10 }}</span>
  42. </template>
  43. </el-table-column>
  44. <el-table-column :show-overflow-tooltip="true" align="center" class-name="status-col" label="操作">
  45. <template slot-scope="scope">
  46. <input :loading="checkLoading" type="button" class="el-button el-button--primary el-button--medium" value="确认" @click="checkFwdbh(scope.row.data1)">
  47. </template>
  48. </el-table-column>
  49. </el-table>
  50. <!-- 分页 -->
  51. <pagination
  52. v-show="total>0"
  53. :total="total"
  54. :page.sync="listQuery.page"
  55. :limit.sync="listQuery.limit"
  56. @pagination="getServiceList"
  57. />
  58. </div>
  59. </template>
  60. <script>
  61. import { getServiceList } from '@/api/service/index'
  62. import Pagination from '@/components/Pagination'
  63. export default {
  64. components: { Pagination },
  65. data() {
  66. return {
  67. // 加载样式控制
  68. checkLoading: false,
  69. // 数据列表
  70. list: [],
  71. // 数据条数
  72. total: 0,
  73. // 按钮加载等待
  74. loading: false,
  75. listQuery: {
  76. // 分页参数
  77. page: 1,
  78. limit: 10
  79. }
  80. }
  81. },
  82. created() {
  83. // 加载列表
  84. this.getServiceList()
  85. },
  86. methods: {
  87. // 获取列表数据
  88. getServiceList() {
  89. getServiceList(this.listQuery).then(response => {
  90. this.list = response.items
  91. this.total = response.total
  92. })
  93. },
  94. // 确认请求
  95. checkFwdbh(fwdbh) {
  96. alert(fwdbh)
  97. }
  98. }
  99. }
  100. </script>
  101. <style scoped>
  102. .icon-star{
  103. margin-right:2px;
  104. }
  105. .drag-handler{
  106. width: 20px;
  107. height: 20px;
  108. cursor: pointer;
  109. }
  110. .show-d{
  111. margin-top: 15px;
  112. }
  113. /* 布局样式 */
  114. .el-row {
  115. margin-bottom: 20px;
  116. &:last-child {
  117. margin-bottom: 0;
  118. }
  119. }
  120. .el-col {
  121. border-radius: 4px;
  122. }
  123. .bg-purple-dark {
  124. background: #99a9bf;
  125. }
  126. .bg-purple {
  127. background: #d3dce6;
  128. }
  129. .bg-purple-light {
  130. background: #e5e9f2;
  131. }
  132. .grid-content {
  133. border-radius: 4px;
  134. min-height: 36px;
  135. }
  136. .row-bg {
  137. padding: 10px 0;
  138. background-color: #f9fafc;
  139. }
  140. </style>

api接口:/src/api/service/index.js

  1. import request from '@/utils/request'
  2. const SERVICE = '/service'
  3. // 获取列表数据
  4. export function getServiceList(query) {
  5. return request({
  6. url: SERVICE + '/service/getServiceLogList',
  7. method: 'post',
  8. data: query
  9. })
  10. }

mock 虚拟数据文件:/mock/service/index.js

  1. const List = []
  2. const count = 30
  3. // 模拟数据列表
  4. for (let i = 0; i < count; i++) {
  5. List.push({
  6. data1: 'ABCD00000000000',
  7. data2: '1004553',
  8. data3: '送修',
  9. data4: 'xxxxxxxx办事处',
  10. data5: '林xx',
  11. data6: '王xxx',
  12. data7: '2005-11-07 00:00',
  13. data8: '2006-07-20 00:00',
  14. data9: '已核销不开票',
  15. data10: '技术支持部'
  16. })
  17. }
  18. const SERVICE = '/service'
  19. export default [
  20. {
  21. // 拦截的路径
  22. url: SERVICE + '/service/getServiceLogList',
  23. type: 'post',
  24. response: _ => {
  25. return {
  26. code: 20000,
  27. total: List.length,
  28. items: List,
  29. limit: 10
  30. }
  31. }
  32. }
  33. ]

mock 数据加载文件(这个原来就有):/mock/index.js

效果图:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/365780
推荐阅读
相关标签
  

闽ICP备14008679号