vue



Vue official API

The following case involves sample code:The sample code

Progressive framework



Vue is a progressive framework for building user interfaces using a bottom-up, incremental design. Vue’s core libraries focus solely on the view layer and are not only easy to get started with, but also easy to integrate with third-party libraries or existing projects.

Progressive presentation: declarative rendering – component systems – Client routing – Big data state management – build tools

Two core points

(1) Responsive data binding: When the data changes, the view is automatically updated, namely bidirectional data synchronization. The principle uses the setter/getter proxy data in Object. DefinedProperty in ES6 to monitor the operation of the data. (2) The combined view components, namely pages, are finally mapped into a component tree, which is designed with tree-shaped data structure for easy maintenance and reuse.

Virtual DOM



Using in memory to generate the data structure corresponding to the real DOM, this generated in memory structure is called the virtual DOM. When the data changes, the minimum cost of rerendering the component is intelligently calculated and applied to the DOM operation.

MVVM




MVVM is short for Model-View-ViewModel. It is an architectural pattern based on front-end development. The core of MVVM is to provide two-way data binding between View and ViewModel, which enables state changes of ViewModel to be automatically transmitted to View. This is called bidirectional data binding.

M: Model (data layer, i.e., index data (front-end is JS))

V: View (i.e. DOM layer or user interface)

VM: ViewModel (middle layer that handles data and interface, i.e. Vue)

Declarative rendering

At the heart of viee. js is a system that allows you to declaratively render data into the DOM using a concise template syntax. Additional: apply colours to a drawing is divided into: render imperative and declarative rendering Imperative to render: command our program what to do, step by step program will follow your command to perform declarative rendering: only need to tell the program to want what effect, application to the other to do specific differences, see the following code execution results, achieve in a different way.

<script type="text/javascript">
    var arr = [1.2.3.4.5];

    // Imperative rendering: care about each step, care about the process, using commands to implement
    var newArr = [];
    for(var i = 0, len = arr.length; i < len; i++) {
        newArr.push(arr[i] * 2);
    }
    console.log(newArr);

    // Declarative rendering: don't care about the intermediate process, only care about the result and implementation conditions
    var arr1 = arr.map(function(item) {
        return item*2;
    });
    console.log(arr1);
</script>
Copy the code

The life cycle

Official document: VUE Official Lifecycle Diagram VUE Lifecycle API

1, life cycle diagram


2. Life Cycle tables

cycle instructions
beforeCreate Data observation is called after instance initialization and before event configuration
created It is called immediately after the instance is created, completes data observation, calculates properties and methods, and initializes events. The $EL attribute is not seen
beforeMount Called before the mount begins: the relevant render function is called for the first time, generating HTML only in the virtual DOM
mounted Called after EL has been replaced by the newly created VM.$el and mounted to the instance. The instance has been configured to replace the DOM object to which the EL attribute points with the compiled HTML content above. Complete the HTML rendering from the template to the HTML page. Ajax interaction during this process
beforeUpdate Called before data updates, before the virtual DOM is rerendered and patched. You can further change the state in this hook without triggering additional rerendering
updated Called after the virtual DOM has been rerendered and patched due to data changes. When called, the component DOM has been updated, so DOM dependent operations can be performed. In most cases, however, you should avoid changing the state during this period, as this can result in an infinite loop of updates. This hook is not called during server-side rendering
activated Called when the keep-alive component is activated
deactivated Called when the keep-alive component is disabled
beforeDestroy Called before the instance is destroyed. The instance is still fully available
destroyed Called after instance destruction. Once called, all event listeners are removed and all child instances are destroyed. This hook is not called during server-side rendering

3, code detailed explanation

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue Introduction to Helloworld</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        {{message}}
    </div>

<script type="text/javascript">
var app=new Vue({
    el:'#app'.data: {message:'hello Vue! '
    },
    beforeCreate: function () {
        console.group('State of beforeCreate before creation ===============');
        console.log("%c%s"."color:red" , "el : " + this.$el); //undefined
        console.log("%c%s"."color:red"."data : " + this.$data); //undefined 
        console.log("%c%s"."color:red"."message: " + this.message)  
    },
    created: function () {
        console.group('Created create complete status ===============');
        console.log("%c%s"."color:red"."el : " + this.$el); //undefined
        console.log("%c%s"."color:red"."data : " + this.$data); // Has been initialized
        console.log("%c%s"."color:red"."message: " + this.message); // Has been initialized
    },
    beforeMount: function () {
        console.group('beforeMount Status before mounting =============== ');
        console.log("%c%s"."color:red"."el : " + (this.$el)); // Has been initialized
        console.log(this.$el);
        console.log("%c%s"."color:red"."data : " + this.$data); // Has been initialized
        console.log("%c%s"."color:red"."message: " + this.message); // Has been initialized
    },
    mounted: function () {
        console.group(Mounted End status ===============);
        console.log("%c%s"."color:red"."el : " + this.$el); // Has been initialized
        console.log(this.$el);     
        console.log("%c%s"."color:red"."data : " + this.$data); // Has been initialized
        console.log("%c%s"."color:red"."message: " + this.message); // Has been initialized
    },
    beforeUpdate: function () {
        console.group('beforeUpdate status beforeUpdate =============== ');
        console.log("%c%s"."color:red"."el : " + this.$el);
        console.log(this.$el);    
        console.log("%c%s"."color:red"."data : " + this.$data); 
        console.log("%c%s"."color:red"."message: " + this.message); 
    },
    updated: function () {
        console.group('Updated complete status ===============');
        console.log("%c%s"."color:red"."el : " + this.$el);
        console.log(this.$el); 
        console.log("%c%s"."color:red"."data : " + this.$data); 
        console.log("%c%s"."color:red"."message: " + this.message); 
    },
    beforeDestroy: function () {
        console.group('beforeDestroy State before destruction =============== ');
        console.log("%c%s"."color:red"."el : " + this.$el);
        console.log(this.$el);     
        console.log("%c%s"."color:red"."data : " + this.$data); 
        console.log("%c%s"."color:red"."message: " + this.message); 
    },
    destroyed: function () {
        console.group('Destroyed state completed ===============');
        console.log("%c%s"."color:red"."el : " + this.$el);
        console.log(this.$el);  
        console.log("%c%s"."color:red"."data : " + this.$data); 
        console.log("%c%s"."color:red"."message: " + this.message)
    }
})
</script>
</body>
</html>
Copy the code

4. Result analysis

Open it in Chrome, F12 look at console, and read it in three stages: Stage 1: Create and mount

  • Beforecreated: EL and data are not initialized
  • Created: data is initialized, but EL is not
  • BeforeMount: El and data are initialized
  • Mounted: The mounting is complete

Phase 2: Update Run the following command on chrome Console:

app.message= 'yes !! I do';
Copy the code
  • BeforeUpdate: The virtual DOM updates the HTML based on data changes
  • Updated: Updates the VIRTUAL DOM updated HTML to the page

Phase 3: Destruction Run the following command on chrome Console:

