We reconstructed a background management system project with VUE +elementUI. We also added some of our own things to the vUE official scaffolding according to our own business scenarios. Now we record some experience in the construction of the whole system and some tips in the process of using VUE

The first, of course, is to build the entire project from scratch

  • Initialize the whole project with the vue-CLI official template (the one called “webpack”) and then introduce the necessary dependence (element, Axios)

A full-featured Webpack + vue-loader setup with hot reload, linting, testing & css extraction.

  • Build with YARN. Previously built with NPM, the project often didn’t run because some plug-in was updated (the plug-in was upgraded, the vUE that went with the plug-in or some other dependency was not upgraded). Yarn is used mainly because it can lock dependent version numbers through yarn.lock, which is basically the same as NPM. (Now the latest version of NPM also has lock function)
  • Routing and directory structure. Routing adopts the multi-level nested form of official documents, which is very flexible to use. Page files are generally placed in the components folder, and other. Vue files are placed in different folders under views according to function modules.

  • HTTP module axios encapsulation, API layer. First, I wrote an Httputil. js file to wrap the AXIos GET and POST methods. The advantage of this is that I can write some common functions at the bottom of the request.
//HttpUtil.js import router from '.. /router' import axios from 'axios' import Vue from 'vue' var qs = require('qs') const Utils = { get (url, data = {}) { return new Promise((resolve, reject) => { axios.get(url, { params: data, withCredentials: True}). Then (function (response) {if (response.data.code === 1010) {console.log(' no permission ') router.push({path: '/login' }) } else if (response.data.code === 0) { resolve(response) } else { new Vue().$message({ message: response.data.message, type: 'error' }) } }) .catch(function (error) { reject() console.log(error) }) }) }, post (url, data = {}, upload = false) { return new Promise((resolve, reject) => { axios.post(url, upload ? data : qs.stringify(data), { withCredentials: true, headers: {'Content-Type': 'application/x-www-form-urlencoded; Charset =UTF-8'}}). Then (function (response) {if (response.data.code === 1010) {console.log(' no permissions ')} else if (response.data.code === 0) {// console.log(response) resolve(response)} else {console.log(' Interface returns status code: ' + response.data.code) new Vue().$message({ message: response.data.message, type: 'error' }) } }) .catch(function (error) { reject() console.log(error) }) }) } } export default UtilsCopy the code

  • Global introduction of iconFONT, global filter introduction. Introduce filter in main.js and define iconfont in app.vue so that iconfont and filters can be used anywhere in the project. (Font library recommended using Ali’s Iconfont, Iconfont- Alibaba Vector icon library)

  • Mock data schemes. The API file is written this way, so ALL I need to do is change the mock field under config, and the entire project request becomes a JSON file under the request Mock folder
@return {[type]} [description] */ getRSAPublicKey (params) {let postUrl = config.mock? 'static/mock/getKey.json' : process.env.DOMAIN + '/bshop/login/key/get' return HttpUtil.get(postUrl, params) }Copy the code

Practical tips

  • Project performance volume optimization. First, use the analyze function that comes with the scaffold. Set it to package.json scripts as follows
"analyz": "NODE_ENV=production npm_config_report=true npm run build"
Copy the code

Then run NPM Run Analyz, you can see a volume analysis of the project, like this picture, and you can optimize it accordingly.

