项目技术以及使用plugin
此项目使用Vue-CLI脚手架
这是我的项目预设
项目使用的插件
- vue-cli-plugin-element
- element-ui——饿了么的集成UI库
- @vue/cli-plugin-router
- router——路由加载组件
- @vue/cli-plugin-eslint
- eslint——代码检验插件
- 主要用来审核代码的格式
- @vue/cli-plugin-babel
- babel——我竟然不知道它是干什么的!
项目使用的依赖
开发依赖
- babel-plugin-component
- babel-plugin-transform-remove-console (在build时删除console.log())
- less/less_loader
运行依赖
- axios
- echarts
- element-ui
- loadsh 进行数据的处理(深度拷贝)
- nprogress 加载条
- vue-table-with-tree-grid
首先来分析一下vue-cli脚手架生成的文件
-
.vscode
-
脚手架不生成此文件
-
这儿我使用的开发工具是vscode,这是vscode相关的配置文件
-
-
dist
-
脚手架不生成此文件
-
这儿存放项目开发完成之后,build出的文件全部存放在这儿
-
这也就是我们最终发行使用的文件
-
-
node_modules
- 脚手架生成此文件
- 这儿存放插件、依赖相关的文件
- 这个文件夹也是我们整个工程中体积最大的文件
-
public
- 脚手架生成此文件
- 此文件夹包括一张vue的大头照和项目的html
- html文件是我们整个项目中的核心,所有模块都会被渲染到这儿
-
src
-
脚手架生成此文件
-
我们开发项目的文件夹
-
-
.browserslistrc
- 脚手架生成此文件
-
.editorconfig
- 脚手架生成此文件
-
.eslintrc.js
- 脚手架生成此文件
- 这就是我们的代码校验的相关配置
-
.gitignore
-
脚手架生成此文件
-
这儿是使用git时,必须要使用的一个文件
-
存放们不想上传到github仓库的文件
-
-
.prettierrc
- 脚手架不生成此文件
-
babel.config.js
- 脚手架生成此文件
-
package-lock.json
- 脚手架生成此文件
- 辅助版本管理
-
package.json
- 脚手架生成此文件
- 版本管理
-
README.md
- 脚手架生成此文件
-
vue.config.js
- 脚手架不生成此文件
相关配置
element.js
-
在我们构建项目的时候,选择按需导入
-
在这儿来声明组件
-
inport Vue from 'vue' import { Button, Message } from 'element-ui' // import 相关的组件名称,只有import,并且使用了组件,在我们的项目中才能生效 Vue.use(Button) Vue.prototype.$message = Message // 给方法重命名,这样我们后面的使用会更方便
-
一些相关的UI组件也可以在这儿导入,然后在组件中使用。
main.js
导入特定的字体包
- alibaba字体包
- 将字体相关的包放入工程中
- 导入相关的字体包
import '../src/assets/fonts/iconfont.css'
- 然后直接在vue组件中,直接使用官方的标签使用即刻
富文本编辑器
vue-quill-editor
- 按照
api
文档导入相关包即可。 导入:import VueQuillEditor from 'vue-quill-editor'
然后再导入相关的样式 - 参照文档将标签置于相应的位置
<quill-editor v-model="addForm.goods_introduce"></quill-editor>
- 将富文本编辑器注册为全局可用组件
VUe.use(VueQuillEditor)
axios
-
导入
axios
包。import axios from 'axios'
-
配置相关的根路径。
axios.default.baseURL = 'http://根路径/'
-
request拦截器
-
axios.interceptors.request.use(config => { //这是为了通过token,来进行登录验证 config.header.Authorization = window.sessionStorage.getItem('token') //必须在最后返回config return config })
-
这是请求之前进行的处理
-
-
response拦截器`
-
axios.interceptors.request.use(config => { //必须在最后返回config return config })
-
这是请求返回结果的处理
- 重命名
Vue.prototype.$http = axios
全局过滤器
//时间过滤器
Vue.filter('dataFormat',function(originVal) {
const dt = new Date(originVal)
const y = dt.getFullYear()
const m = (dt.getMonth() + 1 + '').padStart(2, '0')
const d = (dt.getDate() + '').padStart(2, '0')
const hh = (dt.getHours() + '').padStart(2, '0')
const mm = (dt.getMinutes() + '').padStart(2, '0')
const ss = (dt.getSeconds() + '').padStart(2, '0')
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
})
-
padStart(a,'0')
这就是将这个数字处理之后,如果不够2位或者超出2位,用0补上。 - return 的就是我们已经处理好的时间。
-
Date(originVal)
这就是处理出一个时间,让我们使用后面的方法,可以拿到我们想要的数据。
树状下拉结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MqUeaSjV-1584337386849)(C:\Users\张辉\AppData\Roaming\Typora\typora-user-images\image-20200316125926781.png)]
-
vue-table-with-tree-grid
-
导入包。
import TreeTable from 'vue-table-with-tree-grid'
-
注册为全局可用组件
Vue.component('tree-table', TreeTable)
-
<tree-table class="treeTable" :data="catelist" //绑定的数据 :columns="columns" //列属性的定义 :selection-type="false" :expand-type="false" show-index //展示index列 index-text="#" border //边框 :show-row-hover="false" > <!-- 是否有效,作用域插槽 --> <template slot="isok" slot-scope="scope"> <i class="el-icon-success" v-if="scope.row.cat_deleted === false" style="color:lightgreen;" ></i> <i class="el-icon-error" v-else style="color:red;"></i> </template> <!-- 排序 --> <template slot="order" slot-scope="scope"> <el-tag size="mini" v-if="scope.row.cat_level === 0">一级</el-tag> <el-tag size="mini" type="success" v-else-if="scope.row.cat_level === 1">二级</el-tag> <el-tag size="mini" type="warning" v-else>三级</el-tag> </template> <!-- 操作 --> <template slot="opt" slot-scope="scope"> <el-button size="mini" type="primary" icon="el-icon-edit" @click="showEdit(scope.row.cat_id)" >编辑</el-button> <el-button size="mini" type="danger" icon="el-icon-delete" @click="dropCateByID(scope.row.cat_id)" >删除</el-button> </template> </tree-table> // 为table指定列的定义 columns: [ { label: '分类名称', prop: 'cat_name' }, { label: '是否有效', // 表示将当前列定义为模板列 type: 'template', // 表示当前这一列使用模板名称 template: 'isok' }, { label: '排序', // 表示将当前列定义为模板列 type: 'template', // 表示当前这一列使用模板名称 template: 'order' }, { label: '操作', // 表示将当前列定义为模板列 type: 'template', // 表示当前这一列使用模板名称 template: 'opt' } ],
全局加载条nprogress
- 导入
js,css
即可 import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
- 然后在
axios
的request
请求器中开启即可:NProgress.start()
- 最后在
response
请求器中关闭:NProgress.done()
router.js
路由导航守卫
router.beforeEach((to, from, next) => {
// to 将要访问的路径
// from 代表从那个路径跳转而来
// next 是一个函数,表示放行
// next() 放行 next('/login') 强制跳转
if (to.path === '/login') return next()
// 获取 token
const tokenStr = window.sessionStorage.getItem('token')
if (!tokenStr) return next('/login')
next()
})
- 路由导航守卫必须书写,这样可以放置直接通过URL访问
路由重定向
{path: '/', redirect: '/login'}
其他知识点
lodash
-
cloneDeep(obj) 深度拷贝
-
merge进行数据的合并
Echarts
数据表格,统计图
-
导入:
import echarts from 'echarts'
-
async mounted() { // 3. 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('main')) const { data: res } = await this.$http.get('reports/type/1') if (res.meta.status !== 200) { return this.$message.error('获取折线数据失败!') } // 4. 指定图表的配置项和数据 const result = _.merge(res.data, this.options) // 5. 展示数据 // 使用刚指定的配置项和数据显示图表。 myChart.setOption(result) },