Vue全家桶 | 地址 |
---|---|
Vue全家桶(一)之基础指令 | https://blog.csdn.net/m0_55990909/article/details/123917809 |
Vue全家桶(一)之常用特性 | https://blog.csdn.net/m0_55990909/article/details/123917352 |
Vue全家桶(二)之组件化开发 | https://blog.csdn.net/m0_55990909/article/details/123957131 |
Vue全家桶(三)之cli3脚手架 | https://blog.csdn.net/m0_55990909/article/details/123956982 |
Vue全家桶(四)之ES6模块化与webpack打包 | https://blog.csdn.net/m0_55990909/article/details/124019983 |
Vue全家桶(五)之Vue-Router路由 | https://blog.csdn.net/m0_55990909/article/details/123994048 |
Vue全家桶(六)之VueX状态管理 | https://blog.csdn.net/m0_55990909/article/details/124017667 |
Vue接口调用(一)fetch用法 | https://blog.csdn.net/m0_55990909/article/details/123957200 |
Vue接口调用(二)axios用法 | https://blog.csdn.net/m0_55990909/article/details/123981283 |
Vue接口调用(三)async/await用法 | https://blog.csdn.net/m0_55990909/article/details/123981292 |
✍目录总览:
1. VueX的概念
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
2. 状态管理的概念
可以简单的将其看成把需要多个组件共享的变量全部存储在一个对象里面。
将这个对象放在顶层的Vue实例中,让其他组件可以使用。
在单文件组件中进行状态管理:
图片中的三种东西如下:
//单文件组件内部代码
<template>
<div>
<div>当前计数:{{counter}}</div>
<button @click="counter+=1">+1</button>
<button @click="counter-=1">-1</button>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
counter: 0
}
}
}
</script>
<style scoped>
</style>
上述案例中,需要管理的状态:个数counter。
counter需要某种方式被记录下来,也就是我们的State。
counter目前的值需要被显示在界面中,也就是我们的View部分。
界面发生某些操作时(我们这里是用户的点击,也可以是用户的input),需要去更新状态,也就是我们的Actions
3.1 单个文件的组件状态管理清晰明了,那多个单文件组件的状态管理呢?(出现的问题)
3.2 VueX背后的基本思想:(解决方法)
1. 将多个组件共享的状态抽取出来,交给我们的大管家VueX,统一进行管理。
2. 每个组件视图,按照VueX的规则定,进行访问和修改等操作。
npm install vuex --save
我们创建一个文件夹 src/store,并且在其中创建一个 store.js 文件,代码如下:
import Vuex from 'vuex'
import Vue from 'vue'
// 1.安装插件
Vue.use(Vuex)
// 2.创建对象
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state){
state.count++
},
decrement(state){
state.count--
}
},
actions: {
},
getters: {
},
modules: {
}
})
// 导出store对象
export default store
其次,我们让所有的Vue组件都可以使用这个store对象
import Vue from 'vue'
import App from './App'
// 1.导入store对象
import store from './store'
new Vue({
el: '#app',
// 2.挂载 store
store,
render: h => h(App)
})
this.$store
的方式,获取到这个store对象了//app.vue根组件
<template>
<div id="app">
<p>
<button @click="increment">+1</button>
<button @click="decrement">-1<</button>
</div>
</template>
//行为层
<script>
export default {
name: 'App',
components: {
},
computed: {
count: function() {
return this.$store.state.count
}
},
methods: {
increment: function() {
this.$store.commit('increment')
},
decrement: function() {
this.$store.commit('decrement')
}
}
}
</script>
使用步骤小结:
强调:VueX的store.js定义方式固定,获取方式有两种:
State 提供唯一的公共数据源,所有共享的数据都要统一放到 Store 的 State 中进行存储。
// 创建store数据源,提供唯一公共数据
const store = new Vuex.Store({
state: { count: 0 }
})
组件获取 State 中数据的第一种方式:
this.$store.state.全局数据名称
组件获取 State 中数据的第二种方式:
// 1. 从 vuex 中按需导入 mapState 函数
import { mapState } from 'vuex'
通过刚才导入的 mapState 函数,将当前组件需要的全局数据,映射为当前组件的 computed 计算属性:
// 2. 将全局数据,映射为当前组件的计算属性
computed: {
...mapState(['count'])
}
① 只能通过 mutation 变更 Store 数据,不可以直接操作 Store 中的数据。
② 通过这种方式虽然操作起来稍微繁琐一些,但是可以集中监控所有数据的变化。
调用方式一:
调用方式一:
调用方式二:
1.store.js内定义函数
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
//store.js内定义函数
export default new Vuex.Store({
state: {
count: 0
},
// 只有 mutations 中定义的函数,才有权利修改 state 中的数据
mutations: {
subN(state, step) {
state.count -= step
}
},
}
2.在组件文件内导入函数 绑定函数
//组件文件内导入函数 绑定函数
<template>
<div>
<h3>当前最新的count值为:{{count}}</h3>
//引入的函数进行绑定
<button @click="subN(3)">-N</button>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
data() {
return {}
},
computed: {
//将指定的state变量,映射为当前组件的computed计算属性
...mapState(['count']),
},
methods: {
//将指定的 mutations 函数,映射为当前组件的 methods 函数
...mapMutations(['sub', 'subN']),
}
}
</script>
如果通过异步操作变更数据,必须通过 Action,而不能使用 Mutation,但是在 Action 中还是要通过触发Mutation 的调用方式间接变更数据。
调用方式一:
调用方式二:
//store.js内定义函数
export default new Vuex.Store({
state: {
count: 0
},
// 只有 mutations 中定义的函数,才有权利修改 state 中的数据
mutations: {
sub(state) {
state.count--
}
actions: {
subAsync(context) {
setTimeout(() => {
context.commit('sub')
}, 1000)
}
//组件文件内导入函数 绑定函数
<template>
<div>
<h3>当前最新的count值为:{{count}}</h3>
//引入的函数进行绑定
<button @click="subAsync">-1 Async</button>
</div>
</template>
<script>
//导入store.js里面的acion、mutation函数,acion内部调用mutation
import { mapState, mapMutations, mapActions } from 'vuex'
export default {
data() {
return {}
},
computed: {
//将指定的state变量,映射为当前组件的computed计算属性
...mapState(['count']),
},
methods: {
//将指定的 action 函数,映射为当前组件的 methods 函数
...mapMutations(['sub']),
...mapActions(['subAsync'])
}
}
</script>
1.store.js内定义函数
2.在组件文件内导入函数 绑定函数
① Getter 可以对 Store 中已有的数据加工处理之后形成新的数据,类似 Vue 的计算属性。
② Store 中数据发生变化,Getter 的数据也会跟着变化。
1.store.js内定义函数
2.调用VueX
调用方式1:当作全局对象直接进行调用
调用方式2:在组件文件内导入模块 绑定属性和函数
Module 是模块的意思,为什么在 Vuex 中我们要使用模块呢?
const ModuleA = {
state: {},
mutations: {},
actions: {},
getters: {}
}
const ModuleB = {
state: {},
mutations: {},
actions: {},
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态