数据状态管理器(vuex)
- 作用:管理数据和状态
- Vuex有五个核心概念:
state, getters, mutations, actions, modules
- 使用(和 vue-router 一样)
- 下载包 vuex
npm i vuex
- 引入包 vuex
- Vue 实例上注册
Vue.use(vuex)
- 创造一个仓库实例
const store = new Vuex.Store()
- 把创造的 vuex 实例挂载到 Vue 实例上
new Vue({store})
首先:
在src下新建文件夹store,在store下新建index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {}
})
export default store
其次:
在main.js中引入store下的index.js
import vuex from './store'
new Vue({
// 挂载元素
el: '#app',
// 把对应的路由实例注册到vue实例中
router,
// 把对应的vuex实例挂载 到vue实例中
vuex,
// 组件 在vue里加载对应的app组件
components: { App },
// 对应的模块,就是对应的html的内容
template: '<App/>'
})
- state (状态) - 专门用来存储我们的数据
- 在 new Vuex.Store({
state: {}
}) - 在组件中获取的时候使用
this.$store.state.
数据名称 - 在组件中尽量使用
computed
来获取,因为可以随着改变而改变
- 在 new Vuex.Store({
// 创建一个 Counter 组件
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count () {
return this.$store.state.count
}
}
}
-
mutation (改变) - 在 vuex 中专门用来修改 state 中的数据
- 当你想改变
state
中的数据的时候 - 在
mutation
中去定义一个 方法,用这个方法的第一个参数 state 去修改 - 在组件中想办法调用 mutation 中改变state的方法
- 在组件中使用
commit
去调用 mutation 中的方法
// store.js new Vuex.Store({ state: { data: 'abc' }, mutations: { changeData (state) { state.data = 'gaibian' } } }) // 组件中 // 在执行 js 代码的位置(你想让数据发生改变的位置) // 第一个参数是方法名称 // 第二个参数是携带过去的数据 this.$store.commit('changeData')
示例: 在组件中改变state中的数据,传多个值
// store.js文件 const store = new Vuex.Store({ state: { data: '我是 vuex 中 state 里面的数据' }, mutations: { changeData (state, [type, str]) { state.data = type console.log(type) console.log(str) } } // mutation 中的每一个成员都是一个方法 // 这个方法就是专门用来修改 state 中的数据的 // 接收两个参数 // changeData中的参数 // state - 就代表着 store 中的那个 state 对象 // 第二个参数就是专门接收 commit 的时候带过来的参数 // 如果是一个参数,直接接收就行 // 如果是多个使用数组的形式接受 }) // comOne.vue <template> <div> {{ msg }} <p>{{ data }}</p> <button @click="changeData">改变 state 中的数据</button> <input type="text" v-model="msg"> </div> </template> <script> export default { name: 'comOne', created () { // console.log(this.$store) }, data () { return { msg: '我是 comOne 组件' // data: this.$store.state.data // 需求: 当 this.$store.state.data 改变的时候我能重新获取其值 } }, computed: { // 获取每一个 state 中的数据需要借助 computed 来获取 // 因为 computed 可以在数据发生改变的时候重新能获取 data () { return this.$store.state.data } }, methods: { changeData () { // 可以修改 state 中的数据,但是你仅仅只是可以修改数据,不能修改状态 // this.$store.state.data = '我被改变了' // 那么就需要让 $store 里面的 mutation 中的 changeData 方法执行一下 // 我们有一个 commit 属性,专门用来触发 mutation 中的方法使用的 // 合理的修改 state 中的数据的方式 // commit 第一个参数,是 mutation 中 的方法名称 // commit 第二个参数,是在调用 mutation 中的方法的时候传的参数(以数组的形式) this.$store.commit('changeData', [this.msg, 'abc']) // console.log(this.$store) } } } </script>
- 当你想改变
-
action (行为) - 在 vuex 里面专门用来异步的改变数据的方式,可以包含任意异步操作
- 不是直接去调用 mutation 中的 方法
- 而是使用了 action 中的方法去提交 mutation 中的方法,从而变更状态
- 借助了 dispatch
dispatch('action 中的方法', 调用的时候携带的参数)
// store.js
const store = new Vuex.Store({
state: {
data: '我是 vuex 中 state 里面的数据'
},
mutations: {
changeData (state, type) {
// mutations 中的方法,记录状态这个过程是同步的
// 先记录状态,然后再执行 定时器
// 所以 记录的状态是上一次的,所以 mutations不可以异步改变数据
// 并不是 改变的 数据不对 ;而是 状态不是 最新的,永远是 上一条的状态
// setTimeout(() => {
// state.data = type
// }, 0)
state.data = type
}
},
actions: {
// actions 里面接收的也是方法
// 这里面的方法专门用来去提交 mutations 中的方法
asyncChangeData (store, type) {
// store 就是整个仓库
// 你不需要等着它执行完,过了两秒就会自动执行,并且状态是最新的
setTimeout(() => {
store.commit('changeData', type)
}, 2000)
}
}
})
// comOne.vue
data () {
return {
msg: '我是 comOne 组件'
}
},
computed: {
data () {
return this.$store.state.data
}
},
methods: {
changeData () {
// 当我们想异步的改变数据的时候,不能使用commit 去提交 mutations中的 方法
// 因为不是改变不了数据,而是状态不能记录成最新的
this.$store.commit('changeData', this.msg)
// console.log(this.$store)
this.$store.dispatch('asyncChangeData', this.msg)
// 想异步的改变
// 做法:不是异步的去改变数据,而是异步的去提交改变数据的方式
// 需求:一秒钟以后改变数据
// 不是一秒钟以后再改变数据
// 而是一秒钟以后 去 提交改变数据的 行为
// 我们使用一个 action
/*
想异步去改变 state 中的数据的时候,只要让actions 中 的 asyncChangeData 执行
asyncChangeData 就会去commit mutations中的 changeData
changeData 就会去改变 state 中的数据
dispatch - 派遣,急派
- 专门用来调用 actions 中的方法
*/
/*
this.$store.dispatch('asyncChangeData', this.msg)
这行代码所走的行程:
使用dispatch 触发 actions 中的 asyncChangeData 方法,并将参数传入;
asyncChangeData 方法 使用 commit 触发 mutations 中的 changeData 方法,并将 参数携带过去;
changeData 就会去 改变 state 中的数据
计算属性 computed 发现 state 中的 data发生改变;则会重新return出新的值
*/
}
}
- getters(获取器)
- vuex 里面的 computed计算属性,就是专门用来对输出数据进行改变
有时候我们需要从store中的state中派生出一些状态,例如对列表进行过滤并计数- 在不改变原始数据的基础上让我输出的数据发生一些变化
- 和 组件中的 computed 作用完全一样
- 获取的方式和获取state 中的数据一样
this.$store.state.data // 获取 state 中的数据 this.$store.getters.data2 // 获取 getter 中处理过的数据
getters: {
// data4是所有的data的数据反转
// 和过滤器比较像,但为什么说是vuex中的 计算属性
// 因为当原始 数据 state 改变的时候,会重新 计算我的值;return出新的反转字符串;这是computed的属性
data4 (state, type) {
return state.data.split('').reverse().join('')
}
}
computed: {
data () {
// return this.$store.state.data
// 获取到的是反转后的字符串
return this.$store.getters.data4
},
}
-
modules(模块化)
- 可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理
备注:
为什么把vuex单独提出来,而不放在main.js中
1、模块化开发
2、main.js需要引入第三方插件,自己封装的组件之类的,东西过多
vuex和全局对象的区别:
1、vuex的存储是响应式的。当vue组件从store中读取状态的时候,若store中的状态发生改变,那么相应的组件也会相应地得到高效更新。
2、你不能直接改变store中的状态。改变store中的状态的唯一途径就是提交(commit)mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
如何在 vue 组件中获得vuex状态
1、由于vuex的状态存储是响应式的,从store实例中读取状态最简单的方法就是在计算属性中返回某个状态