51.Vue的Vuex

目录

一、什么是Vuex

二、安装谷歌插件

三、Vuex的基本使用

四、Vuex的核心概念

五、项目结构


git:https://gitee.com/cxy-xupeng/vue-vuex.git

一、什么是Vuex

Vuex是一个状态管理的工具。当一个组件被多个其他组件调用,而这个组件的状态到底是什么,这需要被管理吧(有点并发内味),vuex就用来管理这个状态,并且可以是响应式

二、安装谷歌插件

先来说一下理想的步骤:

1.点击谷歌浏览器右上角的三个点号:(不会吧不会吧,不会真的有人用的不是谷歌浏览器吧?如果不是,可以使用火狐)

2.选择“更多工具”,选择“扩展程序”

3.点击左上角“扩展程序”

4.点击左下角打开Chrome网上应用商店。然后如果你能打开的话,查找Vue.js devtools进行下载(当然我没打得开。。。)

上面我愿称之为:皇帝的商店。因为根本就打不开。

下面讲解我是怎么安装的:

1.百度搜索:极简谷歌插件

2.下载vue插件

3.下载完之后是一个压缩包,解压这个压缩包

4.打开谷歌浏览器,右上角三个点,选择“更多工具”,选择“扩展程序”。在这个页面把我们上一步的CRX文件往浏览器里拖动就行。安装好后就行了

三、Vuex的基本使用

1.创建项目

此处是否需要router的?大家可以选择N

我们适当修改首页,删除helloworld,再把main.js里面关于router的删除,查看结果:

2.安装vuex

npm install vuex --save

3.目录

4.index.js中写了vuex的插件,其中state表示全局状态,mutations表示方法

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

//1.安装插件
Vue.use(Vuex)

//2.创建对象
const store = new Vuex.Store({
  state:{//状态
    count:1000
  },
  mutations:{//方法
    increment(state){
      state.count++;
    },
    decrement(state){
      state.count--;
    },
  },
  actions:{

  },
  getters:{

  },
  modules:{

  }

})

//3.导出store对象
export default store

5.HelloVuex.vue父传子的方法使用属性,只是父里面也是用了全局的state

<template>
  <div>
    {
   
   {$store.state.count}}
  </div>
</template>

<script>
  export default{
    name:'HelloVuex',
    props:{
      count:Number
    }
  }
</script>

<style>
</style>

6.main.js:引入store

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

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  store,
  render: h => h(App)
})

7.App.vue:使用属性的方法

<template>
  <div id="app">
    <h2>{
   
   {message}}</h2>
    <h2>{
   
   {counter}}</h2>
    <h2>{
   
   {$store.state.count}}</h2>
    <button @click="addition">+</button>
    <button @click="substraction">-</button>
    <hello-vuex :count="counter"></hello-vuex>
  </div>
</template>

<script>
  import HelloVuex from './components/HelloVuex.vue'

export default {
  name: 'App',
  data(){
    return{
      message:'徐鹏',
      counter:0

    }
  },
  components:{
    HelloVuex
  },
  methods:{
    addition(){
      this.$store.commit('increment')
    },
    substraction(){
      this.$store.commit('decrement')
    }
  }
}
</script>

<style>
</style>

8.查看结果: 

四、Vuex的核心概念

1.State

  • 单一状态树:我们vuex插件创建的对象,只创建一个,不要创建多个
  • 一开始放到state里面的数据,都会被响应式监听。当属性变化,会通知所有用到该属性的页面。但是未定义的属性,不会响应式

2.Getters

  • 对属性值有计算的,放在这里处理

3.Mutation

  1. vue的store状态更新的唯一方式:提交Mutation
  2. Mutation主要包括两部分:字符串的事件类型(type)+回调函数(handler)(第一个参数为state)
  3. Mutation更新:需要commit
  4. 通过type提交:在store里面,传参就是payload,其中payload包含你需要的参数
  5. 如果想要state里没定义的属性也能响应式,Vue.set()方法可以实现增加属性。Vue.delete()删除属性
  6. index.js和App.vue里面方法名其实一样,我们可以抽取常量
  7. Mutation中的方法必须是同步方法,不然devtools将不好跟踪

4.Action

  1. 因为Mutation不使用异步方法,对于异步方法,我们在action中使用

5.Module

  1. 因为state使用单一状态树,但是后面会很臃肿。因此可以将store分割成多个模块

四、对象的结构

//对象的结构
const obj = {
  name:'aa',
  age:11,
  height:1.8
}

const {name,age} = obj

五、vuex的实例

HelloVuex.vue

<template>
  <div>
    {
   
   {$store.state.count}}
  </div>
</template>

<script>
  export default{
    name:'HelloVuex',
    props:{
      count:Number
    }
  }
</script>

<style>
</style>

mutationstype.js

export const INCREMENT = 'increment'

main.js

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

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  store,
  render: h => h(App)
})

App.vue

