程序员社区

vue-Vuex

目录

1.Vuex是用来做什么的?

Vuex是一个专为Vue.js应用程序开发的状态管理模式

什么是状态管理?

把多个组件需要的共享变量全部存储在一个对象里面,然后将这个对象放在顶层的Vue实例中,让其它组件可以使用

管理什么状态?

比如用户的登录状态、用户名称、头像、地理信息位置

比如商品的收藏、购物车中的物品

这些状态信息,我们都可以放在统一的地方,对它进行保存和管理,而且它们还是响应式的

2.单界面的状态管理

vue-Vuex插图

State:状态

View:视图层,可以针对State的变化显示不同的信息

Actions:主要是用户的各种操作:点击、输入等,会导致State的变化

<template>
  <div id="app">
    <h2>{{message}}</h2>
    <h2>{{counter}}</h2>
    <button @click="counter++">+</button>
    <button @click="counter--">-</button>
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      message: '我是App组件',
      counter: 0
    }
  }
}
</script>

<style>
</style>

vue-Vuex插图1

3.多界面的状态管理

小案例

①提取一个公共的store对象,用于保存在多个组件中共享的状态。

新建store文件夹,创建index.js

vue-Vuex插图2

index.js

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

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

//2.创建对象
const store = new Vuex.Store({
  state: {
    counter: 100
  },
  mutations: {
    increment(state) {
      state.counter++;
    },
    decrement(state) {
      state.counter--;
    }
  }
})

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

②将store对象放置在new Vue对象中,这样可以保证在所有组件中都可以使用到

main.js

import Vue from 'vue'
import App from './App'
import store from "./store";

Vue.config.productionTip = false

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

 ③在其他组件中使用store对象保存的状态

通过this.$store.state属性的方式来访问状态

通过this.$store.commit('mutation中方法')来修饰状态

HelloVuex.vue

<template>
  <div>
    <h2>{{$store.state.counter}}</h2>
  </div>
</template>

<script>
export default {
  name: "HelloVuex"
}
</script>

<style scoped>
</style>

App.vue 

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

<script>
import HelloVuex from "./components/HelloVuex";

export default {
  name: 'App',
  components: {
    HelloVuex
  },
  methods: {
    addition() {
      this.$store.commit('increment');
    },
    subtraction() {
      this.$store.commit('decrement');
    }
  }
}
</script>

<style>
</style>

vue-Vuex插图3

注意:我们通过提交mutation的方式,而非直接改变store.state.count

这是因为Vuex可以更明确地追踪状态的变化,所以不要直接改变store.state.count的值

4.单一状态树

Vuex使用了单一状态树来管理应用层级的全部状态

也就是说所以的共享状态信息都保存在一个store对象中,不保存在多个对象中,这样方便管理和维护

5.Getters的基本使用

有时候,我们需要从store中获取一些state变异后的状态

修改store对象

const store = new Vuex.Store({
  state: {
    counter: 100,
    students: [
      {id: 110, name:'fyx', age: 18},
      {id: 111, name:'cxl', age: 20},
      {id: 112, name:'pjt', age: 22}
    ]
  },
  mutations: {
    increment(state) {
      state.counter++;
    },
    decrement(state) {
      state.counter--;
    }
  },
  getters: {
    powerCounter(state) {
      return state.counter * state.counter
    },
    more20stu(state) {
      return state.students.filter(s => s.age > 20)
    },
    //getters可作为参数
    more20stuLength(state ,getters) {
      return getters.more20stu.length
    },
    //getters里面的函数如果想传参数
    moreAgeStu(state) {
      return age => {
        return state.students.filter(s => s.age > age)
      }
    }
  }
})

修改App.vue里面的template标签内容

<template>
  <div id="app">
    <h2>{{$store.state.counter}}</h2>
    <button @click="addition">+</button>
    <button @click="subtraction">-</button>
    <hello-vuex/>
    <h2>...Vuex相关内容...</h2>
    <h2>{{$store.getters.powerCounter}}</h2>
    <h2>年龄大于20的学生信息:{{$store.getters.more20stu}}</h2>
    <h2>年龄大于20的学生人数:{{$store.getters.more20stuLength}}</h2>
    <h2>年龄大于x的学生人数,x自己传:{{$store.getters.moreAgeStu(18)}}</h2>
  </div>
</template>

vue-Vuex插图4

6.Mutation传递参数

在通过mutation更新数据的时候,有可能我们希望携带一些额外的参数

这个参数被认为是mutation的载荷(Payload)

如果你想传的参数不止一个,我们通常会传一个对象

修改App.vue

