“This is the 22nd day of my participation in the Gwen Challenge.

Today’s adorable pet picture, I wish all the hard work of kind-hearted lovely angels happy every day ~💕







Writing in the front:

From the official website:

  • 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
  • If your application is simple, you might not want to use Vuex
  • If you need to build a medium to large single-page application, and you’re probably thinking about how best to manage state outside of components, Vuex would be the natural choice

Therefore, vuex is not suitable for all situations. It is most important to use it on demand 😜~ Start the text ~

Install vuex

Create a store file and extract the data

When vuEX is not used, data is maintained separately

With VUex, data is stored in a Store

Getters gets the data

Mutations modify data

Actions Set asynchrony

The recommended Chrome extension is Vue. Js devTools

Install vuex

This time I want to try CNPM, specify the domestic mirror:

npm config set registry https://registry.npm.taobao.org
Copy the code

Verification is successful:

npm config get registry
Copy the code

If the link to the image you just set is printed, the setting is successful

Install CNPM:

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

Verify whether the CNPM is successfully installed:

cnpm -v
Copy the code

If the output of each library version is not an error message, it indicates that the CNPM installation is successful

Install Vue CLI scaffolding:

CNPM -g@vue /cli-init or CNPM I -g@vue /cli-initCopy the code

Select the template Webpack-Simple to create the project:

Vue init webpack- Simple vuex-testCopy the code

Entry project:

cdVuex-test (Project Name)Copy the code

Installation project dependencies:

cnpm install
Copy the code

Operating Projects:

cnpm run dev
Copy the code

It then automatically opens in the default browserlocalhost:8080Helloworld vUE is the default configuration of the system. It looks like this:



Display this page, the project has been created successfully ~

Pause the current VUE service (close the terminal window or CTRL + C) and install vuex:

npm install vuex --save
Copy the code

The package.json file in the project folder will have a vuex dependency:

  "dependencies": {
    "vue": "^ 2.5.11"."vuex": "^ 3.6.2." "
  },
Copy the code

Vuex is successfully installed. Run the CNPM run dev command to start the project again

There was a bug when I was installing today. I couldn’t find the VUe-cli file. The NPM file in the node_modules directory was missing. The key is to need that NPM folder, you can find a friend’s NPM file copy over

Create a store file and extract the data

Background:

Sometimes we might use the same set of data in different components; For example, the price of an item is the same whether it’s a preview or a detail page. If these components maintain this set of data separately, to ensure consistency of data, if one child needs to change the data, all other children need to do the same. When there are a large number of components involved, it becomes cumbersome and error-prone, with too much redundancy. At this point, we can manage this data through VUEX

When vuEX is not used, data is maintained separately

When vuex is not used, components maintain their own data, like this:

  data () {
    return {
      products:[
            {name:"Shaanxi Big Apple".price:120},
            {name:"Pineapple".price:12},
            {name:"Big watermelon".price:60},
            {name:Passion fruit.price:20}}}]Copy the code

Product-list-one/product-list-two/product-list-two/product-list-two

<template>
  <div id="app">
    <product-list-one v-bind:products="products"></product-list-one>
    <product-list-two v-bind:products="products"></product-list-two>
  </div>
</template>
Copy the code

The sub-page is displayed after receiving the props:

    <ul>
      <li v-for="product in products" v-bind:key="product.id">
            <span class="name">{{product.name}}</span>
            <span class="price">${{product. Price}}</span>
        </li>
    </ul>
Copy the code

The effect:



Yes, each of our children gets the data from the parent. If we want to modify the data, we need to add a modification function saleProducts to each component. In this case, we have two components that need to be modified, so we need to add this function twice:

saleProducts(){
  var saleProducts = this.products.map((product) = >{
    return {
      name: product.name+"-onsale".price:product.price/2}})return saleProducts
}
Copy the code

The effect: this function, only to reduce the price of goods by half



The parent component modifs the data directly and then passes it to the child component. Hi, I think so too. Vuex refined this idea into a mechanism for storing and managing data in a store. When components need the data, they go to the Store and get it. When the data needs to be modified uniformly, the data in the Store can also be manipulated by submitting events. Take the sub-components and leave the rest to Vuex

You just move on and I’ll do the rest. You just go ahead. I’ll do the rest.

The revision idea of the case is as follows:

  1. Move (cut) the data in the main component app. vue, remove the code for the main component V-bind to dynamically transfer data and the sub-component props to receive data
  2. Create a new directory for store code, including data storage, data retrieval, and so on
  3. Import the store file in the main.js file and register it with the Vue instance object, named Store
  4. Use store on child pages if you only need to get source dataThis $store. State. Data

    If the name is x when registered in the VUE object, writeThis $x.s Tate. Data
  5. If you need to do some filtering and counting operations on the source data, you can do it in getters, such as the commodity price reduction mentioned above, because this is only a temporary price reduction, and the source data is not modified, but a copy is made for modification

With VUex, data is stored in a Store

Create a new folder in the SRC directory and name it Store. It’s going to be a new key file, I’m going to call it store.js, and I’m going to store the data here

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

Vue.use(Vuex)

export const store = new Vuex.Store({
    state: {products:[
            {name:"Shaanxi Big Apple".price:120},
            {name:"Pineapple".price:12},
            {name:"Big watermelon".price:60},
            {name:Passion fruit.price:20}}}})Copy the code

