第一天,用svn把项目拉下来,然后使用yarn安装依赖,yarn有啥用,为啥现在很多用yarn的,
yarn的优点
并行安装,npm是顺序安装,所以yarn的速度会更快,
复用缓存包,如果之前已经安装过一个软件包,yarn再次安装时会从缓存中获取
自动添加版本锁,yarn.lock类似于package-lock.json
项目结构
├─assets # 静态资源
│ └─img
├─components # 组件库
│ └─global # 全局组件 <放入后不需要注册也不需要引入>
├─decorator # 装饰器
├─filter # 过滤器
├─http # 网络请求
├─layouts # layout文件
├─plugins # 插件库 如需要引入第三方组件等 <推荐使用cdn>
├─router # 路由
├─store # vuex
│ └─modules # vuex 模块
├─style # 样式
│ ├─css # css 文件
│ └─sass # sass 工具库样式
├─utils # 工具库目录
└─views # 页面文件
assets存放静态资源
值得一说的是这里面图标用的是阿里的矢量图标库,使用方法可以看这里iconfont代码应用
components组件库
里面就是放一些公共组件,global文件夹下的组件会直接注册到全局组件里,怎么自动注册的呢?其实就是遍历global文件下所有的vue后缀文件,然后通过文件名获取组件实例,然后通过Vue.component方法注册到vue全局组件里
import Vue from 'vue'
const requireComponents = require.context('./', true, /\.vue/)
requireComponents.keys().forEach(fileName => {
// 组件实例
const reqCom = requireComponents(fileName)
// 提取组件内 name 为 组件名字
const reqComName = reqCom.default.name
// 组件挂载
Vue.component(reqComName, reqCom.default || reqCom)
})
公共组件大概看了一下,整体项目没有用到分号感觉不太舒服,因为我之前先学过java,C++,所以习惯加分号,发现有用到/deep/深度选择器,关于深度选择器的原理看这里,vue scoped css
装饰器
这里边的亮点是装饰器,因为这是一个js项目,我之前还不知道js项目居然也可以使用装饰
器,以为只有ts项目才有装饰器,其实就是多安装一个loader用于解析注解,将注解转化成函数,
@vue/cli-plugin-babel这个插件里有个babel-loader,babel-loader里有个@babel/plugin-proposal-decorators插件,这个插件可以用来解析装饰器,这里面应该是vue/cli自带的功能
过滤器
这里面放了一些vue用到的过滤器
网络请求
一般看这里都是看怎么进行请求拦截和响应拦截的
请求拦截
http.interceptors.request.use(
config => {
openLoading(config)
const sessionid = session.getSession(SESSIONID)
if (sessionid) config.headers[SESSIONID] = sessionid
config.headers['cache-control'] = 'no-cache'
config.headers.Pragma = 'no-cache'
if (localSession.getLocal(USER_INFO)?.userToken) {
config.headers.token = localSession.getLocal(USER_INFO)?.userToken
}
return config
},
error => {
throw new Error(JSON.stringify(error))
}
)
发送请求的时候首先会触发一个loading动画,然后在请求头里面添加了一个自定义属性sessionid,这个现在看不出来有啥用? 之后添加了自定义属性token,这个一般是用户标识符,
并且禁用强制缓存,这个是出于什么考虑的?
响应拦截
http.interceptors.response.use(
async response => {
closeLoading(response.config)
let res = response.data
if (process.env.VUE_APP_mockFlag === 'true') { // 如果是mock模式,没有外层包装
return res
}
if (response.config.responseType === 'blob') { // 如果请求是BLOB
console.log('blob')
try {
const JsonData = await CheckStreamOrJSON(res)
res = JsonData
} catch {
return response
}
}
if (!res.success) { // 逻辑错误 自定义错误码
if (res.message) {
if (res.code === '401' && !localSession.getLocal(USER_INFO)?.userToken) {
// 首次调用getCurrentUserInfo接口时无token,不需要提示message
} else {
ErrorMessage(res.message)
}
}
globalError('接口调用失败')
switch (res.code) {
case '401':
if (!res.result) {
reLogin()
} else {
// 适配三方单点登录的逻辑,若未登录会返回三方登录的url
session.destroy('pathIDMap')
session.destroy(SESSIONID)
window.location.href = res.result
}
throw new Error('no login')
case '402':
session.destroy(SESSIONID)
vm.$router.push({ name: 'login' })
throw new Error('no sso login')
default:
break
}
throw new Error(JSON.stringify(res))
}
return res.result
},
error => {
closeLoading(error)
// http error
globalError(new Date(), 'err' + error) // for debug
const status = error?.response?.status ?? 'unKnow'
ErrorMessage(status ? ERROR_MSG[status] ?? `连接出错(${status})!` : '未知错误!')
throw new Error(JSON.stringify(error))
}
)
响应拦截就是关闭loading,根据res.success判断响应是否成功,根据不同code返回不同的错误信息
// http 说明表
const ERROR_MSG = {
400: '请求错误(400)',
401: '未授权,请重新登录(401)',
403: '拒绝访问(403)',
404: '请求出错(404)',
408: '请求超时(408)',
429: '系统繁忙,请稍后重试(429)',
502: '网络错误(502)',
503: '服务不可用(503)',
504: '网络超时(504)'
}
布局文件
就是一些布局组件
插件库
就是一些vue插件,有些感觉不是插件也放进来了,vue插件就是提供一个有install方法的对象,然后使用Vue.use方法将插件添加进来,Vue.use会在内部调用对象的install方法,然后将Vue对象当作参数传进去,install里拿到Vue对象就可以执行一些操作,插件使用方法
路由
这里面主要看一下全局前置守卫做了什么操作
router.beforeEach((to, from, next) => {
// document.title = `${to.meta.title}`
const user = session.getSession(SESSIONID)
// 下面的判断是处理边界问题
//
if (!user && !to.meta.public) {
next('/base/login')
} else if (to.meta.permission) {
// 如果是管理员权限则可进入,这里只是简单的模拟管理员权限而已
user === 'admin' ? next() : next('/403')
} else {
next()
}
})
这里边有个疑问sessionid和token到底哪儿个才是用户标识符?
全局状态管理器
全局样式
对浏览器标签进行了初始化设置,并使用了css-generator-plugin插件
页面
放在pages文件夹,比较混乱
+ 使用技术栈 vue 全家桶
+ 关闭vue esm 错误提示 (请注意你的代码标准哦!)
+ 代码格式化 eslint standard标准 [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
+ 网络请求使用 axios
+ 本地存储使用 session (钉钉环境)
+ 高阶函数库使用 lodash
+ 时间处理器 moment
+ 数字精确计算 decimal.js
+ SDK dingtalk-jsapi 2.8.33
+ UI 组件库 ant-design-vue: 1.4