<button @click="addCount(5)">+5</button>
<button @click="addCount(10)">+10</button>
<button @click="addStudent">添加学生</button>
  methods: {
    addition() {
      this.$store.commit('increment');
    },
    subtraction() {
      this.$store.commit('decrement');
    },
    addCount(count) {
      this.$store.commit('incrementCount', count)
    },
    addStudent() {
      const stu = {id: 113, name: 'gy', age: 25}
      this.$store.commit('addStudent', stu)
    }
  }

修改store对象的mutations

  mutations: {
    increment(state) {
      state.counter++;
    },
    decrement(state) {
      state.counter--;
    },
    incrementCount(state, count) {
      state.counter += count
    },
    addStudent(state, stu) {
      state.students.push(stu)
    }
  },

vue-Vuex插图5

7.Mutation的另一种提交风格

//1.普通的提交封装
this.$store.commit('incrementCount', count)
//2.特殊的提交封装
this.$store.commit({
  type: 'incrementCount',
  count
})

对应于mutations中的写法 

incrementCount(state, payload) {
      // state.counter += count;
      state.counter += payload.count;
    }

 这里传过来的payload其实就是前面commit里面的对象

8.mutation的响应规则

Vuex的store中的state是响应式的,当state中的数据发生改变时,Vue组件会自动更新,页面会发生变化

修改App.vue

<h2>....info对象内容...</h2>
<h2>{{$store.state.info}}</h2>
<button @click="updateInfo">修改信息</button>

修改store对象

 在mutations中添加方法

updateInfo(state) {
   state.info.name='hzr'
   // state.info['address'] = 'Los Angeles'
   Vue.set(state.info, 'address', 'Los Angeles')
   // delete state.info.age
   //该方法做不到响应式
   Vue.delete(state.info, 'age')
}

vue-Vuex插图6

点击按钮之后

vue-Vuex插图7

9.vuex-mutations的类型常量

当项目增大时,mutations里面的方法会很多,官方建议将方法名抽成常量,commit提交的时候也用常量

vue-Vuex插图8

 vue-Vuex插图9

vue-Vuex插图10

10.Mutation同步函数

Vuex要求我们Mutations中的方法必须是同步方法

因为我们在使用devtools时,devtools可以帮助我们捕捉mutation的快照

但如果是异步操作,那么devtools将不能很好地追踪这个操作什么时候会被完成

Action类似于Mutation,是用来代替Mutation进行异步操作的

vue-Vuex插图11

<h2>....info对象内容...</h2>
<h2>{{$store.state.info}}</h2>
<button @click="updateInfo">修改信息</button>

App.vue里面的methods中的方法 

updateInfo() {
   // this.$store.commit('updateInfo')
   this.$store
      .dispatch('aUpdateInfo', '我是携带的信息')
      .then(res => {
        console.log('里面完成了提交')
        console.log(res)
   })
}

store对象里mutations的updateInfo方法同上 

actions: {
    //context: 上下文
    aUpdateInfo(context, payload) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          context.commit('updateInfo')
          console.log(payload)
          resolve('2222')   //一旦执行了resolve(),就去执行then()
        }, 1000)
      })
    }
  },

修改信息并打印携带的信息之后,在App.vue里面提示"里面已完成提交",并且打印从aUpdateInfo函数传来的信息

vue-Vuex插图12

11.modules的使用

Modules是模块的意思

Vue使用单一状态树,这意味着很多状态都会交给Vuex来管理

为了解决这个问题,Vuex允许我们将store分割成模块(Module),而每个模块拥有自己的state,mutations,actions,getters等

<h2>...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>

methods中的方法 

updateName() {
   this.$store.commit('updateName', 'LiSi')
},
asyncUpdateName() {
   this.$store.dispatch('aUpdateName')
}

store对象中的modules 

modules: {
  a: moduleA
}
const moduleA = {
  state: {
    name: 'ZhangSan'
  },
  mutations: {
    updateName(state, payload) {
      state.name = payload;
    }
  },
  getters: {
    fullname(state) {
      return state.name + '1111'
    },
    fullname2(state, getters) {
      return getters.fullname + '222'
    },
    //调用根state中的变量
    fullname3(state, getters, rootState) {
      return getters.fullname2 + rootState.counter
    }
  },
  actions: {
    aUpdateName(context) {
      setTimeout(() => {
        context.commit('updateName', 'WangWu')
      }, 1000)
    }
  },
}

vue-Vuex插图13

 点击第一个按钮 

vue-Vuex插图14 

点击第二个按钮

vue-Vuex插图15

赞(0) 打赏
未经允许不得转载:IDEA激活码 » vue-Vuex

一个分享Java & Python知识的社区