The target
-
Vuex overview
-
Vuex basic use
-
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