VueX
什么是VueX?
-
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension (opens new window),提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
-
什么是状态管理
如果我们多个组件想共享同一个数据 , 我们可以考虑将数据放到一个公共的对象中 , 将这个公共对象放入Vue的protoType中 , 这样虽然做到了数据共享 , 但是由于是我们自己封装的 , 不是响应式的 , 所以Vue出了一个插件
VueX
Vuex就是为了提供这样—个在多个组件间共享状态的插件// 共享对象 const Variable = { name : 'Renyi' } // 将Variable 放入Vue原型中 Vue.prototype.Variable = Variable; // 多组件共享 Vue.component('cpn1', { this.Variable.name }) Vue.component('cpn2', { this.Variable.name }) const vue = new Vue({ el : "#app", data: { } })
-
什么时候使用VueX
当多个组件需要共享数据时 , 比如用户的登录状态
VueX 的使用
-
创建项目
vue init webpack vuex
-
安装 VueX
npm install vuex --save
-
在src下创建 store 文件夹
我们在src下单独创建一个文件夹 , 用于vuex , 这个文件夹的名词为
store
并在其下建立一个index.js
文件我们在
index.js
文件中导入 vuex 并在 ,mian.js
中进行注册 , 并且我们创建Vuex.store
对象 , 其有state
属性 , 我们可以定义i一些公共的属性,在这里我们定义一个count
/*store/index.js*/ import vue from "vue" import vuex from "vuex" // 1. 安装插件 vue.use(vuex) // 2. 创建对象 const store = new vuex.store({ stata: { count: 1000 } }) export default store
/*mian.js*/ ... import store from "./store/index" /* eslint-disable no-new */ new Vue({ el: '#app', router, store, render: h => h(App) })
-
在以上代码中 , 我们在
store/index.js
文件中的Vue.store
对象中定义了state
属性 , 并在其中定义了count
属性 , 我们可以在其他组件中使用它 -
创建
HelloVue.vue
文件 , 并通过$store.state.price
引用我们的count
属性<template> <div> <h1>{{$store.state.count}}</h1> <button @click="increase">+</button> <button @click="decrease">-</button> </div> </template> <script> export default { name: "HelloVue", methods: { increase() { this.$store.state.price++ }, decrease() { this.$store.state.price-- } } } </script>
-
但是 VueX 并不推荐我们直接通过
store
操作state
它希望我们通过store
下的属性mutations
进行操作 , 在mutations
中的方法 , vue会自动传入state
属性 , 我们可以直接操作它/*store/index.js*/ import Vue from "vue" import Vuex from "vuex" // 1. 安装插件 Vue.use(Vuex) // 2. 创建对象 const store = new Vuex.Store({ state: { price: 1000 }, mutations: { increase(state) { state.price++ }, decrease(state) { state.price-- } } }) export default store
-
此时我们在组件中必须通过
this.$store.commit("increase")
来操作increase
就是mutations
中定义的方法名<template> <div> <h1>{{$store.state.price}}</h1> <button @click="increase">+</button> <button @click="decrease">-</button> </div> </template> <script> export default { name: "HelloVue", methods: { increase() { this.$store.commit("increase") }, decrease() { this.$store.commit("decrease") } } } </script>
VueX的核心
-
State
-
Mutation
-
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
const store = new Vuex.Store({ state: { count: 1 }, mutations: { increment (state) { // 变更状态 state.count++ } } })
-
我们可以通过
this.$store.commit("函数名")
来调用mutations
中的函数increaseCount(count){ this.$store.commit("increment") }
-
Mutation携带参数
increaseCount(count){ this.$store.commit("increaseCount",count) }
mutations: { increaseCount(state,count) { state.price += count } }
-
修改state中的属性
-
如果我们想要修改
state
中的属性 , 可以怎么做呢? -
Info
state: { info: { name: "renyi", age: 20 } }
Mutation
mutations: { updateInfo(state,address){ //add state.info['address'] = "chengdu" } }
这种方式无法做到响应式开发
-
通过
Vue.set
可以做到响应式开发mutations: { // 往state 的 info中添加一个属性address值为chengdu addInfo(state){ Vue.set(state.info,"address","chengdu") } // 删除state 的 info中的 address 属性 deleteInfo(state){ Vue.delete(state.info,"address") } }
-
-
-
Getters
-
如果我们需要将
state
中的数据进行修改后在获取 , 我们可以通过getters
来实现 , 其实我们也可以在methods
或computed
中实现 , 但是代码无法实现复用 -
state 中有以下数据 , 我需要获取 a ge 大于等于20的
state: { price: 1000, Students: [ {name: "renyi" , age : 20 , high : "166"}, {name: "lisi" , age : 55 , high : "188"}, {name: "wangwu" , age : 15 , high : "195"}, {name: "zhaoliu" , age : 23 , high : "230"} ] }
-
通过 getters 获取
getters: { getStudentLimit(state){ /* Students数组中的每一个元素都会赋值给student , 当student.age >= 23返回true , 就会将当前元素添加到临时数组 , 等待Students 迭代完毕后 , 将所有返回true的元素 , 添加到Students 数组中, 覆盖其原数据 */ return state.Students.filter(student => { return student.age >= 20 }) } }
-
展示
<h3>{{$store.getters.getStudentLimit}}</h3>
-
我们还可以在
getters
中继续使用getters
/*获取getStudentLimit返回的数组的长度*/ getStudentSize(state,getters){ return getters.getStudentLimit.length }
-
如果我们需要通过传递参数的方式进行盗用getters中的数据呢
/* customAge 返回的是一个函数(function) 那么我们可以继续调用这个function并且传递参数 最终在这个function中返回需要的数据 */ customAge(state,getters){ return function (age) { return state.Students.filter(student => { return student.age >= age }) } }
<!-- $store.getters.customAge 返回的是一个函数 我们可以调用这个函数: 函数(24) 最终$store.getters.customAge(24)返回的就是我们需要的数据 --> <h3>{{$store.getters.customAge(24)}}</h3>
-
-
Action
-
Module