On the first day, use svn to pull down the project, and then use yarn to install dependencies. What's the use of yarn? Why do many people use yarn now,
Advantages of yarn
Parallel installation, npm is installed in sequence, so the speed of yarn will be faster,
Reuse the cache package. If a software package has been installed before, it will be obtained from the cache when yarn installs it again
Automatically add version lock, yarn Lock is similar to package lock json
Project structure
├─assets # Static resources │ └─img ├─components # Component library │ └─global # Global components < do not need to be registered or imported after placement > ├─decorator # Decorator ├─filter # filter ├─http # Network request ├─layouts # layout file ├─plugins # If the plug-in library needs to introduce third-party components, etc. < CDN > is recommended ├─router # route ├─store # vuex │ └─modules # vuex module ├─style # style │ ├─css # css file │ └─sass # sass tool library styles ├─utils # Tool library catalog └─views # pagefile
assets store static resources
It is worth mentioning that the icons here use Ali's vector icon library. You can see how to use them here iconfont code application
components component library
There are some public components. The components in the global folder will be directly registered in the global components. How can they be registered automatically? In fact, it is to traverse all vue suffix files under the global file, and then obtain the component instance through the file name, and then through vue The component method is registered in the vue global component
import Vue from 'vue' const requireComponents = require.context('./', true, /\.vue/) requireComponents.keys().forEach(fileName => { // Component instance const reqCom = requireComponents(fileName) // Extract the name in the component as the component name const reqComName = reqCom.default.name // Component mount Vue.component(reqComName, reqCom.default || reqCom) })
After a general look at the common components, I feel uncomfortable that the semicolon is not used in the overall project. Because I have learned Java and C + + before, I am used to adding semicolons. I found that / deep / depth selector is useful. See here for the principle of depth selector, vue scoped css
Decorator
The highlight here is the decorator, because this is a js project. I didn't know that js project can also use decoration
It is thought that only ts projects have decorators. In fact, it is to install an additional loader to parse annotations and convert annotations into functions,
@The vue/cli plugin Babel plug-in has a Babel loader, and the Babel loader has a @ Babel / plugin proposal decorators plug-in. This plug-in can be used to parse decorators, which should be the built-in function of vue/cli
filter
There are some filters vue used in it
Network request
Generally, this is about how to intercept requests and responses
Request interception
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)) } )
When sending a request, a loading animation will be triggered first, and then a user-defined attribute sessionid will be added to the request header. Can't you see the use of this now? After that, the user-defined attribute token is added, which is generally a user identifier,
And disable forced caching. What is the reason for this?
Response interception
http.interceptors.response.use( async response => { closeLoading(response.config) let res = response.data if (process.env.VUE_APP_mockFlag === 'true') { // If it is mock mode, there is no outer packaging return res } if (response.config.responseType === 'blob') { // If the request is BLOB console.log('blob') try { const JsonData = await CheckStreamOrJSON(res) res = JsonData } catch { return response } } if (!res.success) { // Logical error custom error code if (res.message) { if (res.code === '401' && !localSession.getLocal(USER_INFO)?.userToken) { // When the getCurrentUserInfo interface is called for the first time, there is no token, and there is no need to prompt message } else { ErrorMessage(res.message) } } globalError('Interface call failed') switch (res.code) { case '401': if (!res.result) { reLogin() } else { // Adapt to the logic of three-party single sign on. If you do not log in, the url of the three-party login will be returned 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] ?? `link error (${status})!` : 'unknown error!') throw new Error(JSON.stringify(error)) } )
Response interception is to close loading, judge whether the response is successful according to res.success, and return different error messages according to different code s
// http description table const ERROR_MSG = { 400: 'Request error(400)', 401: 'Unauthorized, please log in again(401)', 403: 'access denied(403)', 404: 'Request error(404)', 408: 'request timeout(408)', 429: 'The system is busy, please try again later(429)', 502: 'network error(502)', 503: 'Service Unavailable(503)', 504: 'Network Timeout (504)' }
Layout file
Just some layout components
Plug in Library
It's just some Vue plug-ins. Some feel that they are not plug-ins. Vue plug-ins provide an object with an install method, and then use Vue Use method to add the plug-in, Vue Use will call the install method of the object internally, and then pass the Vue object as a parameter. After getting the Vue object in install, you can perform some operations, Plug in usage
route
It's mainly for a look Global front guard What did you do
router.beforeEach((to, from, next) => { // document.title = `${to.meta.title}` const user = session.getSession(SESSIONID) // The following judgment is to deal with the boundary problem // if (!user && !to.meta.public) { next('/base/login') } else if (to.meta.permission) { // If you have administrator privileges, you can enter. Here is just a simple simulation of administrator privileges user === 'admin' ? next() : next('/403') } else { next() } })
There is a question here. Which of sessionid and token is the user identifier?
Global state manager
Global style
The browser tag is initialized and used CSS generator plugin
page
Put it in the pages folder, which is chaotic
+ Using technology stack vue Family bucket + close vue esm Error prompt (Please pay attention to your code standard!) + Code formatting eslint standard standard [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com) + Network request usage axios + Local storage usage session (Nailing environment) + Use of higher-order function library lodash + Time processor moment + Digital accurate calculation decimal.js + SDK dingtalk-jsapi 2.8.33 + UI Component library ant-design-vue: 1.4