The target

  1. Vuex overview

  2. Vuex basic use

  3. Complete the TODO case with Vuex

1. Vuex overview

Vuex is a mechanism to implement global state (data) management of components and facilitate data sharing among components

Benefits of using Vuex to manage data:

A. Centralized management of shared data in VUEX facilitates development and maintenance

B. Can efficiently realize data sharing between components and improve development efficiency

C. The data stored in VUEX is responsive. When the data is changed, the data in the page will be updated synchronously

2. Basic use of Vuex

To create a VUE project with VUex, open the terminal and type the command: vue UI

When the project dashboard opens, we click on the project Management drop-down list in the upper left corner of the page, and then on Vue Project Manager

Click Create project, as shown below

First, set up the project name and package manager

Second, set up the manual configuration project

Step 3: Set the function items

Step 4: Create the project

3. Complete the counter case with Vuex

Open the vuex project you just created, find the app.vue component in the SRC directory, and rewrite the code as follows:

<template>
  <div>
    <my-addition></my-addition>

    <p>----------------------------------------</p>

    <my-subtraction></my-subtraction>
  </div>
</template>

<script>
import Addition from './components/Addition.vue'
import Subtraction from './components/Subtraction.vue'

export default {
  data() {
    return{}},components: {
    'my-subtraction': Subtraction,
    'my-addition': Addition
  }
}
</script>

<style>
</style>
Copy the code

Create the addition. vue component in the Components folder as follows:

<template>
    <div>
        <h3>The latest count value is:</h3>
        <button>+ 1</button>
    </div>
</template>

<script>
export default {
  data() {
    return{}}}</script>

<style>
</style>
Copy the code

Create the Subtraction. Vue component in the Components folder as follows:

<template>
    <div>
        <h3>The latest count value is:</h3>
        <button>- 1</button>
    </div>
</template>

<script>
export default {
  data() {
    return{}}}</script>

<style>
</style>
Copy the code

Finally, create the.prettierrc file in the project root (SRC level) and write the following code:

{
    "semi":false."singleQuote":true
}
Copy the code

4. Core features in Vuex

A.State

State provides the only common data source, and all shared data is stored in State in the Store

For example, open the store.js file in the project and add data to the State object that we want to share, such as: count:0

How to access State in a component:

1).this.$store.state

Such as this. $store. State. The count

2). Import mapState function as required:

import { mapState } from ‘vuex’

The data is then mapped to calculated attributes:

computed:{ … MapState ([‘ global data name ‘])}

B.Mutation

Mutation is used to modify data in the $store

Usage:

Open the store.js file and add the code for mutations as follows