<template>
  <div id="app">
    <h2>{
   
   {message}}</h2>
    <h2>{
   
   {counter}}</h2>
    <h2>HelloVuex的值:<hello-vuex :count="counter"></hello-vuex></h2>

    <h2>-----------vuex的state----------------</h2>
    <h2>{
   
   {$store.state.count}}</h2>

    <h2>-----------vuex的getters----------------</h2>
    <h2>count的平方:{
   
   {$store.getters.powerCounter}}</h2>
    <h2>年龄大于等于20的学生:{
   
   {$store.getters.more20stu}}</h2>
    <h2>年龄大于等于20的学生数量:{
   
   {$store.getters.more20stucount}}</h2>
    <h2>年龄大于指定数字的学生:{
   
   {$store.getters.moreAgeStu(5)}}</h2>


    <h2>-----------vuex的mutations----------------</h2>
    <button @click="addition">+</button>
    <button @click="substraction">-</button>
    <button @click="addCount(5)">+5</button>
    <button @click="addCount(10)">+10</button>
    <button @click="addStudent">添加学生</button>
    <button @click="updateStudent">响应式修改学生</button>


    <h2>-----------vuex的modules----------------</h2>
    <h2>{
   
   {$store.state.a.name}}</h2>
    <button @click="updateName">修改名字</button>
    <h2>{
   
   {$store.getters.fullname}}</h2>
    <h2>{
   
   {$store.getters.fullname2}}</h2>
    <h2>{
   
   {$store.getters.fullname3}}</h2>
    <button @click="asyncUpdateName">异步修改名字</button>



  </div>
</template>

<script>
  import HelloVuex from './components/HelloVuex.vue'
  import {INCREMENT} from './store/mutationstype.js'

export default {
  name: 'App',
  data(){
    return{
      message:'徐鹏',
      counter:0

    }
  },
  components:{
    HelloVuex
  },
  methods:{
    //1.普通提交封装
    addition(){
      this.$store.commit(INCREMENT)
    },
    substraction(){
      this.$store.commit('decrement')
    },
    // addCount(count){
    //   this.$store.commit('incrementCount',count)
    // },
    //2.特殊的提交封装
    addCount(count){
      this.$store.commit({
        type:'incrementCount',
        count
      })
    },
    addStudent(){
      const stu = {id:4,name:'ddd',age:40}
      this.$store.commit('addStudent',stu)
    },
    updateStudent(){
      // this.$store.commit('updateStudent')
      this.$store.dispatch('aUpdateStudent','我是payload')
    },
    updateName(){
      this.$store.commit('updateName','李四')
    },
    asyncUpdateName(){
      this.$store.dispatch('aaUpdateStudent')
    }
  }
}
</script>

<style>
</style>

index.js

import Vue from 'vue'
import Vuex from 'vuex'
import {INCREMENT} from './mutationstype.js'

//1.安装插件
Vue.use(Vuex)

//2.创建对象
const moduleA = {
  state:{
    name:'张三'
  },
  mutations:{
    updateName(state,payload){
      state.name = payload
    }
  },
  actions:{
    aaUpdateStudent(context){
      console.log(context.rootGetters)
      setTimeout(()=>{
        context.commit('updateName','王五')
      },1000)
    }
  },
  getters:{
    fullname(state){
      return state.name+'111'
    },
    fullname2(state,getters){
      return getters.fullname+'222'
    },
    fullname3(state,getters,rootState){
      return getters.fullname2+rootState.count
    }
  }
}


const store = new Vuex.Store({
  state:{//状态
    count:1000,
    students:[
      {id:1,name:'aaa',age:10},
      {id:2,name:'bbb',age:20},
      {id:3,name:'ccc',age:30},
    ]

  },
  mutations:{//方法
    [INCREMENT](state){
      state.count++;
    },
    decrement(state){
      state.count--;
    },
    //type提交风格
    incrementCount(state,payload){
      state.count += payload.count;
    },
    addStudent(state,stu){
      state.students.push(stu)
    },
    updateStudent(state){
      //响应式增加state里面没有的属性
      Vue.set(state.students[0],'address','上海')
      //响应式删除state的属性
      Vue.delete(state.students[1],'name')
    }
  },
  actions:{
    //context:上下文
    aUpdateStudent(context,payload){
      return new Promise((resolve,reject)=>{
        setTimeout(()=>{
          context.commit('updateStudent')
          console.log(context)
          resolve('111')
        },1000)
      }).then(res=>{
        console.log('完成提交')
        console.log(res)
      })
    }

  },
  getters:{//变化状态的值
    powerCounter(state){
      return state.count * state.count
    },
    more20stu(state){
      return state.students.filter(s=>s.age>=20)
    },
    more20stucount(state,getters){
      return getters.more20stu.length
    },
    //自己传参
    moreAgeStu(state){
      return function(age){
        return state.students.filter(s=>s.age>=age)
      }
    }
  },
  modules:{//模块
    a:moduleA,
    b:{
      state:{},
      mutations:{},
      actions:{},
      getters:{}
    },

  }

})

//3.导出store对象
export default store

五、项目结构

我们之前是吧所有的代码都写在一个文件里,太乱,需要一个合理的结构:

我们把之前的都抽出来。

具体代码可以通过git自行查看

猜你喜欢

转载自blog.csdn.net/qq_40594696/article/details/111151464