app.$destroy();
Copy the code
  • BeforeDestroy: called before destruction
  • App. Message = ‘Hello vue’. The page will not be updated synchronously.

The specific diagram is as follows:

Commonly used options

Vue has many configuration options, some of which are commonly used, as described in this section

1, the computed

Calculated attributes: mainly to transform the original data output. Modify output: including formatting data (price, date), case conversion, sorting, adding symbols

computed: {
    newPrice () {
        return A '$' + this.price + '元'; }}Copy the code

2, the methods,

Method properties: Used to bind methods corresponding to events in HTML

methods:{
    add (num) {
        this.count += num; }}Copy the code

3, watch

Data change listener: Mainly used to monitor data changes in data. The DIV-Model takes effect

watch: {
    question(val, oldVal) {
        console.log('new: %s, old: %s', val, oldVal); }}Copy the code

4, filters,

Filters: Usually format characters, using pass-values

filters: {
    filterA(value) {
        returnvalue.toUpperCase(); }}Copy the code

5, mixins

Mixed in: Used to reduce code pollution, reduce code volume, and achieve code reuse

// When added temporarily, it is used to display logs
var addLog={
    updated:function(){
        console.log("Data release changes, changes into."+this.count+"."); }}// Instantiate vue
var app = new Vue({
    // Mount the instance
    el:'#app'.// Page data initialization, characters, objects, arrays
    data: {count: 100
    },
    / / with
    mixins: [addLog]
})
Copy the code

6, extends

Extension: Extends the constructor

/ / extension
var extendObj ={
    created: function(){
        console.log("I'm being expanded."); }}// Instantiate vue
var app = new Vue({
    // Mount the instance
    el:'#app'.// Page data initialization, characters, objects, arrays
    data:{
    },
    / / extension
    extends: extendObj
})
Copy the code

Complete code example

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue Introduction to Helloworld</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        {{message}}
        <div>Price: {{newPrice}}</div>
        <div>The Numbers: {{count}}</div>
        <div><button @click="add(2)">add</button></div>
        <div><input v-model="question"></div>
        <div>Filtering: {{filtera | filtera}}</div>
    </div>

<script type="text/javascript">
// When added temporarily, it is used to display logs
var addLog={
    updated:function(){
        console.log("Data release changes, changes into."+this.count+"."); }}/ / extension
var extendObj ={
    created: function(){
        console.log("I'm being expanded."); }}// Instantiate vue
var app = new Vue({
    // Mount the instance
    el:'#app'.// Page data initialization, characters, objects, arrays
    data: {message: 'hello Vue! '.price: 100.count: 100.question: ' '.filtera: 'abc'
    },
    // Calculate attributes: mainly to transform the original data output.
    // Modify output: format data (price, date), case conversion, sort, add symbols
    computed: {
        newPrice () {
            return A '$' + this.price + '元'; }},// Method declaration: used to bind methods in HTML
    methods:{
        add (num) {
            this.count += num; }},// The data attribute listens for v-model
    watch: {
        question(val, oldVal) {
            console.log('new: %s, old: %s', val, oldVal); }},// Filters, which usually format characters, use passed values
    filters: {
        filterA(value) {
            returnvalue.toUpperCase(); }},// Mix: reduce code pollution, reduce code volume, and achieve code reuse
    mixins: [addLog],
    / / extension
    extends: extendObj
})
</script>
</body>
</html>
Copy the code

Examples of event

Vue has instance properties, instance methods, and instance events. The first two are similar to options. They are not used very often.

1, $on (add event outside constructor)

$ON takes two arguments. The first argument is the name of the event that was called, and the second argument is an anonymous method

app.$on('reduce'.function(){
    console.log('Reduce () executed');
    this.count--;
});
Copy the code

2. $once (event executed once)

app.$once('reduceOnce'.function(){
    console.log('Methods that are executed only once');
    this.count--;
});
Copy the code

3, $off (close event)

function off(){
    console.log('Close the event');
    app.$off('reduce');
}
Copy the code

4, $emit (event call)

function reduce() {
    // Event invocation
    console.log('Emit event call');
    app.$emit('reduce');
}
Copy the code

Complete sample code

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue Introduction to Helloworld</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <div>The Numbers: {{count}}</div>
        <button onclick="reduce()">On call</button>
        <button onclick="reduceOnce()">Once call</button>
        <button onclick="off()">Off call</button>
    </div>

<script type="text/javascript">
var app = new Vue({
    el:'#app'.data: {count: 1}})$on adds events outside the constructor
app.$on('reduce'.function(){
    console.log('Reduce () executed');
    this.count--;
});
/ / call
function reduce() {
    // Event invocation
    console.log('Emit event call');
    app.$emit('reduce');
}

// $once specifies the event to be executed once
app.$once('reduceOnce'.function(){
    console.log('Methods that are executed only once');
    this.count--;
});
/ / call
function reduceOnce() {
    app.$emit('reduceOnce');
}

// Close the event
function off(){
    console.log('Close the event');
    app.$off('reduce');
}
</script>
</body>
</html>
Copy the code

Custom instruction

Custom directives in vue are implemented through vue. directive and do something that the built-in directives cannot

1. Sample code

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue introduction to custom instructions</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <div v-test="color">
        {{num}}
    </div>
</div>
<button onclick="unbindApp()">unbundling</button>

<script type="text/javascript">
/ / unbundling
function unbindApp() {
    app.$destroy();
}

// Custom instruction
Vue.directive("test", {/ / 1 - bound
    bind:function (el, binding, vnode) {
        console.log("1-bind is bound");
        console.log("el:",el);
        console.log("binding:",binding);
        console.log("vnode:",vnode);
        el.style.color = binding.value;
    },
    / / 2 - is inserted
    inserted:function (el, binding, vnode) {
        console.log("2-inserted inserted");
    },
    / / 3 - update
    update:function (el, binding, vnode) {
        console.log("3 - update to update");
    },
    //4- The update is complete
    componentUpdated:function (el, binding, vnode) {
        console.log("4-componentUpdated complete");
    },
    / / 5 - unbundling
    unbind:function (el, binding, vnode) {
        console.log("5 - to unbind solution"); }});var app = new Vue({
    el:'#app'.data: {num: 123.color:'red'}})</script>
</body>
</html>
Copy the code

2. Debugging procedure

(1) Chrome opens the controller to view (2) Console type “app.num= ‘new name set by console'” (3) Click unbind button

3. Parameter description

  • El: The element bound by the directive, which can be used to manipulate the DOM directly
  • Binding: An object that contains a lot of information about an instruction
  • Vnode: : Virtual node generated by Vue compilation

4. Life cycle

A custom directive has five life cycles (also called the hook function), which are bind, inserted, Update, componentUpdated, and unbind.

  1. Bind: called only once, when a directive is first bound to an element. Use this hook function to define an initialization action to be performed once on the binding
  2. Inserted: called when the bound element is inserted into the parent (called when the parent is present, not necessarily in the document)
  3. Update: called when the template to which the element is bound is updated, regardless of whether the binding value has changed. Unnecessary template updates can be ignored by comparing binding values before and after updates
  4. ComponentUpdated: called when the template of the bound element completes an update cycle
  5. Unbind: called only once, when a directive is unbound from an element

