vue+element-ui商城后台管理系统(day05-06)
day05-06
一. 实现商品列表goods-list
1.1 创建新分支
1.2 根据queryInfo属性的数据获取当前页面的数据
1.3 渲染页面
- 时间过滤器(Vue全局注册, 把时间戳格式化)
.padStart(2, '0')
如果字符串不足两位, 前面补齐一个’0’
Vue.filter('dateFormat', 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}`
})
- 搜索, 删除, 编辑功能
1.4 新增功能
- 创立新路由
- 页面结构:
- 面包屑 卡片 警告栏
- 步骤条
- 动态为其赋值上索引属性
- 步骤条绑定的是数字
- 加入侧边栏
- 添加表单
- 嵌套关系: form 包裹 tabs
- 设置label位置的属性: label-position
- 添加表单属性
- 商品分类(级联选择器)
- 获取/categories的商品分类数据
- 判断选中是否为三级不是的话变为空数组
- 没有选择商品分类不能跳转
- 加入tabs的一个拦截函数before-leave
return false
的话则不会触发菜单切换
- 加入tabs的一个拦截函数before-leave
- 获取动态参数
- 给tabs绑定
tab-click
, 再进行判断
- 给tabs绑定
- 使用checkbox渲染标签
- 复选框样式优化(重置margin属性)
- 获取静态参数
- 给tabs绑定tab-click
- 图片上传模块
- 上传出错:
无效token
- 加上
header
属性 - 通过
on-success
绑定一个事件并传回response
把响应的临时路径保存到表单数组 - 移除图片
- 添加
on-remove
事件的回调函数 - 参数可以获取到
file=>
这个图片信息, 然后再addForm
中把图片splice
掉
- 添加
- 图片预览
- 通过一个dialog进行实现
- 提交表单
- 拷贝级联表双向绑定的数组,并拷贝一份给form
- 上传出错:
- 商品分类(级联选择器)
二. 自己做遇到的问题
2.1 商品分类table的lazy-load失效
:tree-props
要有haschildren
属性
2.2 el-row, el-col问题
- 如果不给
el-col
都加上span
属性, 不会显示在同一行?
2.3 全局style
- 在vue文件可以引入两个
style
可以一个有scoped
一个没有
2.4 tabs-pane绑定的name
- 在
before-leave
中得以看出他的name
是string
类型
2.5 复选框发现点击一个会消失一个
-
浅拷贝:
this.addGoodForm.goods_vals = [...this.manyParamsList]
- 这样的做法是让表单数据与传来的参数数据第一层分离,
- 但是出现问题点击一个会选择全部
- 原因: 只有第一层拷贝, 剩下的也是直接引用
- 解决方法: 使用深拷贝
-
深拷贝
-
①
lodash
插件 -
②
JSON.parse(JSON.stringify( targetObj ))
转换为JSON格式再转换回来 -
import Vue from 'vue' const deepClone = obj => { // 判断类型都否需要深拷贝 const isObject = args => (typeof args === 'object' || typeof args === 'function') && typeof args !== 'undefined' // 不是则报一个错 if (!isObject) throw new Error('Not Reference Types') // 判断是否为数组并赋予Array原型 let newObj = Array.isArray(obj) ? [...obj] : { ...obj } Reflect.ownKeys(newObj).map(key => { // 判断子结点是仍为对象, 如果是则递归 newObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key] }) return newObj } // 全局导入vue Vue.prototype.$deepClone = deepClone
-
-
用这个方法可以把参数列表与复选框的值给分离
2.6 图片上传
file-list
的作用???- 图片的src拼接要加上协议比如开头要加http://
三. 基本布局实现
四. 内容渲染
4.1 省份级联表
- 传入
js
文件
4.2 绘制echarts
图标
- https://echarts.apache.org/zh/index.html
- 可以用深拷贝把请求回来的数据跟options合并
五. 项目优化
5.1 项目优化策略
- 生成打包报告
- 第三方启用
CDN
Element-UI
组件按需加载- 路由懒加载
- 首页内容指定
5.2 导入cdn发现的问题
-
cdn
网站- https://cdn.jsdelivr.net/
- http://staticfile.org/
-
Import in body of module; reorder to top
import
要在所有vue.use()
之前- element要把babel配置的东西去掉
- 下面是官方要求配置的东西
- 下面是官方要求配置的东西
-
vue-quill-editor
需要引入的的`cdn
<script src="https://cdn.staticfile.org/quill/1.3.7/quill.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-quill-editor@3.0.6/dist/vue-quill-editor.js"></script>
<link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.7/quill.core.min.css">
<link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.7/quill.snow.min.css">
<link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.7/quill.bubble.min.css">
5.3 人性化
- 进度条展示
NProgress
在axios
拦截器中添加NProgress.start()
NProgress.done()
- 在axios上配置
// 进度条
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
axios.interceptors.request.use(config => {
console.log(NProgress)
NProgress.start()
config.headers.Authorization = window.sessionStorage.getItem('token')
return config
})
axios.interceptors.response.use(config => {
NProgress.done()
return config
})
5.4 serve
与build
-
serve发现很多
eslint
的警告- 一一按规范调整
-
build很多
console.log
警告-
添加
transform-remove-console
插件并在胚子文件的plugins
中配置 -
但是在
serve
与build
阶段都会移除-
按需添加插件
-
const prodPlugins = [] if (process.env.NODE_ENV === 'production') { prodPlugins.push('transform-remove-console') }
-
-
-
5.5 configureWebpack
与chainWebpak
-
configureWebpack
通过操作对象 -
chainWebpak
通过链式编程- 来达到修改
webpack
配置
- 来达到修改
-
通过
chanin
实现改变开发与发布模式的入口函数-
module.exports = { chaninWebpack: config => { config.when(progress.enc.MODE_ENV === 'production', config => { config.entry('app').clear().add('./src/main-prod.js') }) config.when(progress.enc.MODE_ENV === 'development', config => { config.entry('app').clear().add('./src/main-dev.js') }) } }
-
-
实现
CDN
打包资源- 通过externals加载外部
CDN
资源 - {}中如果有
axios: 'axios'
的话就会查找index.html
element
打包规则:- 不同上面方法要在externals中加入
elementui
属性 - 直接在
index.html
中加入就可
- 不同上面方法要在externals中加入
css
文件同理
- 通过externals加载外部
5.6 开发与发布时候title不同名操作
-
通过在
vue.config.js
中加入自定义属性-
config.plugin('html').tap(args => { args[0].isProd = true return args // 记得要return args })
-
-
在
index.htm的title
中使用判断语句<%= htmlWebpackPlugin.options.isProd ? '' : 'dev -' %>
5.7 路由懒加载
- ①安装
@babel/plugin-syntax-dynamic-import
- ②
babel.config.js
配置声明插件 - ③讲路由改为按需加载的形式
const Foo = () => import(...)
这样已经是按需加载const Foo = () => import(/* webpackChunkName: "group-one" */...)
来实现按组划分
5.8 node部署压缩
const compression = require('compression')
app.use(compression())
六. 项目上线
6.1 项目打包
-
发现build完全部需要导入的文件都
Failed to load resource: net::ERR_FILE_NOT_FOUND
-
问题: 我写的是相对路径倒是被解析成绝对路径
-
解决办法: 在
vue.cnfig.js
中加入-
module.expots = { publicPath: './', }
-
6.2 申请https
- 配置
HTTPS
服务 - 申请
SSL
证书(https://freessl.org)
.jpg)]
const https = require('https')
const fs = require('fs')
const options = {
cert: fs.readFileSync('.pem')
key: fs.readFileSync('.key')
}
// 443 https默认端口
https.createSetver(options, app).listen(443)