Here are two points of volume optimization: 1. Element components are introduced on demand, and 2. Lazy route loading. For the first point, there is a very detailed introduction in the official documentation of Ele. me. The second routing lazy loading, you can be found in the above package will become after vendor. Js, 0. XXXX. Js, 1. XXXX. Js, 2. XXXX. Js, every route into a file, project when open the corresponding routing component, will load the corresponding js (well, These are the skateboard shoes I want. The implementation is actually very simple, defined in the routing file in this way

const UserIndex = resolve => require(['@/components/UserIndex'], resolve)
Copy the code

The above is a simple way to implement lazy loading of routing components by combining vUE’s asynchronous components with Webpack’s Code Splitting feature.

  • Front-end authority implementation. There are two permissions for the whole project: button permissions and Tab permissions. The implementation roadmap is simple: 1. Agree with the background code corresponding to each permission, such as ‘AB’. 2. After successful login, store permission information in sessionStroage. (If you use localStorage [multi-label communication], when a computer logs in to two accounts, the latter account will overwrite the permission of the former account). 3. Write a public function that returns whether the permissions are in the permissions array, passing code as a parameter. 4. Button permissions are implemented directly with V-if, TAB permissions are initialized at mouted. All four, basic implementation mind is like this, the concrete implementation depending on the structure of each project will be different (primary routing permissions, secondary routing permissions), my own concrete implementation is quite complicated, to do not have universality, temporarily not here, but there are a few scenarios we also need to be considered: 1. Refresh the page to obtain the latest rights. 2. If no permission is granted on the current page, the page is skipped. 3. If the first TAB option in the second-level menu is deleted, click the first-level menu corresponding to this item to jump to the first available second-level TAB (original second-level TAB) under the first-level menu. 4. When refreshing the page each time, the menu should not shake obviously. (First initialize the page according to the privileges stored in sessionStroage, and then initialize the page with the newly requested privileges)
  • Skillfully use VUEX to load data in advance. There is a detail page with a bunch of selection boxes that need to read data from the background (and this interface is slow to return). In this case, vuex can use a necessary page before this page to load data in advance. Because vuex computed data is responsive, you can’t change it. In this case, you can use json. stringify and json. parse to convert responsive data into a normal array.
  • Default location for storing your profile picture. As we all know, webpack’s url-loader handles converting all images under 10KB in the asset directory to Base64 encoding.
<! - error - >
<img :src="headPic | 'asset/img/default.jpg'">
Copy the code

This code will give you an error, and the GIF will default to the static directory

<img :src="headPic | '/static/img/default.jpg'">
<img :src="'/static/img/month'+ month +'.jpg'">
<! "> < span style =" max-width: 100%; clear: both; min-height: 1em;
<img v-if="headPic" :src="headPic">
<img v-else="headPic" src="asset/img/default.jpg">
Copy the code

  • Resolve ie10 incompatibility bug in 360 compatibility mode by importing ‘ES6-PROMISE/Auto’
  • This.$route.query. XXXX route value remember to use parseInt.
  • Remember to use nexTick for many functions that start after the page has been rendered, such as the viewModel of the el-Checkbox-group. If you set its value after the data has been initialized (before the page has been initialized), it will report an error.
Vue.nextTick(() = > {
      this.selectCountries(a)
      this.disableCountries(a)
 })
Copy the code

  • When using attributes under objects in tags, remember to write v-if judgments. (otherwise, an error will be reported when products is initialized to null)
<div v-if="products" class="len-tip">{{products.length}}/500</div>
Copy the code

  • Vue2. X cancelled debounce and suggested we use libraries such as LoDash. I looked at the team and implemented this in a rather simple way.
      watch: {
            searchInfo (a) {
              let oldSearchInfo = this.searchInfo
              setTimeout(() = > {
                if (this.searchInfo = = = oldSearchInfo) {
                  // Request data
                }
              }, 500)
            }
          }
Copy the code

  • PerfectPixel, a pixel-level page development plug-in. Since the company is very strict about page UI requirements, I found this plug-in, which can paste the design picture on the web page, adjust the transparency of the texture when cutting the page, so that the page and the design picture completely fit, so there is no problem at all.
  • Mounted sequence of parent and child routes. Current VUE ===> Level-1 route === Level-2 route

The last

Weekends should be girlfriend’s request to accompany her to the coffee shop, take the opportunity to write an article summary of a period of time before the work. All of the implementation methods in this article are not the best way to solve the problem. If you have a better way, please leave a comment to me in the comments section below. We will discuss together and make progress together