Component based

1. Component registration

(1) Global registration

// script
Vue.component('button-counter', {
    data: function () {
        return {
            count: 0}},template: '< button v - on: click = "count++" > global components display: {{count}} < / button >'
});

new Vue({
    el: '#app'
});

/ / HTML to use
<button-counter></button-counter>
Copy the code

(2) Local registration

// script
new Vue({
    el: '#app'.components: {"button-inner": {data: function() {
                return {
                    inner: 0}},template: '< button v - on: click = "inner++" > partial components display: {{inner}} < / button >'}}});/ / HTML to use
<button-inner></button-inner>
Copy the code

2. Pass the props attribute

(1) Attribute value

// script
new Vue({
        el: '#app'.components: {"button-props": {template:`
      
parameter 1: {{here}}:-- parameter 2: {{fromHere}}< div> '
.props: ['here'.'fromHere']}}});/ / HTML to use <button-props here="hello" from-here="world"></button-props> Copy the code

PS: If the attribute contains “-“, the props needs the hump value

(2) Pass value to component in constructor (V-bind)

// script
new Vue({
        el: '#app'.data: {
            message: 'hello'
        },
        components: {"button-props": {template:`
      
parameter 1: {{here}}:-- parameter 2: {{fromHere}}< div> '
.props: ['here'.'fromHere']}}});/ / HTML to use <button-props v-bind:here="message" :from-here="message"></button-props> Copy the code

3. Parent and child components

