Create a complete vue mobile project configuration

The installation of vue and the creation of a new project have been introduced in the previous article. If you need to see the previous article

Mobile end project

I. Some ui frameworks for mobile terminals
1.Voinc: A UI Framework Based on vue.js and ionic Styles( https://wangdahoo.github.io/vonic-documents/#/?id=Introduction)
2.Vux Mobile UI Component Library Based on WeUI and Vue(2.x)( https://vux.li/#/?id=Introduction)
3. NutUI Jingdong Lightweight Mobile Vue Component Library( https://nutui.jd.com/#/index)
4. Mint UI launched by hungry front-end team( http://mint-ui.github.io/docs/#/zh-cn2)
5. Vant is a Vue component library that supports front-end team implementation based on a unified specification( https://github.com/youzan/zent)
6. Mobile Component Library Implemented by Cube UI Drip WebApp( https://didi.github.io/cube-ui/#/zh-CN/docs/quick-start)

II. Mobile Adaptation

Solution: lib-flexible automatically adds a meta name="viewport" tag to the html head, and automatically sets font-size of html to screen width divided by 10, that is, 1 REM equals font-size of html root node. Automatic conversion of PX from css to REM using postcss-px2rem-exclude

Step: 1. Introduce lib-flexible NPM install lib-flexible -- save into the project
2. Introduce lib-flexible import'lib-flexible/flexible.js'into the project entry main.js file
3. Install postcss-px2rem-exclude NPM install postcss-px2rem-exclude--save
4. Find the file. postcssrc.js in the project's root directory and add the following code

"postcss-px2rem-exclude": { 
      remUnit: 75,
      exclude: /node_modules|folder_name/i // Ignore files in the node_modules directory (the style of the introduced third-party ui will not change with it)
    }

3. Install vue plug-in for IDE (I'm using vscode now, take vscode as an example)
1. Search Vetur in the vscode extension

2. Configuration after installation
File -> Preferences -> User Code Fragment -> Click on New Code Fragment -> Name vue.json to determine
3. Delete redundant code
4. Paste the code vue template below

{
    "Print to console": {
        "prefix": "vue",   
        "body": [
            "<!-- $1 -->",
            "<template>",
            "<div class='$2'>$5</div>",
            "</template>",
            "",
            "<script>",
            "//Here you can import other files (such as components, tools, third-party plug-ins, js, json files, image files, etc.).
            "//For example, import Component Name from Component Path;
            "",
            "export default {",
            "//import introduces components that need to be injected into the object before they can be used.
            "components: {},",
            "data() {",
            "//Store data here.
            "return {",
            "",
            "};",
            "},",
            "//The listening attribute is similar to the data concept.
            "computed: {},",
            "//Monitor data changes in data.
            "watch: {},",
            "//Method Set,
            "methods: {",
            "",
            "},",
            "//Life Cycle - Creation Completion (access to current this instance)
            "created() {",
            "",
            "},",
            "//Life Cycle - Mount Completion (DOM Elements can be accessed)
            "mounted() {",
            "",
            "},",
            "beforeCreate() {}, //Life Cycle - Before Creation.
            "beforeMount() {}, //Life cycle - before mounting.
            "beforeUpdate() {}, //Life cycle - before update.
            "updated() {}, //Life cycle - after update.
            "beforeDestroy() {}, //Life cycle - before destruction.
            "destroyed() {}, //Life Cycle - Completion of Destruction.
            "activated() {}, //If the page has keep-alive caching, this function will trigger.
            "}",
            "</script>",
            "<style lang='scss' scoped>",
            "//@ import url(); introduce the common css class.
            "$4",
            "</style>"
        ],
        "description": "Log output to console"
    }
}

6. In the code above, "prefix", "vue" is the shortcut key; after saving, try to create a new. Vue ending file (enter Vue and press tab key)


IV. vue Routing
1. Define components. A component has just been defined with templates
2. Introduce the components just written into router index.js file

I'm using the module-by-module loading method provided by vue-router here.
The following two lines of code do not specify webpackChunkName, and each component is packaged into a js file.

const ImportFuncDemo1 = () => import('../components/ImportFuncDemo1')
const ImportFuncDemo2 = () => import('../components/ImportFuncDemo2')

The following two lines of code specify the same webpackChunkName, which will be merged and packaged into a js file.

// const ImportFuncDemo = () => import(/* webpackChunkName: 'ImportFuncDemo' */ '../components/ImportFuncDemo')
// const ImportFuncDemo2 = () => import(/* webpackChunkName: 'ImportFuncDemo' */ '../components/ImportFuncDemo2')

3. Configuration

import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter)
// Load by module.
const HelloWorld= () => import('../components/HelloWorld')


 const routes=[{
    path: '/',
    redirect: '/HelloWorld',
    name:'HelloWorld'
  },{
    path:'/HelloWorld',
    component: HelloWorld,
    name:'HelloWorld'
  }
]

const router = new VueRouter({
	 routes,
   mode: 'history',
  //  Rigorous mode of vuex
   strict: process.env.NODE_ENV !== 'production',
  // The whole thing is: in the history mode of routing, some list pages use caching mode to record location (usually returning without refreshing, forward refreshing), and scroll Behavior is generally used.
  //At the same time, keep-alive (cache) and activated (hook triggered by cache) are used to make the return record position of the list page. Caching mode also has pits, that is, when the cache is cleared, it is usually cleared from the new page.
  //Back to the topic, the scrolling behavior is: for example, a list page, slides a lot, points in, and then returns to the record just where it was.
	scrollBehavior (to, from, savedPosition) {
	    if (savedPosition) {
		    return savedPosition
		} else {
			if (from.meta.keepAlive) {
				from.meta.savedPosition = document.body.scrollTop;
			}
		    return { x: 0, y: to.meta.savedPosition ||0}
		}
	}
})

export default router

4. Routing files are injected into main.js files

import Vue from 'vue';
import router from './router/index';
import 'lib-flexible/flexible.js';
import App from './App'


new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

5. Configure router-view in app.vue

<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

6. Routing Jump and Reference Mode

 1.$router is an instance of VueRouter. To navigate to different URL s, use the $router.push method
 2.$route is the current router jump object, where you can get name, path, query, params, etc.


(1) Setting up dynamic routing
        {
    		path:'/shopDetails/:id',
   	 		component: shopDetails,
   			 name:'shopDetails'
         }
        Jump this.$router.push('/shopDetails/'+id)
        Get id through this.$route.params.id
       
(2) matching routing by carrying parameters through params and name in routing attributes    
        
         {
    	 	path:'/shopDetails',
		   	 component: shopDetails,
		   	 name:'shopDetails'
         }
         Jump this.$router.push({name:'shopDetails',params:{id:id})  
         Get this.$route.params.id
 (3) By path matching routing, query carries parameters. In this case, the parameters passed by query will be displayed after the url? id=?
         {
	    	 path:'/shopDetails',
		   	 component: shopDetails,
		   	 name:'shopDetails'
         }
         Jump this.$router.push({path:'/shopDetails',query:{id:id})  
         Get this.$route.query.id

7. The difference between query and params

1. Dynamic routing and query attribute transfer page refresh parameters will not be lost, params will lose 2. Dynamic routing is generally used to transfer a parameter (such as the ID of the details page). Query and params can pass one or more parameters.
2. To be frank, query is equivalent to get request. When the page jumps, you can see the request parameters in the address bar, while params is equivalent to post request. The parameters will not be displayed in the address bar.

8. Routing Patterns

V. axios request

The tutorials on the axios documentation are not repeated here. You need to see the documentation. Here I post my tutorial on how to use the axios documentation.
axios document address: https://www.npmjs.com/package/axios

1. Install npm install axios
2. Create a new axios file under utils to configure axios

import axios from 'axios';
const qs = require('qs');
const service=axios.create({
    baseURL: process.env.BASE_API,    //Requesting a public address, the base URL `will be added to `url', so the back request only needs the api way.
    timeout: 5000,    //Request response time
})
// Whether to carry cookie information, default to false, set according to project requirements
service.defaults.withCredentials = true;
// Add a request interceptor
service.interceptors.request.use(function (config) {
    // Do something about requesting data
    if(config.method  === 'post'){  //post parametric serialization
      config.data = qs.stringify(config.data);
    } 
    return config;
  }, function (error) {
    return Promise.reject(error);
  });

// Add a response interceptor
service.interceptors.response.use(function (response) {
    // Do something about response data
    return response;
  }, function (error) {
      console.log(error)
    // Do something with response error
    return Promise.reject(error);
  });
export default  service;

3. Create a new api file, where all request functions are stored to facilitate search and management.

import axios from '../utils/axios';
// Home page banner
export function banner(){
    return axios({
        url:'/wxchat/xxx.action', //Request address
        method:'POST'
    })
}
// post request with parameters
export function qiang(activityStatusType){
    return axios({
        url:'/wxchat/xxx.action',
        method:'POST',
        data:{activityStatusType:activityStatusType}
    })
}
// get request
export function moneys(){
	 return axios({
        url: '/sd-web/xxx',
        method: 'get'
    }); 
}
// get request with parameters
export function moneys(ids){
	 return axios({
        url: '/sd-web/xxx',
        method: 'get',
        params:{id:ids}
    }); 
}

4. Page Practical Application

 import {banner} from '../../api/api'; //Introduce the required request function on the page
  //Use in life cycle functions or methods needed
    mounted() {
        banner().then(response => {
            this.banner=response.data.data.SlAdvertisTabList
        }).catch(err=>{
             console.log(err)
        });
    },
 

5. Cross-domain configuration

(1) Configure cross-domain in index.js written in config folder

proxyTable: {
    '/wxchat': {
      target: 'xxx',  //Target Interface Domain Name
      changeOrigin: true,  //Is it cross-domain?
      secure: false,  //By default, target does not accept back-end servers running on HTTPS and using invalid certificates. If you want to accept it, you need to set this item to false.
      // PathRewrite: {// If the interface itself does not exist / wxchat needs to rewrite the address rewrite interface through pathRewrite
      //   '^/wxchat: ' '   
      // }
    }
},

Note: In this project I wrote, there is a / wechat universal prefix, so I didn't rewrite it with pathRewrite. If you don't have a universal prefix in your interface, you need to rewrite it.

In the above configuration,'^/wxchat'is actually a regular expression.

'^/wxchat'should be split into'^' and'/ wxchat'strings, where'^' matches the initial position of the string.

'/ wxchat': {} tells node that my interface will only use proxy if it begins with'/ wxchat'. So your interface will write / wxchat/xx/xx. The final proxy path is http://xxx.xx.com/wxchat/xx/xx.
But no, I don't have / wxchat in the correct interface path. So I need path Rewrite, remove'/ wxchat'with'^/ wxchat':', so that I can not only have the correct identification, but also remove wxchat when I request the interface.

Configuration of development environments without universal prefixes for interfaces

'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')

module.exports = merge(prodEnv, {
  NODE_ENV: '"development"',
  BASE_API: '"/wechat"',     //If you configure //wechat across domains, you don't need to write a universal prefix in the interface, just write it according to the normal interface.
})

Development Environment Configuration with Universal Prefixes for Interfaces

'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')

module.exports = merge(prodEnv, {
  NODE_ENV: '"development"',
  BASE_API: '""',     //Just empty here. The universal prefix is written in the interface.
})

VI. Use of vuex

When should we use vuex for the use of vuex? When you think you need a global state, but it's too cumbersome in other ways, you need it. For example, in an app project I'm working on now, the header component is a public component. How can the header component's title change with the page's jump? Commentable with different understandings)
Disadvantage: vuex page refresh, data will be lost solution: local storage, state data can be obtained locally

1. In vuex, there are five basic default objects:

  • state
  • getters can be interpreted as state's computational properties by monitoring the changes of state values in real time and compiling the data before acquisition.
  • mutations
  • actions: Asynchronous triggering mutations
  • modules: store's sub-module, which is used to develop large-scale projects and facilitate state management. Let's not explain it here. It's the same as above.

2. Download and install vuex NPM install vuex--save
3. Create a new store folder under src to create an index.js to configure.
4. Introduce vue, vuex and use global injection plug-in

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store=new Vuex.Store({
    // Set the state value to be accessed globally
    state:{
       title:'Test title',    //Head Title
    }
})
export default store;

5. Introduce store in main.js and inject it globally

import Vue from 'vue';
import router from './router/index';
import store from './store';
import 'lib-flexible/flexible.js';
import App from './App'


new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})

6. Test the title just written in any component

<template>
    <div class='orderDetails'>
        {{$store.state.title}}
    </div>
</template>

7. As shown in the figure, the title has been set successfully.

8. The title has been successfully set as shown in the figure above. How to change the title? We need to use mutations object. We define a method to change the title in mutations object. The parameters in mutations are the first default state, and the next is the custom parameters.

 // Synchronized by changing the initial value in state
    mutations :{
        TITLE(state,title){
            return state.title=title
        },
    },

9. Look at the test results

9. You can see from the diagram that this has been implemented. Next, look at the asynchronous operation.

 // When asynchronously triggering the methods in mutations to execute the methods in actions globally in external components, you only need to execute this.$store.dispatch('title', 132) so that you can change the value of the title globally.
    actions:{
       title({commit},title){
            commit('TITLE',title)
        },
    }

It's not the same as the previous synchronization operation.

10. The difference between synchronization and asynchronization in vuex

1. When the point is sent too fast, the content rendered on the page is inconsistent with the data in the state, and the state in vuex becomes slow and does not update continuously.
2. In action, data consistency can be achieved in the state of the page.
3. When you have asynchronous operations in your operations, such as sending requests to the background for data acquisition, you need to use action dispatch to complete. Others can use commit.

Packing on-line
1.

Execute npm run build command

2. After execution, you will find that there is an additional dist folder in your directory, which is the packaged data.

3. Reasons for page blankness after packaging
3.1 css, js path reference error problem

Solution: Open the index.js file in the config folder.
There are two assetsPublicPath attributes in the file. The first one is to change the assetsPublicPath attribute in build:
The assetsPublicPath attribute specifies the root directory for compilation and publication,'/'refers to the project's root directory,'. /' refers to the current directory.

3.2 Setting up Routing history Mode

Solution: Change to hash or delete the mode configuration directly so that it defaults. If you have to use history mode, you need to add a candidate resource on the server that covers all situations: if the URL does not match any static resource, you should return an index.html, which is your app dependent page.

Tags: Vue axios Mobile npm

Posted on Fri, 09 Aug 2019 00:18:11 -0700 by suthen_cowgirl