This is the 7th day of my participation in the August More Text Challenge

1. Core cover concept of VUEX

Vuex is a state management mode 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 way. It facilitates data sharing between components

1.1 the state

State provides a unique data resource. All shared data must be stored in state in store

  • The first way to access state in a component is:

This.$store.state. The global data name

  • The second way to access state in a component is:

Import {mapState} from ‘vuex’ Use the mapState function you just imported to map global data needed by the current component to computed attributes of the current component. 2. Map global data to the computed property of the current component, computed :{… mapState([‘count’]) }

1.2 mutation

(1) Only store data can be changed by mutation. (2) Although the operation is a little more complicated in this way, all data changes can be monitored centrally.

  1. this.$store.commit()Is the first way to trigger mutations,
// define mutations in store.js
const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
   add(state) {
   // Change the state
    state.count++
   }
  }
})
// The component receives violations mutations
methods: {
    add() {
      this.$store.commit('add')}},//mutations can transfer parameters
 mutations: {
   add2(state,step) {
    state.count += step
   }
  }
// trigger mutation with a parameter
methods: {
    add() {
      this.$store.commit('add'.3)}},Copy the code
  1. The second way to trigger mutations is through functional mapping

Import {mapMutations} from ‘vuex’ imports the mapState function that maps the global data needed by the current component to computed attributes of the current component. 2. Map the specified mutations function to the methods function of the current component (methods:{… mapMutations([‘add’]) }

1.3 the action

If the data is changed by an asynchronous operation, the Action must be used instead of Mutation, but the data must be changed indirectly by triggering Mutation in the Action.

  1. this.$store.dispatchIs the first way to trigger actions
// Define actions in store.js
  actions: {
    addAsync(context) {
      setTimeout(() = > {
        context.commit('add')},1000)}}// Trigger an action with dispatch in the event method
add () {
    / / triggers the action
    this.$store.dispatch('addAsync')}Copy the code

Triggers an asynchronous task to carry parameters

  mutations: {
   add(state,step) {
    state.count += step
   }
  },
  actions: {
    addAsync(context,step) {
      setTimeout(() = > {
        context.commit('add',step)
      },1000)}}/ / triggers the action
add () {
    this.$store.dispatch('addAsync'.5)}Copy the code
  1. The second way to trigger actions is through function mapping

Import {maptActions} from ‘vuex’ Use the mapState function you just imported to map global data needed by the current component to computed attributes of the current component. 2. Map the specified mutations function to the methods function of the current component (methods:{… maptActions([‘addAsync’]) }

1.4 the getter

Getters form new data by processing data in a Store. It does not modify the original data in state. It is used to wrap data. Getters can process existing data in Store to form new data, similar to Vue’s calculated properties. ② When the data in the Store changes, the data in the Getter also changes.

  1. This $store. Getters. NameYes, the first way to call getters
// called in the component
 {{$store.getters.showNum}}
 / / store. Defined in js
   getters: {
    showNum (state){
      return 'The most current data${state.count}`}}Copy the code
  1. By mapping it as a function

Import mapState function import {maptGetters} from ‘vuex’ To map global data needed by the current component to computed attributes of the current component using the mapState function just imported. 2. Map the specified mutations function to the methods function computed :{… maptGetters([‘showNum’]) }

2. Realize todoList function with Vue

The development of preparation

  • Antd – vue component library
  • vuex

Demand analysis

  • Add event functionality
  • Flag event function
  • Delete event function

Code share

Component code vuextodolist.vue

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

    <a-list bordered :dataSource="infolist" class="dt_list">
      <a-list-item slot="renderItem" slot-scope="item">
        <! -- Check box -->
        <a-checkbox :checked="item.done" @change="(e) => {cbStatusChanged(e, item.id)}">{{item.info}}</a-checkbox>
        <! -- Delete link -->
        <a slot="actions" @click="removeItemById(item.id)">delete</a>
      </a-list-item>

      <! -- Footer area -->
      <div slot="footer" class="footer">
        <! -- Number of unfinished tasks -->
        <span>{{unDoneLength}} a surplus</span>
        <! -- 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>
        <! -- Clear the list of completed tasks -->
        <a @click="clean">Cleanup complete</a>
      </div>
    </a-list>
  </div>
</template>

<script>
import { mapState, mapGetters } from 'vuex'

export default {
  name: 'app'.data() {
    return{}},created() {
    this.$store.dispatch('getList')},computed: {
    ...mapState(['inputValue'.'viewKey']),
    ...mapGetters(['unDoneLength'.'infolist'])},methods: {
    // Listen for text box content changes
    handleInputChange(e) {
      this.$store.commit('setInputValue', e.target.value)
    },
    // Add an item to the list
    addItemToList() {
      if (this.inputValue.trim().length <= 0) {
        return this.$message.warning('Text box contents cannot be empty! ')}this.$store.commit('addItem')},// Delete the corresponding task according to the Id
    removeItemById(id) {
      // console.log(id)
      this.$store.commit('removeItem', id)
    },
    // Listen for events whose status changes
    cbStatusChanged(e, id) {
      // e.target.checked accepts the latest checked status
      // console.log(e.target.checked)
      // console.log(id)
      const param = {
        id: id,
        status: e.target.checked
      }

      this.$store.commit('changeStatus', param)
    },
    // Clear completed tasks
    clean() {
      this.$store.commit('cleanDone')},// Modify the list data displayed on the page
    changeList(key) {
      // console.log(key)
      this.$store.commit('changeViewKey', key)
    }
  }
}
</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

The state management code store.js

import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    // All task lists
    list: [].// The contents of the text box
    inputValue: 'aaa'.// Next Id
    nextId: 5.viewKey: 'all'
  },
  mutations: {
    initList(state, list) {
      state.list = list
    },
    // Assign a value to inputValue in store
    setInputValue(state, val) {
      state.inputValue = val
    },
    // Add a list item
    addItem(state) {
      const obj = {
        id: state.nextId,
        info: state.inputValue.trim(),
        done: false
      }
      state.list.push(obj)
      state.nextId++
      state.inputValue = ' '
    },
    // Delete tasks based on their Id
    removeItem(state, id) {
      // Find the index of the corresponding item by Id
      const i = state.list.findIndex(x= > x.id === id)
      // Delete the corresponding element according to the index
      if(i ! = = -1) {
        state.list.splice(i, 1)}},// Change the selected status of the list item
    changeStatus(state, param) {
      const i = state.list.findIndex(x= > x.id === param.id)
      if(i ! = = -1) {
        state.list[i].done = param.status
      }
    },
    // Clear completed tasks
    cleanDone(state) {
      state.list = state.list.filter(x= > x.done === false)},// Modify the view's keyword
    changeViewKey(state, key) {
      state.viewKey = key
    }
  },
  actions: {
    getList(context) {
      axios.get('/list.json').then(({ data }) = > {
        // console.log(data)
        context.commit('initList', data)
      })
    }
  },
  getters: {
    // Count the number of unfinished tasks
    unDoneLength(state) {
      return state.list.filter(x= > x.done === false).length
    },
    infolist(state) {
      if (state.viewKey === 'all') {
        return state.list
      }
      if (state.viewKey === 'undone') {
        return state.list.filter(x= >! x.done) }if (state.viewKey === 'done') {
        return state.list.filter(x= > x.done)
      }
      return state.list
    }
  }
})


Copy the code