// script
/ / child component
var city = {
    template:`<div>Sichuan of China</div>`
}
/ / the parent component
var parent = {
    template:
        `
      

Panda from China!

`
.components: {"city": city } } / / instantiate new Vue({ el: '#app'.// Define local components components: {// Register the component "parent": parent } }); / / HTML to use <parent></parent> Copy the code

Complete sample code

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue Entry components</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <! -- Global component -->
    <div><button-counter></button-counter></div>
    <! -- Partial component -->
    <div><button-inner></button-inner></div>
    <! -- general attribute pass value -->
    <div><button-props here="hello" from-here="world"></button-props></div>
    <! -- v -- bind -->
    <div><button-props v-bind:here="message" :from-here="message"></button-props></div>
    <! -- Parent component call -->
    <div><parent></parent></div>

</div>

<script type="text/javascript">
    // Define global components
    Vue.component('button-counter', {
        data: function () {
            return {
                count: 0}},template: '< button v - on: click = "count++" > global components display: {{count}} < / button >'
    });

    / / child component
    var city = {
        template:`<div>Sichuan of China</div>`
    }
    / / the parent component
    var parent = {
        template:
            `
       

Panda from China!

`
.components: {"city": city } } / / instantiate new Vue({ el: '#app'.data: { message: 'hello' }, // Define local components components: {"button-inner": {data: function() { return { inner: 0}},template: '< button v - on: click = "inner++" > partial components display: {{inner}} < / button >' }, / / value "button-props": {template:`
parameter 1: {{here}}:-- parameter 2: {{fromHere}}< div> '
.props: ['here'.'fromHere']},// Register the component "parent": parent } });
</script> </body> </html> Copy the code

To make the template

Templates in Vue are implemented using template

1, options template

<div id="app">
</div>

<script type="text/javascript">
    / / instantiate
    new Vue({
        el: '#app'.data: {
            message: 'hello'
        },
        template:'

'
});
</script>
Copy the code

2. Label template

<div id="app">
    <template id="demo2">
        <h2 style="color:red">I'm the template tag template</h2>
    </template>
</div>

<script type="text/javascript">
    / / instantiate
    new Vue({
        el: '#app'.data: {
            message: 'hello'
        },
        template:'#demo2'
    });
</script>
Copy the code

3,

<div id="app">
</div>
<script type="x-template" id="demo3">
    <h2 style="color:red">I'm a script tag template</h2>
</script>
<script type="text/javascript">
    / / instantiate
    new Vue({
        el: '#app'.data: {
            message: 'hello'
        },
        template:'#demo3'
    });
</script>
Copy the code

Complete sample code

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue Entry components</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <! -- template -->
    <template id="demo2">
        <h2 style="color:red">I'm the template tag template</h2>
    </template>
</div>
<! -- script tag template -->
<script type="x-template" id="demo3">
    <h2 style="color:red">I'm a script tag template</h2>
</script>
<script type="text/javascript">
    / / instantiate
    new Vue({
        el: '#app'.data: {
            message: 'hello'
        },
        // Option template
        //template: '

'
//template:'#demo2' template:'#demo3' });
</script> </body> </html> Copy the code

Slot slot.

A slot is an HTML template for a component. The two most important questions about a slot are whether to display it and how to display it

1. Single slot

Single slot, alias default slot, anonymous slot, do not set the name attribute

<div id="app">
    <children1>
        <span>12345</span>
    </children1>
</div>
<script type="text/javascript">
    var app = new Vue({
        el: '#app'.components: {
            children1: {
                template: ""}}});</script>
Copy the code

2. Named slot

A slot becomes a named slot by adding the name attribute. Named slots can appear N times in a component, in different locations

<div id="app">
    <children2>
        <span slot="first" @click="tobeknow">12345</span>
        <span slot="second">56789</span>
    </children2>
</div>
<script type="text/javascript">
    var app = new Vue({
        el: '#app'.methods: {
            tobeknow: function () {
                console.log("It is the parent's method"); }},components: {
            children2: {// This returns no value and will not be distributed
                template: "< slot name='first'>"}}});</script>
Copy the code

3. Scope slot

In Vvue2.5, slot-scope replaces scope to implement scoped slots, which are used in component calls. Specifically, the template tag uses slot-scope to get the value of the attribute on the slot, which is an object. Slot-scope = “it can take any string”, often seen in element-UI components.

<div id="app">
    <! -- pass data to component -->
    <tb-list :data="data">
        <! -- get the value above the slot -->
        <template slot-scope="scope">
            <p>Index: {{JSON. Stringify (scope)}}</p>
            <p>Index: {{scope. $index}}</p>
            <p>Name: {{scope. Row. The name}}</p>
            <p>Age: {{scope. Row. Age}}</p>
            <p>Gender: {{scope. Row. Sex}}</p>
        </template>
    </tb-list>
</div>
<script type="text/javascript">
    var app = new Vue({
        el: '#app'.data: {
            data: [{
                name: 'kongzhi1'.age: 'and'.sex: 'man'}},components: {
            // Scope slot
            'tb-list': {
                template:
                    `
       
`
./ / get the value props: ['data']}}});
</script> Copy the code

Complete code example

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue entry slot</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <children1>
        <span>12345</span>
    </children1>
    <children2>
        <span slot="first" @click="tobeknow">12345</span>
        <span slot="second">56789</span>
    </children2>
    <! -- pass data to component -->
    <tb-list :data="data">
        <! -- get the value above the slot -->
        <template slot-scope="scope">
            <p>Index: {{JSON. Stringify (scope)}}</p>
            <p>Index: {{scope. $index}}</p>
            <p>Name: {{scope. Row. The name}}</p>
            <p>Age: {{scope. Row. Age}}</p>
            <p>Gender: {{scope. Row. Sex}}</p>
        </template>
    </tb-list>
</div>
<script type="text/javascript">var app = new Vue({ el: '#app', data: { data: [{ name: 'kongzhi1', age: '29', sex: 'man' }] }, methods: { tobeknow: function () { console.log("It is the parent's method"); }}, components: {// single slot children1: {template:"<button><slot></slot>A single slot</button>"
            },
            // 具名slot
            children2: {
                template: "<button><slot name='first'></slot>Named slot,<slot name='second'></slot></button>"}, // Scope slot 'tb-list': {template: '<ul>
                        <li v-for="(item, index) in data">
                            <slot :row="item" :$index="index"></slot>
                        </li>
                    </ul>', // getprops: ['data']}});</script>
</body>
</html>
Copy the code

vue-router

Official document Vue Router is the official route manager of vue. js. Its deep integration with the vue.js core makes building a single page application a breeze. The functions included are:

  • Nested routing/viewing diagrams
  • Modular, component-based routing configuration
  • Route parameters, queries, and wildcards
  • View transition effect based on vue. js transition system
  • Fine-grained navigation control
  • Links with automatically activated CSS classes
  • HTML5 history mode or hash mode, automatically demoted in IE9
  • Custom scroll bar behavior

Quick start

A brief introduction

Vue-router is the official routing solution of VUE. It is easy to use. The official Address in Chinese is as follows: Vue-router Chinese manual

Second, the installation

Vue-router is a plug-in package that needs to be installed using NPM. If you use vue-CLI to build the initialization project, you will be prompted to install it, or you can use the command to install it yourself:

npm install vue-router --save
Copy the code

3. Interpret core documents

After building the project with vue-cli, in the SRC /router/index.js file, you will see the following routing core files:

// Introduce the vUE framework
import Vue from 'vue'
// Import vue-router routing dependency
import Router from 'vue-router'
// Introduce the page component and name it HelloWorld
import HelloWorld from '@/components/HelloWorld'
// Vue uses Router globally
Vue.use(Router)
// Define route configuration
export default new Router({
  routes: [                // Configure routing, which is an array
    {                        // Each link is an object
      path: '/'.// Link the path
      name: 'HelloWorld'.// Route name,
      component: HelloWorld     // The corresponding component template}]})Copy the code

Four, the use of

Inject the router into the system entry file main.js as follows:

// Introduce the vUE framework
import Vue from 'vue'
// Introduce the root component
import App from './App'
// Configure the imported route
import router from './router'
// Disable the prompt given in production mode
Vue.config.productionTip = false
// Define the instance
new Vue({
  el: '#app',
  router, // Inject into the framework
  components: { App },
  template: '<App/>'
})
Copy the code

This section describes how to configure route attributes

The code is as follows:

export default new Router({
    mode: 'history'.// Routing mode. The value can be History and hash
    base: '/'.// The package path, which defaults to /, can be changed
    routes: [{path: string, / / path
        ccomponent: Component; // Page components
        name: string; // Name route - Indicates the name of the route
        components: { [name: string]: Component }; // Name the view component
        redirect: string | Location | Function; / / redirection
        props: boolean | string | Function; // Routing components pass parameters
        alias: string | Array<string>; // Route alias
        children: Array<RouteConfig>; // Nested subroutesbeforeEnter? :(to: Route, from: Route, next: Function) = > void; // Route individual hooks
        meta: any; // Customize the tag attributes, such as whether login is required
        icon: any; / / icon
        / / server +
        caseSensitive: boolean; // Is the matching rule case-sensitive? (Default: false)
        pathToRegexpOptions: Object; // Options for compiling regex}]})Copy the code

Page jump

1. Router-link indicates the router-link label

Use router-link to jump within the HTML tag, corresponding to the hyperlink A tag, as follows:

<router-link to="/">[Display field]</router-link>Copy the code

To: navigation path The following is an example:

<p> Navigation: <router-link to="/"> home page < / router - the link ><router-link to="/hello">hello</router-link>
</p>
Copy the code

Two, programmatic navigation -JS code internal jump

In the actual project, most of the time is through the JS code inside the navigation jump, the use of the following way:

this.$router.push('/xxx')
Copy the code

Simple usage :(1) write a button and bind the goHome() method on the button.

<button @click="goHome"</button>Copy the code

(2) in

export default {
    name: 'app'.methods: {
        goHome(){
            this.$router.push('/home'); }}}Copy the code

3. Other common methods

// Record a step back, equivalent to history.back()
this.$router.go(-1)
// Move forward in the browser record, equivalent to history.forward()
this.$router.go(1)
Copy the code

Subroutes and routes are nested

Child routing, also called route nesting, is implemented by following children with a route array. The array is basically the same as other configured routes. You need to configure path and Component, and then add the corresponding part to display the child page information, which is equivalent to embedding iframe. Take a look at the following example:

SRC /components/ home.vue (parent page)

<template>
    <div class="hello">
        <h1>{{ msg }}</h1>
        <! -- Add child route navigation -->
        <p>Navigation:<router-link to="/home">Home page</router-link> | 
            <router-link to="/home/one">- Subpage 1</router-link> |
            <router-link to="/home/two">- Subpage 2</router-link>
        </p>
        <! -- Subpage display section -->
        <router-view/>
    </div>
</template>
<script>
export default {
    name: 'Home',
    data () {
        return {
            msg: 'Home Page! '}}}</script>
<style scoped>
</style>
Copy the code

2, SRC /components/ one.vue (subpage 1)

<template>
    <div class="hello">
        <h1>{{ msg }}</h1>
    </div>
</template>
<script>
export default {
    name: 'One',
    data () {
        return {
            msg: 'Hi, I am One Page! '}}}</script>
<style scoped>
</style>
Copy the code

3, SRC /components/ two-.vue (subpage 2)

<template>
    <div class="hello">
        <h1>{{ msg }}</h1>
    </div>
</template>
<script>
export default {
    name: 'Two',
    data () {
        return {
            msg: 'Hi, I am Two Page! '}}}</script>
<style scoped>
</style>
Copy the code

SRC /router/index.js (route configuration)

import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/components/Home'
import One from '@/components/One'
import Two from '@/components/Two'
Vue.use(Router)
export default new Router({
    routes: [{path: '/'.// The default page redirects to the home page
        redirect: '/home'
    },
    {
        path: '/home'.// Home page routing
        name: 'Home'.component: Home,
        children: [// Nested subroutes
            {
                path:'one'.// Subpage 1
                component:One
            },
            {
                path:'two'.// Subpage 2
                component:Two
            },
        ]
    }
    ]
})
Copy the code

5. Renderings



PS: Each part of the code is very simple, also annotated, after using vue-CLI initialization project completed directly copy to the corresponding directory to see the effect.

Route transfer parameter

1. Pass the parameter through to in the tag

Basic grammar:

<router-link :to="{name:xxx, params: {key:value}}">valueString</router-link>
Copy the code

PS: “to” is preceded by a colon, followed by an object state string

  • Name: name in the route configuration file. It’s called named routing, and we’ll talk about that in the next video.
  • Params: Arguments to pass, which are in the form of objects in which multiple values can be passed.

(1) add the following code to the navigation inside SRC /components/ home.vue:

<router-link :to="{name: 'one', params:{username:'test123'}}"> child pages1</router-link>
Copy the code

(2) Add the following code to SRC /router/indes.

{
    path:'one'.// Subpage 1
    name: 'one'.// Route name - Names the route
    component:One
}
Copy the code

(3) accept parameters in SRC /components/ one.vue.

<h2>{{$route.params.username}}</h2>
Copy the code

2. Pass parameters in the URL

(1) Add the following code to the SRC /router/index.js file:

{
    path:'/home/two/:id/:name'.// Subpage 2
    component:Two
},
Copy the code

(2) Take the arguments and add the following code in SRC /components/ two-.vuez:

< p > ID: {{$route. Params. ID}} < / p > < p > name: {{$route. Params. Name}} < / p >Copy the code

(3) route jump, add the following code in SRC /components/ home.vue:

</router-link> </router-link>Copy the code

PS: to is a string route without a colon and must be matched. (4) If the route parameters need to have specific rules, you need to add regular expressions, as shown in the following example:

{
    path:'/home/two/:id(\\d+)/:name'.// Subpage 2
    component:Two
}
Copy the code

3, programmatic navigation – Params pass parameters

(1) Add the following code to the SRC /router/index.js page:

{
    path:'/home/three'.// Subpage 3
    name: 'three'.component:Three
}
Copy the code

(2) add the following code to the SRC /components/ three.vue page:

< p > ID: {{$route. Params. ID}} < / p ><p>Name: {{$route.params.name}}</p>
Copy the code

(3) add the following code to SRC /components/ home.vue:

// template
<button @click="toThreePage"> page3- params mass participation < / button >// script
methods: {
    toThreePage() {
        this.$router.push({name: 'three'.params: {id: 1.name: 'zhangsan'}}}})Copy the code

This.$router-push () method is not allowed to use path with params, otherwise params will be invalid. You need to specify the page by name. B. The above parameters will not be displayed in the address bar of the browser. If the page is refreshed once, the parameters will not be obtained.

{
    path:'/home/three/:id/:name'.// Subpage 3
    name: 'three'.component:Three
}
Copy the code

4, programmatic navigation -query pass parameters

(1) Add the following code to the SRC /router/index.js page:

{
    path:'/home/three'.// Subpage 3
    name: 'three'.component:Three
}
Copy the code

(2) add the following code to the SRC /components/ three.vue page:

< p > ID: {{$route. Query. ID}} < / p ><p>Name: {{$route.query. Name}}</p>
Copy the code

(3) add the following code to SRC /components/ home.vue:

// template
<button @click="toThreePage"> page3- params mass participation < / button >// script
methods: {
    toThreePage() {
        this.$router.push({path: '/home/three'.query: {id: 1.name: 'zhangsan'}}}})Copy the code

/home/three? /home/three? /home/three? id=1&name=zhangsan

Name route – Name view – Redirection – alias

1. Name the route

Give a route a unique name and jump to call that name. SRC /router/index.js = SRC /router/index.js = SRC /router/index.js = SRC /router/index.js = SRC /router/index.js = SRC /router/index.js

{
    path: 'one'.// Subpage 1
    name: 'one'.// Route name - Names the route
    component: One // Page components
}
Copy the code

Vue/SRC /component/ home.vue

// Template jump call
<router-link :to="{name: 'one'}"> child pages1</router-link>
// Router. Push function jump call
router.push({ name: 'user'}})
Copy the code

2. Name the view

In SRC /router/index.js, select * from SRC /router/index.js where you can select * from SRC /router/index.js where you can select * from SRC /router/ index.php

import Vue from 'vue'
import Router from 'vue-router'
// Create the page component
const Header = { template: '<div>Header</div>' }
const Left = { template: '<div>Left</div>' }
const Right = { template: '<div>Right</div>' }
Vue.use(Router)
export default new Router({
    routes: [{path: '/'.// Home page routing
        components: {
            default: Header,
            a: Left,
            b: Right
        }
    }
    ]
})
Copy the code

(2) in SRC/app.vue, the code is as follows:

<template>
    <div id="app">
        <router-view />
        <router-view name="a" class="left" />
        <router-view name="b" class="right" />
    </div>
</template>
<script>
export default {
    name: 'App'
}
</script>
<style>
#app {
    text-align: center;
    color: #2c3e50;
    width: 500px;
    border: 1px solid red;
    margin: 0 auto;
}
.left..right{
    float: left;
    width:48%;
    text-align: center;
    border:1px solid red
}
</style>
Copy the code

PS: As a matter of practice, named views can only be placed on the top page, that is, the code in the first step can not be placed on other pages.

3. Redirection

(1) SRC /router/index.js (2) SRC /router/index.js (3)

export default new Router({
    routes: [{path: '/'.// The default page redirects to the home page
        redirect: '/home' / / redirection
    },
    {
        path: '/home'.// Home page routing
        component: Home,
        children: [// Nested subroutes
            {
                path:'/home/two/:id/:name'.// Subpage 2
                component:Two
            },
            {
                path:'/home/three/:id/:name'.// Subpage 3
                name: 'three'.// Route name - Names the route
                redirect: '/home/two/:id/:name' // Redirection - pass parameters},]}]})Copy the code

SRC /components/ home.vue

<router-link to="/"> home page < / router - the link > |<router-link to="/home/two/1/lisi">Child page 2</router-link>  |
<router-link :to="{name: 'three', params: {id: 1, name: 'zhangsan'}}">Child pages 3</router-link>
Copy the code

Note 1- Redirection without parameters:

redirect: '/home' // Redirection - with no parameters
Copy the code

Note 2- Redirection with parameters:

redirect: '/home/two/:id/:name' // Redirection - pass parameters
Copy the code

4, alias,

In SRC /router/index.js, the code is as follows: (1) In SRC /router/index.js, the code is as follows:

{
    path:'/one'.// Subpage 1
    component:One,
    alias: '/oneother'
}
Copy the code

SRC /components/ home.vue

<router-link to="/oneother">Child pages 1</router-link>
Copy the code

Note 1: Differences between redirect and alias

  • Redirect: Changes the url value directly, turning the URL into a real path. \
  • Alias: The URL path is not changed. This is more friendly. It lets the user know the path to access, but only changes the content in the URL.

** Note 2: ** aliases should not be used when path is’/’. The following aliases do not work.

{
    path: '/',
    component: Hello,
    alias:'/home'
}
Copy the code

Transition animations

1. Code examples

(1) Add a tag outside the tag. The tag also needs a name attribute. The code is as follows:

<transition name="fade" mode="out-in">
    <router-view />
</transition>
Copy the code

(2) Add CSS, a total of 4 CSS class names, 4 class names related to the transition name property, such as name= “fade”, the corresponding CSS:

/* Page switch animation */
/* Enter the end state of the transition, which takes effect when the element is inserted, and remove */ when the transition is complete
.fade-enter-active {
    transition: opacity .5s;
}
/* Enter the start state of the transition, which takes effect as soon as the element is inserted and is deleted immediately after only one frame is applied
.fade-enter {
    opacity: 0;
}
/* Leaves the start state of the transition, triggered when an element is deleted, after only one frame is applied */
.fade-leave {
    opacity: 1;
}
/* The end state of the exit transition, which takes effect when the element is deleted, is deleted when the exit transition is complete */
.fade-leave-active {
    opacity:0;
    transition: opacity .5s;
}
Copy the code

2, transition mode

  • In-out: the new element enters the transition first, and the current element exits after the transition is complete, default mode.
  • Out-in: The current element transitions out, and the new element transitions in when the departure is complete.

Mode with 404

1. Mode Mode

Example code:

export default new Router({
    mode: 'history'./ / mode model
    routes: [...]. })Copy the code

Mode values shows that: (1) the histroy: URL like normal URL, example: http://localhost:8080/home (2) the hash: default values, will be more than a “#”, example: http://localhost:8080/#/home

2. 404 Page Settings

If the route to be accessed does not exist or the user enters an incorrect route, a 404-friendly message is displayed. Configure the following parameters:

/ / 404
{
    path: The '*'.component: () = > import('@/components/404')}Copy the code

(2) In SRC /components/404.vue:

<template>
    <div class="hello">
        <h1>404 not found</h1>
    </div>
</template>
<script>
export default {
    data () {
        return{}}}</script>
<style scoped>
</style>
Copy the code

Routing hooks

Routing hooks, or navigation hooks, are actually route interceptors. There are three types of vue-router:

  1. Global hooks: most commonly used
  2. Route individual hooks
  3. Assembly hooks

1. Global hooks

SRC /router/index.js// Define route configuration
const router = new VueRouter({ ... })
// Global route interception - performed before page entry
router.beforeEach((to, from, next) = > {
    // You can add a global login judgment here
    // Continue to execute
    next();
});
// Global rear hook - used to end animation, etc
router.afterEach(() = > {
    // Do not accept next
});
export default router;
Copy the code

** Each hook method takes three arguments: **to: Route: Route object to enter from: Route: Route from which the current navigation is about to leave next: Function: continue to execute the Function

  • Next () : Continue execution
  • Next (false) : Interrupt the current navigation.
  • Next (‘/’) or next({path: ‘/’}) : Jump to a new page

Route individual hooks

Use: add a separate hook to the route configuration and use it in SRC /router/index.js as follows:

{
    path:'/home/one'.// Subpage 1
        component: One,
        // Route the internal hook
        beforeEnter: (to, from, next) = > {
        console.log('Execute before entering'); next(); }}Copy the code

3. Hooks within components

Define hook functions within the routing component using:

  • BeforeRouteEnter: called before the page is entered
  • BeforeRouteUpdate (added in 2.2) : Called when the page route changes, usually with parameters
  • BeforeRouteLeave: Off page call

On any page, write the following code:

<script>
export default {
    name: 'Two',
    data () {
        return {
            msg: 'Hi, I am Two Page! '}},// called before entering the page
    beforeRouteEnter(to, from, next) {
        console.log('Enter the Route hook')
        next()
    },
    // Off page call
    beforeRouteLeave(to,from, next){
        console.log('Enter the leave route hook')
        next()
    },
    // Called when the page route changes
    beforeRouteUpdate(to, from, next) {
        console.log('Enter the Update route hook')
        console.log(to.params.id)
        next()
    }
}
</script>
Copy the code

The route was loaded lazily. Procedure

1. Normal routing mode:

// 1, introduce the page component first
import Home from '@/components/Home'
// 2
    {
        path: '/home'.component: Home
}
Copy the code

2. Lazy loading mode

In large projects, in order to improve the efficiency of page initialization, routing generally uses lazy loading mode, a total of three implementations. (1) The first way to write:

component: (resolve) = > require(['@/components/One'], resolve)
Copy the code

(2) The second way to write:

component: () = > import('@/components/Two')
Copy the code

(3) The third way to write:

components: r= > require.ensure([], () = > r(require('@/components/Three')), 'group-home')
Copy the code

PS:

  • The second abbreviation is commonly used
  • In the third case, ‘group-home’ is to package components into blocks. Multiple components can be grouped into a group. When packaged, Webpack will package all asynchronous modules in the same chunk into one asynchronous block.

vuex

For details of the vuEX official document, see the following document

Background introduction

1. What is VUex?

Vuex is a state management pattern developed specifically for vue.js applications. It uses centralized storage to manage the state of all components of an application, and rules to ensure that the state changes in a predictable manner. Install DevTools Extension for Chrome

2. Unidirectional data flow

Schematic description:

  • State: Data source (unidirectional data flow) that drives the application
  • View: Map state to View declaratively (statically displayed data source)
  • Actions: Handles state changes caused by user Actions on a view (data source change tracking)

A simple demo case:

<template>
    <div>
        <! -- view -->
        <div>{{ count }}</div>
        <button @click="increment">increment</button>
    </div>
</template>
<script>
export default {
    // state
    data () {
        return {
            count: 0}},// actions
    methods: {
        increment () {
            this.count++
        }
    }
}
</script>
<style>
</style>
Copy the code

3. Problems solved by VUEX

  • State is shared between multiple view components, including parent and sibling components
  • The behavior of different view components needs to change the same state

4. Usage scenario of VUEX

Medium and large single-page applications need to consider how to better manage state outside components. Simple applications are not recommended

5. Difference between vuex and global variables

  • Responsive: The state store of VUex is responsive. When the Vue component reads the state from the store, if the state in the store changes, the corresponding component will be updated efficiently
  • Cannot change stores directly: Changes in stores cannot be changed directly; the only way to change the state in a Store is commit mutation, which is convenient for tracking every state change

6. Vuex core process

Schematic description:

  1. Vue Components: Indicates the Vue Components. HTML page, responsible for receiving user actions and other interactive behavior, execute the dispatch method to trigger the corresponding action for response
  2. Dispatch: The operation behavior triggering method. It is the only method that can execute an action
  3. Actions: Actions module. Is responsible for handling all interactions received by Vue Components. Contains synchronous/asynchronous operations, supports multiple methods of the same name, and fires in the order in which they are registered. The operations requested to the background API are performed in this module, including triggering other actions and submitting mutations. This module provides encapsulation of promises to support chained triggering of actions
  4. Commit: Indicates how to Commit a state change. Submitting the mutation is the only way to execute the mutation
  5. Mutations: State change method of operation. Is the only recommended way for Vuex to modify state. Any other way will cause an error in strict mode. This method can only be synchronized, and the method name must be globally unique. During the operation, some hooks will be exposed for state monitoring and so on
  6. State: Page State management container object. The scattered data of data objects in Vue Components is stored in a centralized manner, which is globally unique for unified state management. The data required for the page display is read from this object, utilizing Vue’s fine-grained data response mechanism for efficient status updates
  7. Getters: State object reading method. This module is not listed separately in the figure and should be included in render. Vue Components uses this method to read the global state object

** Summary: **Vue component receives interactive behavior, calls dispatch method to trigger action related processing, if the page state needs to change, calls Commit method to submit mutation to change state, obtains the new value of state through getters, and rerenders Vue Components. The interface is updated

An introduction to the sample

1, install,

npm install vuex --save
Copy the code

2. Simple example

SRC /vuex/store.js

/ / into the vue
import Vue from 'vue'
/ / introduce vuex
import Vuex from 'vuex'
/ / use vuex
Vue.use(Vuex)
// 1. State: Creates the initialization state
const state = {
    // Place the initial state
    count: 1
}
Mutations: A method to create a change in state
const mutations = {
    // State change function - generally uppercaseADD (state, n) { state.count += n; }}// 3, getters: provides external access to state
const getters = {
    count: function(state){
        returnstate.count; }}// 4, Actions: Create driver method changes mutations
const actions ={
    // Trigger the corresponding method in mutations - generally lower case
    add ({commit}, data) {
        commit('ADD', data)
    }
}
// 5, all injection Store
const store = new Vuex.Store({
    state,
    mutations,
    getters,
    actions
});
// 6, output store
export default store;
Copy the code

Code description:

  • State-mutations – getters – Actions – Store, the above method is basically fixed.
  • For small projects, simply manage state as above.

(2) in SRC /main.js code

import Vue from 'vue'
import App from './App'
import router from './router'
/ / into the store
import store from './vuex/store'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store, // Global injection
  components: { App },
  template: '<App/>'
})
Copy the code

(3) SRC /compontent/ count. vue

<template>
    <div class="hello">
        <h1>{{ msg }}</h1>
        <h2>{{count}}</h2>
        <button @click="clickAdd">new</button>
    </div>
</template>
<script>
export default {
    data () {
        return {
            msg: 'Vuex test! '}},computed: {
        // Obtain the state value
        count() {
            return this.$store.state.count; }},methods: {
        clickAdd() {
            // Distribute the Add method in the action
            this.$store.dispatch('add'.1); }}}</script>
<style scoped>
</style>
Copy the code

State – The method of obtaining the state object

1. Use it directly in the component’s template

<h2>{{ $store.state.count }}</h2>
Copy the code

2. Assign a value for computed

// Method 1: obtain directly
computed: {
    count() {
        // this refers to the vue instance object in main.js
        return this.$store.state.count; }}Copy the code

3. Assign values via mapState objects

// Method 2: use mapState
computed: mapState({
    / / es5 writing
    count: function (state) {
         return state.count;
     },
    / / es6 writing
    count: state= > state.count
})
Copy the code

4. Assign values via an array of mapStates

// Method 3: array obtain
computed: mapState(['count'])
Copy the code

5, using mapState JSON to assign values

// Method 4: obtaining JSON
computed: mapState({
    count: 'count'
})
Copy the code

PS: General 4 and 5 two more commonly used complete sample code

<template>
    <div class="hello">
        <h1>{{ msg }}</h1>
        <h2>{{ $store.state.count }}</h2>
        <h2>{{count}}</h2>
        <button @click="clickAdd">new</button>
    </div>
</template>
<script>
import {mapState} from 'vuex'
export default {
    data () {
        return {
            msg: 'Vuex test! '}},// Mode 1: assigns a value on the computed field
    // computed: {
    // count() {
    // // this refers to the Vue instance object in main.js
    // return this.$store.state.count;
    / /}
    // },
    // Method 2: assign values via the mapState object
    // computed: mapState({
    // // es5
    // // count: function (state) {
    // // return state.count;
    / / / /},
    // // es6
    // count: state => state.count
    // }),
    // Method 3: assign values via the mapState object
    // computed: mapState(['count']),
    // Method 4: use the JSON of mapState to assign a value
    computed: mapState({
        count: 'count'
    }),
    methods: {
        clickAdd() {
            // Distribute the Add method in the action
            this.$store.dispatch('add'.1); }}}</script>
<style scoped>
</style>
Copy the code

Mutations – getters – actions asynchronous

1. Mutations (modified state)

(1) $store.com MIT () is triggered directly in the template

// template
<button @click="$store.commit('ADD')">+</button>
// src/vuex/store.js
const mutations = {
    // State change functionADD (state) { state.count++; }}Copy the code

(2) The trigger is introduced by mapMutations

<template> <div class="hello"> <h1>{{ msg }}</h1> <h2>{{count}}</h2> <! 图 文, 图 文, 图 文, 图 文, 图 文 --> < button@click ="ADD">+</button> </div> </template> <script> mapMutations} from 'vuex' export default { data () { return { msg: 'Vuex test! Computed: mapState({count: 'count'}), mapState({count: 'count'}), mapState({count: 'count'}), mapState({count: 'count'}), mapState({count: 'count'}); mapMutations([ 'ADD' ]) } </script> <style scoped> </style>Copy the code

Getters (get state and filter)

(1) Basic usage

// src/vuex/store.js
const getters = {
    count: function(state){
        // Return plus 100
        return state.count + 100; }}Copy the code

(2) Get the value in general

computed: {
    / / for getters
    count(){
        return this.$store.getters.count; }} (3) mapGetters gets the value// 1. Introduce mapMutations
import {mapState, mapMutations, mapGetters} from 'vuex'
// 2
computed: {
    / / for getters. mapGetters(["count"])}Copy the code

3. Actions (asynchronous state modification)

Actions and mutations essentially have the same function, except that actions asynchronously change the state state, while mutations synchronously change the state. But in actual projects, they usually change the value of mutations through actions. (1) Add asynchronous code to store.js

// src/vuex/store.js
const actions ={
    // Triggers the corresponding method in mutations
    add ({commit}) {
        // Add asynchrony
        setTimeout(() = >{
            commit('ADD')},3000);
        console.log('I execute ahead of Reduce'); }}Copy the code

(2) Routine use

// template
<button @click="add">+</button>
// script
methods: {
    add() {
        / / distribution of the action
        this.$store.dispatch('add'); }}Copy the code

(3) Use of mapActions

// template
<button @click="add">+</button>
// script
/ / introduce mapActions
import {mapState, mapActions} from 'vuex'
/ / use mapActions
methods: {
    ...mapActions(['add'])}Copy the code

Passing parameters

In the method call of VUex, the parameters are passed, just add the parameters corresponding to mutations and actions, and pass them in when the call is made. (1) in SRC /vuex/store.js

// Pass parameters in actions
constmutations = { ADD (state, n) { state.count += n; }}// Pass parameters in actions
const actions ={
    // Triggers the corresponding method in mutations
    add ({commit}, n) {
        // Add asynchrony
        setTimeout(() = >{
            commit('ADD', n);
        },3000);
        console.log('I execute ahead of Reduce'); }}Copy the code

(2) Regular call passing of page components

// template
<button @click="add">+</button>
// script
methods: {
    add() {
        / / distribution of the action
        this.$store.dispatch('add'.99); }}Copy the code

(3) Page components are passed by mapActions calls

// template
<button @click="add(99)">+</button>
// scriptmethods: { ... mapActions(['add'])}Copy the code

The module – module group

When the application is very complex and has a lot of state, you need to split the store into modules. Each module has its own state, mutation, action, getter, and even nested submodules, split the same way from top to bottom.

1. General structure

/ / module A
const moduleA = {
  state: {... },mutations: {... },actions: {... },getters: {... }}B / / modules
const moduleB = {
  state: {... },mutations: {... },actions: {... }}/ / assembly
const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})
/ / value
store.state.a // -> moduleA status
store.state.b // -> moduleB status
Copy the code

2. Detailed examples

In practice, it is recommended to write modules separately. (1) the SRC/vuex/module1. Js

/ / module 1
const module1 = {
    // Initialize the state
    state: {
        module1: {
            name: 'module 1'}},// Write actions
    mutations: { CHANGE1 (state, data) { state.module1 = data; }},/ / value
    getters: {
        module1: function(state){
            returnstate.module1; }},// Create the driver asynchronously
    actions: {
        change1 ({commit}, data) {
            commit('CHANGE1', data)
        }
    }
}
export default module1;
Copy the code

(2) the SRC/vuex/module2. Js

/ / module 1
const module2 = {
    // Initialize the state
    state: {
        module2: {
            name: '2'}},// Write actions
    mutations: { CHANGE2 (state, data) { state.module2 = data; }},/ / value
    getters: {
        module2: function(state){
            returnstate.module2; }},// Create the driver asynchronously
    actions: {
        change2 ({commit}, data) {
            commit('CHANGE2', data)
        }
    }
}
export default module2;
Copy the code

(3) the SRC/vuex/store. Js

/ / into the vue
import Vue from 'vue'
/ / introduce vuex
import Vuex from 'vuex'
/ / into the module1
import module1 from '@/vuex/module1'
/ / the introduction of module2
import module2 from '@/vuex/module2'
/ / use vuex
Vue.use(Vuex)
// Module injection
const store = new Vuex.Store({
    modules: {
        a: module1,
        b: module2
    }
})
/ / output store
export default store;
Copy the code

(4) components used, SRC /compontent/one.vue

<template> <div id="app"> <! - module1 - > < h2 > {{module1. Name}} < / h2 > < button @ click = "change1 ({' name ':' change1})" > module1 change < / button > <! -- module2 --> <h2>{{ module2.name }}</h2> <button @click="change2({'name': "> </button> </div> </template> <script> MapActions} from 'vuex' export default {name: 'app', data () {return {}}, computed:{// mapState value //... MapState ({// module1: state => state.a.dule1.name, // module2: state => state.B.mudule2.name //}) MapGetters (['module1', 'module2'])}, methods: {// mapAction... mapActions([ 'change1', 'change2' ]) } } </script> <style> </style>Copy the code

PS: The name in the module must be unique, otherwise it will conflict when getting the value and changing the value. Currently, mapGetters can only get the object.

axios



Chinese Translation Manual

1, the introduction of

Axios is a Promise-based HTTP library that can be used in browsers and node.js. In short, it is one of the most popular and simple HTTP request solutions on the front end.

2, installation,

npm install vuex –save

3, functionality,

  • Create XMLHttpRequests from the browser
  • Create an HTTP request from Node.js
  • Supporting Promise API
  • Intercept requests and responses
  • Transform request data and response data
  • Cancel the request
  • Automatically convert JSON data
  • The client supports XSRF defense

4. Code encapsulation

The following is a package of the configuration file, more detailed directly to the official document query. (1) Tool class encapsulation

/ / introduce axios
import axios from 'axios';
// Create the Axios instance
const httpService = axios.create({
    // Url prefix -'https://some-domain.com/api/'
    baseURL: process.env.BASE_API, // Custom
    // Request timeout
    timeout: 3000 // Custom
});
// Request interceptor
httpService.interceptors.request.use(
    config= > {
        // Add token-secure carry according to the condition
        if (true) { // Custom
            // Let each request carry the token
            config.headers['User-Token'] = ' ';
        }
        return config;
    }, 
    error= > {
        // Request error handling
        Promise.reject(error); })// The respone interceptor
httpService.interceptors.response.use(
    response= > {
        // Handle states uniformly
        const res = response.data;
        if(res.statuscode ! =1) { // Custom
            // Return an exception
            return Promise.reject({
                status: res.statuscode,
                message: res.message
            });
        } else {
            returnresponse.data; }},// Processing processing
    error= > {
         if (error && error.response) {
            switch (error.response.status) {
                case 400:
                    error.message = 'Error request';
                    break;
                case 401:
                    error.message = 'Unauthorized, please log in again';
                    break;
                case 403:
                    error.message = 'Access denied';
                    break;
                case 404:
                    error.message = 'Request error, resource not found';
                    break;
                case 405:
                    error.message = 'Requested method not allowed';
                    break;
                case 408:
                    error.message = 'Request timeout';
                    break;
                case 500:
                    error.message = 'Server side error';
                    break;
                case 501:
                    error.message = 'Network not implemented';
                    break;
                case 502:
                    error.message = 'Network error';
                    break;
                case 503:
                    error.message = 'Service unavailable';
                    break;
                case 504:
                    error.message = 'Network timeout';
                    break;
                case 505:
                    error.message = 'HTTP version does not support this request';
                    break;
                default:
                    error.message = 'Unknown error'${error.response.status}`; }}else {
            error.message = "Failed to connect to server";
        }
        return Promise.reject(error); })/* Network request part */
/* * get Request * URL: request address * params: parameter * */
export function get(url, params = {}) {
    return new Promise((resolve, reject) = > {
        httpService({
            url: url,
            method: 'get'.params: params
        }).then(response= > {
            resolve(response);
        }).catch(error= > {
            reject(error);
        });
    });
}
/* * post request * URL: request address * params: parameters * */
export function post(url, params = {}) {
    return new Promise((resolve, reject) = > {
        httpService({
            url: url,
            method: 'post'.data: params
        }).then(response= > {
            resolve(response);
        }).catch(error= > {
            reject(error);
        });
    });
}
/* * File upload * URL: request address * params: parameters * */
export function fileUpload(url, params = {}) {
    return new Promise((resolve, reject) = > {
        httpService({
            url: url,
            method: 'post'.data: params,
            headers: { 'Content-Type': 'multipart/form-data' }
        }).then(response= > {
            resolve(response);
        }).catch(error= > {
            reject(error);
        });
    });
}
export default {
    get,
    post,
    fileUpload
}
Copy the code

(2) Use

// Import utility class - directory custom
import fetch from '@/util/fetch'
/ / use
const TMPURL = ' '; / / url
const params = {}; / / parameters
fetch.post(TMPURL + '/login/login', params);
Copy the code