Getting Started with Vuex

1. What is Vuex?

Official website explanation: Vuex is a state management model developed for Vue.js applications. It uses a centralized store to manage the state of all components of the application, and uses corresponding rules to ensure that the state changes in a predictable manner.

Just getting in touch with Vuex, it may not be helpful to see such an official explanation! After understanding its usefulness and operating a simple demo, I probably have a preliminary understanding of it. I think Vuex acts as a "bridge", which facilitates sharing a resource between multiple similar components and passing values, which is more efficient for large-scale projects! The above are my personal opinions, I hope to give pointers and exchanges!

2. Installation of Vuex

Vuex also has a variety of installation methods, and npm is still used here for installation.

npm install vuex --save

If the image below appears, the installation is complete.

At this point, you can see that vuex has been installed in the package.json file, as shown in the figure:

3. Vuex project

It is still necessary to build a project through the vue-cli scaffolding. Here is an introduction to the installation and use of cnpm.

Install Taobao mirror:

npm install -g cnpm --registry=https://registry.npm.taobao.org

Test if the installation is successful:

cnpm -v

If the corresponding version number appears, indicating that the installation is successful, you can use cnpm.

Install vue-cli globally:

cnpm install -g vue-cli

Test if the installation is successful:

vue -V

Initialize the project:

vue init webpack-simple vuex-demo

Open the project:

//进入文件夹下
cd vuex-demo
//安装依赖
cnpm install 
//运行服务
cnpm run dev

Passing values ​​between parent and child components, as mentioned earlier, use props or $emit.

Implementation effect: the content of the two modules is the same

Analysis: If there is a common resource in the parent component, the child component needs to be bound with a tag, and then pass the value through props to use it. Then all the same things are copied twice, what if there are multiple? This is not very reasonable, so let's learn the use of Vuex.

The above has entered the project. Next, install Vuex, create a new folder store under src and create a new file store.js. Then introduce the new store.js in main.js and use it in the instantiated object.

//这是store.js文件
//引入Vue和Vuex
import Vue from 'vue'
import Vuex from 'vuex'

在Vue中使用Vuex
Vue.use(Vuex)

//定义store并允许外部使用,把公共资源products提取出来,放在state下
export const store = new Vuex.Store({
	state:{
		products:[
	        {name:"A",price:200},
	        {name:"B",price:140},
	        {name:"C",price:20},
	        {name:"D",price:10},
        ]
	}
})
//这是main.js文件
//main.js引入store.js
import {store} from './store/store'

new Vue({
  store:store,
  el: '#app',
  render: h => h(App)
})

Then delete the public data products and the binding information of the component label in App.vue.

//这是App.vue
<template>
  <div id="app">
    <!--不使用Vuex前-->
    <!-- <product-list-one v-bind:products="products"></product-list-one>
    <product-list-two v-bind:products="products"></product-list-two> -->
    <product-list-one></product-list-one>
    <product-list-two></product-list-two>
  </div>
</template>

<script>
import ProductListOne from './components/ProductListOne.vue'
import ProductListTwo from './components/ProductListTwo.vue'
export default {
  name: 'app',
  components:{
    'product-list-one':ProductListOne,
    'product-list-two':ProductListTwo
  },
  data () {
    return {
      //共用资源
      // products:[
      //   {name:"A",price:200},
      //   {name:"B",price:140},
      //   {name:"C",price:20},
      //   {name:"D",price:10},
      // ]
    }
  }
}
</script>

<style>

</style>

Then, delete the original props and data in the two components respectively, and use computed.

<script>
export default {
  //这是未使用Vuex前
  // props:["products"],
  // data () {
  //   return {
      
  //   }
  // }

  //使用computed来得到products的值
  computed:{
    products(){
      return this.$store.state.products;
    }
  }
</script>

In this way, Vuex is simply used and state is used. Vuex has five cores: State, Getter, Mutation, Action, and Module. The following will continue to introduce.

State: used to store data

Getter: used to get data

For the basis of the above items, if the information price needs to be displayed at a 50% discount of the original data at this time, the method needs to be defined at this time:

//html中products换为对应的saleProducts
<li v-for="product in saleProducts">
    <span class="name">{{product.name}}</span>
    <span class="price">${{product.price}}</span>
</li>

//定义的打折方法
saleProducts(){
   //取到数据后进行修改
   var saleProducts = this.$store.state.products.map(product=>{
      return {
         //新的展示样式
         name:"**" + product.name +"**",
         price:product.price / 2
      }
   })
   //返回最后的数据
   return saleProducts;
}

In the same way, both components need to be written in this way, which is also a bit cumbersome. Then extract the method in store.js

getters:{
    //state就是上面state里面的product数据
	saleProducts:(state)=>{
	     var saleProducts = state.products.map(product=>{
	        return {
	          name:"**" + product.name +"**",
	          price:product.price / 2
	        }
	      })
	     return saleProducts;
    }
},

Then, just return the data directly in the component, isn't it easy!

//定义的打折方法
saleProducts(){
  //返回最后的数据,直接调用store.js中getters下的方法即可
   return this.$store.getters.saleProducts;
}

Mutation: used to trigger event changes

Add a button to the component and drop the price on click.

//html
<button @click="reducePrice">商品降价</button>


//script
methods:{
    reducePrice:function(){
       this.$store.state.products.forEach(product=>{
         product.price -= 1;
       })
    }
}

Of course, that's it. We use mutation to achieve this:

mutations:{
	reducePrice:(state)=>{
			state.products.forEach(product=>{
        		product.price -= 1;
      		})
		}
	}
}
reducePrice:function(){
   this.$store.commit('reducePrice');
}

Action: Submit Mutation, asynchronous operation

What if you want to lag 2s after clicking the button to achieve the effect? Action is required at this time.

actions:{
	reducePrice:(context,payload)=>{
		setTimeout(function(){
			context.commit('reducePrice',payload);
		},2000)
	}
}
reducePrice:function(amount){
   this.$store.dispatch("reducePrice",amount);
}

Module: Modular

Finally, let's talk about mapGetters and mapActions.

Install babel:

cnpm install babel-preset-stage-2 --save-dev

Its main function is multiple methods. After introduction, you can write it directly in ...mapGetters/...mapActions, and directly call the method in store.js.

<script>
//引入
import {mapGetters} from 'vuex'
import {mapActions} from 'vuex'

export default {
  computed:{
    products(){
      return this.$store.state.products;
    },
    ...mapGetters([
      "saleProducts"
    ])
   //多个方法,注释掉直接使用mapGetters
    // saleProducts(){
    //   // var saleProducts = this.$store.state.products.map(product=>{
    //   //   return {
    //   //     name:"**" + product.name +"**",
    //   //     price:product.price / 2
    //   //   }
    //   // })
    //   // return saleProducts;
    //   return this.$store.getters.saleProducts;
    // }
  },
  methods:{
    // reducePrice:function(amount){
    //   // this.$store.state.products.forEach(product=>{
    //   //   product.price -= 1;
    //   // })
    //   // this.$store.commit('reducePrice');
    //   this.$store.dispatch("reducePrice",amount);
    // }
    //同理
    ...mapActions([
      "reducePrice"
    ])
  }
}
</script>

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325130305&siteId=291194637