mutations: {
    add(state,step){
      // The first parameter is always state, the $state object
      // The second parameter is passed when add is calledstate.count+=step; }}Copy the code

Then add the following event code to the button in addition. vue:

<button @click="Add">+1</button>

methods:{
  Add(){
    // Use the commit function to call the corresponding function in mutations,
    The first argument is the name of the function in mutations that we want to call
    // The second argument is the one passed to add
    this.$store.commit('add'.10)}}Copy the code

The second way to use mutations is:

import { mapMutations } from 'vuex'

methods: {... mapMutations(['add'])}Copy the code

As follows:

import { mapState,mapMutations } from 'vuex'

export default {
  data() {
    return{}},methods: {// Obtain the sub function of mapMutations mapping. mapMutations(['sub']),
      // Trigger the Sub function when the button is clicked
      Sub(){
          // Call sub to complete the operation on the data
          this.sub(10); }},computed: {... mapState(['count'])}}Copy the code

C.Action

Mutations cannot write asynchronous code, which will cause the vUE debugger to display errors. In VUEX we can use actions to perform asynchronous operations.

The operation steps are as follows:

Open the store.js file and modify the Action as follows:

actions: {
  addAsync(context,step){
    setTimeout(() = >{
      context.commit('add',step);
    },2000)}}Copy the code

Then add the following event code to the button in addition. vue:

<button @click="AddAsync">... +1</button>

methods:{
  AddAsync(){
    this.$store.dispatch('addAsync'.5)}}Copy the code

The second way:

import { mapActions } from 'vuex'

methods: {... mapMutations(['subAsync'])}Copy the code
import { mapState,mapMutations,mapActions } from 'vuex'

export default {
  data() {
    return{}},methods: {// Obtain the sub function of mapMutations mapping. mapMutations(['sub']),
      // Trigger the Sub function when the button is clicked
      Sub(){
          // Call sub to complete the operation on the data
          this.sub(10);
      },
      // Get the addAsync function of the mapActions map. mapActions(['subAsync']),
      asyncSub(){
          this.subAsync(5); }},computed: {... mapState(['count'])}}Copy the code

D.Getter

Getters are used to process data in a Store to form new data

It only wraps the data stored in the Store. It does not modify the data stored in the Store. When the data in the Store changes, the content generated by the Getter changes as well

Open the store.js file and add getters as follows:

export default new Vuex.Store({
  .......
  getters: {// Add a showNum attribute
    showNum : state= >{
      return 'The latest count value is:'+state.count; }}})Copy the code

Then open addition. vue and add interpolation expressions using getters

<h3>{{$store.getters.showNum}}</h3>
Copy the code

Alternatively, in Addition. Vue, you can import mapGetters and map them to computed properties

import { mapGetters } from ‘vuex’

computed:{ … mapGetters([‘showNum’]) }

5. Vuex case

A. Initialize the case

Start by initializing a case using Vuex using the VUE UI

Then open the public folder and create a list.json file with the following code:

[{"id": 0."info": "Racing car sprays burning fuel into crowd."."done": false
    },
    {
        "id": 1."info": "Japanese princess to wed commoner."."done": false
    },
    {
        "id": 2."info": "Australian walks 100km after outback crash."."done": false
    },
    {
        "id": 3."info": "Man charged over missing wedding girl."."done": false
    },
    {
        "id": 4."info": "Los Angeles battles huge wildfires."."done": false}]Copy the code

Next, open main.js and add the import of store.js as follows:

import Vue from 'vue'
import App from './App.vue'
import store from './store.js'

// 1. Import the ant-design-vue component library
import Antd from 'ant-design-vue'
// 2. Import the component library stylesheet
import 'ant-design-vue/dist/antd.css'

Vue.config.productionTip = false
// 3. Install the component library
Vue.use(Antd)

new Vue({
  store,
  render: h= > h(App)
}).$mount('#app')
Copy the code

Then open store.js and add code to axios to request json file for data as follows:

import Vue from 'vue' import Vuex from 'vuex' import axios from 'axios' Vue.use(Vuex) export default new Vuex.Store({ Status: {// All tasks list: [], // inputValue: 'AAA'}, mutations: { initList(state, list) { state.list = list }, setInputValue(state,value){ state.inputValue = value } }, actions: { getList(context) { axios.get('/list.json').then(({ data }) => { console.log(data); context.commit('initList', data) }) } } })Copy the code

Finally, replace the app. vue file to obtain and display the data in store:

<template>
  <div id="app">
    <a-input placeholder="Please enter the task" class="my_ipt" :value="inputValue" @change="handleInputChange" />
    <a-button type="primary">To add</a-button>

    <a-list bordered :dataSource="list" class="dt_list">
      <a-list-item slot="renderItem" slot-scope="item">
        <! -- Check box -->
        <a-checkbox :checked="item.done">{{item.info}}</a-checkbox>
        <! -- Delete link -->
        <a slot="actions">delete</a>
      </a-list-item>

      <! -- Footer area -->
      <div slot="footer" class="footer">
        <! -- Number of unfinished tasks -->
        <span>0 the remaining</span>
        <! -- Operation button -->
        <a-button-group>
          <a-button type="primary">all</a-button>
          <a-button>unfinished</a-button>
          <a-button>Has been completed</a-button>
        </a-button-group>
        <! -- Clear the list of completed tasks -->
        <a>Cleanup complete</a>
      </div>
    </a-list>
  </div>
</template>

<script>
import { mapState } from 'vuex'

export default {
  name: 'app'.data() {
    return {
      // list:[]}},created(){
    // console.log(this.$store);
    this.$store.dispatch('getList')},methods: {handleInputChange(e){
      // console.log(e.target.value)
      this.$store.commit('setInputValue',e.target.value)
    }
  },
  computed: {... mapState(['list'.'inputValue'])}}</script>

<style scoped>
#app {
  padding: 10px;
}

.my_ipt {
  width: 500px;
  margin-right: 10px;
}

.dt_list {
  width: 500px;
  margin-top: 10px;
}

.footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>
Copy the code

B. Complete the added items

First, open the app. vue file, bind the click event to the “Add Event” button, and write a handler

// Bind events
<a-button type="primary" @click="addItemToList"</a-button>// Write an event handler
methods:{
    ......
    addItemToList(){
      // Add items to the list
      if(this.inputValue.trim().length <= 0) {return this.$message.warning('Text box contents cannot be empty')}this.$store.commit('addItem')}}Copy the code

Then open store.js and write addItem

export default new Vuex.Store({
  state: {
    // All task lists
    list: [].// The value in the text input box
    inputValue: 'AAA'.// Next id
    nextId:5
  },
  mutations: {...// Add a list item
    addItem(state){
      const obj = {
        id :state.nextId,
        info: state.inputValue.trim(),
        done:false
      }
      // Add the created items to the array list
      state.list.push(obj)
      // Increment the nextId value
      state.nextId++
      state.inputValue = ' '}}... })Copy the code

C. Complete the deletion

First, open the app. vue file, bind the click event to the “Delete” button, and write a handler

// Bind events
<a slot="actions" @click="removeItemById(item.id)"> delete < / a >// Write an event handler
methods:{
    ......
    removeItemById(id){
      // Delete items by id
      this.$store.commit('removeItem',id)
    }
  }
Copy the code

Then open store.js and write addItem

export default new Vuex.Store({
  ......
  mutations: {...removeItem(state,id){
      // Delete item data by id
      const index = state.list.findIndex( x= > x.id === id )
      // console.log(index);
      if(index ! = -1) state.list.splice(index,1); }}... })Copy the code

D. The selected status is changed

First, open the app. vue file, bind the click event to the “check” button, and write a handler

// Bind events
<a-checkbox :checked="item.done" @change="cbStateChanged(item.id,$event)">{{item.info}}</a-checkbox>

// Write an event handler
methods:{
    ......
    cbStateChanged(id,e){
      // Triggered when the check box status changes
      const param = {
        id:id,
        status:e.target.checked
      }

      // Change the event status according to the ID
      this.$store.commit('changeStatus',param)
    }
  }
Copy the code

Then open store.js and write addItem

export default new Vuex.Store({
  ......
  mutations: {...changeStatus(state,param){
      // Change the state of the corresponding item according to the ID
      const index = state.list.findIndex( x= > x.id === param.id )
      if(index ! = -1) state.list[index].done = param.status
    }
  }
  ......
})
Copy the code

E. Statistics of remaining items

Open store.js and add getters to finish counting the remaining items

getters:{
  unDoneLength(state){
    const temp = state.list.filter( x= > x.done === false )
    console.log(temp)
    return temp.length
  }
}
Copy the code

Open app. vue and use getters to display the remaining items

// Display the remaining items using the calculated attributes mapped<! -- Number of unfinished tasks --><span>{{unDoneLength}} a surplus</span>

/ / import getters
import { mapState,mapGetters } from 'vuex'
/ / map
computed: {... mapState(['list'.'inputValue']),
  ...mapGetters(['unDoneLength'])}Copy the code

F. Clear completed items

First, open the app. vue file, bind the click event to the “Clean Done” button, and write a handler

<! -- Clear the list of completed tasks --><a @click="clean">Cleanup complete</a>

// Write an event handler
methods:{
  ......
  clean(){
    // Clear the completed items
    this.$store.commit('cleanDone')}}Copy the code

Then open store.js and write addItem

export default new Vuex.Store({
  ......
  mutations: {...cleanDone(state){
      state.list = state.list.filter( x= > x.done === false)}}... })Copy the code

G. Click the TAB to switch events

Open app. vue, bind click events to the “All”, “Incomplete”, and “Done” tabs, write a handler and change the list data source to a getters.

<a-list bordered :dataSource="infoList" class="dt_list">... <! -- Operation button --><a-button-group>
    <a-button :type="viewKey ==='all'? 'primary':'default'" @click="changeList('all')">all</a-button>
    <a-button :type="viewKey ==='undone'? 'primary':'default'" @click="changeList('undone')">unfinished</a-button>
    <a-button :type="viewKey ==='done'? 'primary':'default'" @click="changeList('done')">Has been completed</a-button>
  </a-button-group>. </a-list>// Write event handlers and map calculated properties
methods:{
  ......
  changeList( key ){
    // Click "All", "Done", "not done" to trigger
    this.$store.commit('changeKey',key)
  }
},
computed: {... mapState(['list'.'inputValue'.'viewKey']),
  ...mapGetters(['unDoneLength'.'infoList'])}Copy the code

Open store.js and add getters, mutations, state

export default new Vuex.Store({
  state: {...// Save the default TAB values
    viewKey:'all'
  },
  mutations: {...changeKey(state,key){
      // Triggered when the user clicks the "All", "Done", and "unfinished" tabs
      state.viewKey = key
    }
  },
  ......
  getters: {...infoList(state){
      if(state.viewKey === 'all') {return state.list
      }
      if(state.viewKey === 'undone') {return state.list.filter( x= > x.done === false)}if(state.viewKey === 'done') {return state.list.filter( x= > x.done === true)}}}})Copy the code