Import in main.js and register in vue instance:

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

new Vue({
  // Register store in the vue instance and name it store
  store:store,
  el: '#app'.render: h= > h(App)
})
Copy the code

Use in child components:

computed:{
    products(){
        return this.$store.state.products; }}Copy the code
<ul>
  <li v-for="product in products" v-bind:key="product.id">
        <span class="name">{{product.name}}</span>
        <span class="price">${{product. Price}}</span>
    </li>
</ul>
Copy the code

So you can use data products normally:

Take it one step at a time.

Getters gets the data

Once the source data is available, we can add a new getters field to the Store, where we define the price reduction function:

getters:{
	// The price in products is halved
	saleProducts:(state) = >{
		// Map manipulates each element one by one and returns a new object, without changing the source data
	    var saleProducts = state.products.map((product) = >{
	        return {
	            name: "* *"+product.name+"* *".price: product.price/2}})return saleProducts
}
Copy the code

Subcomponents use price reduction functions:

computed:{
    saleProducts(){
      return this.$store.getters.saleProducts
    }
}
Copy the code
<ul>
  <li v-for="product in saleProducts" v-bind:key="product.id">
        <span class="name">{{product.name}}</span>
        <span class="price">${{product. Price}}</span>
    </li>
</ul>
Copy the code

The effect:



Fine, also this and $sign, looks advanced and concise (brag 🤥)

If we were to actually modify the data, how would we do that?

Mutations modify data

The only way to change the state in Vuex’s store is to commit mutation. Mutations in Vuex are very similar to events: each mutation has a string event type (type) and a callback function (handler). This callback is where we actually make the state change, and it accepts state as the first argument

We can’t change the data at will, we need to use events to submit the request, similar to the idea of using events to pass values from children to their parents in VUE

Specific operations are as follows:

  1. Add the Mutations field in the Store object to define the “price change function.”
  2. Set up the listener in the child component
  3. When an event occurs, the handler is triggered, and commit commits the request to modify the data (state)

Define the treatment function reducePrice in the Mutations field of the store:

mutations:{
    reducePrice:(state) = >{
        state.products.forEach((product) = >{
            product.price -= 1; }}})Copy the code

Commit commits the event request in the subcomponent:

  methods:{
    reducePrice(number){
      this.$store.commit('reducePrice')}}Copy the code

Add a button to the child component and bind the click event to reduce the price of the item by 1 each time the button is clicked

<button @click="reducePrice()">The price</button>
Copy the code

As the data will be displayed through the saleProducts function set above — the value will be displayed after the value is reduced by half, we click the button once, only 0.5 will be reduced when the data is displayed. The source data is actually reduced by 1, which is shown here for a comparison:

<template>
  <div id="product-list-one">
    <h2>ProductListOne</h2>
    <h3>After the price is halved:</h3>
    <ul>
      <li v-for="product in saleProducts" v-bind:key="product.id">
            <span class="name">{{product.name}}</span>
            <span class="price">${{product. Price}}</span>
        </li>
    </ul>
    
    <h3>The source data is here:</h3>
    <ul>
      <li v-for="product in products" v-bind:key="product.id">
            <span class="name">{{product.name}}</span>
            <span class="price">${{product. Price}}</span>
        </li>
    </ul>
    <button @click="reducePrice()">The price</button>
  </div>
</template>
Copy the code

Effect:



We can also pass in a parameter to the reduceProducts function, such as reducing the price by $4 per click, which has a proper name in the Store: Playload

4:

<button @click="reducePrice(4)">The price</button>
Copy the code

Mutations receives and processes:

mutations:{
    reducePrice:(state,playload) = >{
        state.products.forEach((product) = >{ product.price -= playload; }}})Copy the code

Effect:

Mutations can only define synchronous functions, and does not allow asynchronous operations, which are set by actions

Actions Set asynchrony

4. Action (mutation) :

  • The Action commits mutation rather than a direct state change.
  • Actions can contain any asynchronous operation

The operation steps are similar:

  1. Add an Actions field to the Store object, write asynchronous code,
  2. Dispatches at child components
  3. You can also pass in an argument and receive it with playload

Add actions field in store to define asynchronous operation reducePrice:

actions:{
    reducePrice:(context,playload) = >{
        setTimeout(function(){
            context.commit("reducePrice",playload)
        },3000)}}Copy the code

Child components use:

  methods:{
    reducePrice(number){
      this.$store.dispatch("reducePrice",number)
    }
  }
Copy the code

Effect: 3 seconds after clicking the button, the price of the product is reduced by 4

The recommended Chrome extension is Vue. Js devTools

  • This extension allows you to view and debug vuex operations, such as mutations and Actions
  • You can search and install it in the Chrome App Store
  • Once it’s installed, you can see that the console has a vUE tag, and the initial screen looks like this, showing our HTML tags and our computed:

  • If we use mutations in the application, we can use the extension to see what happens when the application runs to this part, for example, if I click the “price reduction” button (there is no asynchronous operation that sets the price reduction), and see the data change directly

  • For actions, after pressing the button for 3 seconds, you can see changes in the debug section while the data changes

It’s nice to keep track of when the data is changing

Well, that’s all for today’s sharing, thanks for your support ~~