努力不一定成功,但是,不努力一定很轻松!!!
【23.Vuex
】
[可以去官网看看Vuex3文档](Vuex 是什么? | Vuex (vuejs.org))
-
问题1:Vuex是什么?
-
【官方理解1】:Vuex 是一个专为 Vue.js 应用程序开发的状态【数据】管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools。
-
【理解2】:vuex是使用vue中必不可少的一部分,基于父子、兄弟组件,我们传值可能会很方便,但是如果是没有关联的组件之间要使用同一组数据,就显得很无能为力,那么vuex就很好的解决了我们这种问题,它相当于一个公共仓库,保存着所有组件都能共用的数据。
-
【理解3】:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,Vuex是实现组件
全局状态(数据)管理
的一种机制,可以方便的实现组件之间的数据共享
。如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。如果您的应用够简单,最好不要使用Vuex。 -
【理解4】:Vuex是在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。
-
-
问题2:使用Vuex管理数据优势?
- 能够在 vuex 中集中管理共享的数据【state中】,便于开发和后期进行维护。
- 能够高效的实现组件之间的数据共享,提高开发效率。
- 存储在 vuex 中的数据是响应式的,当数据发生改变时,页面中的视图也会同步更新。
- vuex中的数据操作可以在开发阶段通过开发调试工具来进行追踪,便于开发。
- 简单来说,vuex 就是为了实现组件间通信的。使用 vuex 的好处:可以跨层级进行通信;vuex 中的所有操作都有记录;vuex 独立于组件系统,是专门用来管理数据的框架。
注意:
- vuex 是 vue 作者为我们提供的一套全局状态管理工具。
- 标准化操作数据,代码调试和封装更加有据可行。
- 集中式的数据管理,便于查看数据。
- vuex 中的数据没有持久化能力,如果想要持久化,可以自行来解决。
- vuex 解决的问题是在复杂项目中,组件间的通信。
-
问题3:什么时候使用Vuex?
Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。
-
问题4:安装vuex环境
-
【vue2版本】:需要安装vuex3这个版本
npm i vuex@3 //@:指定版本
-
【vue3版本】:需要安装vuex4这个版本
npm i vuex@4 //@:指定版本
-
-
问题5:配置vuex环境
新建store文件->index.js,进行如下配置,在main.js中进行引入
//引入Vue核心库 import Vue from 'vue' //引入Vuex import Vuex from 'vuex' //应用Vuex插件 Vue.use(Vuex) //准备actions对象——响应组件中用户的动作 const actions = {} //准备mutations对象——修改state中的数据 const mutations = {} //准备state对象——保存具体的数据 const state = {} //创建并暴露store export default new Vuex.Store({ // 简写 actions, mutations, state })
在
main.js
中创建vm时传入store
配置项【因为index.js
这种特殊的命名可以被vue识别,所以引入的时候,不用./store/index.js
】...... //引入store import store from './store' ...... //创建vm new Vue({ el:'#app', render: h => h(App), store, })
Vuex
- 组件派发【dispatch】任务到actions,actions触发mutations中的方法,然后mutations来改变state中的数据,数据变更后响应推送给组件,组件重新渲染。
成员列表:
- state:存放状态(全局状态数据) 必填项。
- getters:获取 state 中的数据,可以认为是 store 的计算属性【类似于组件中的计算属性】。
- mutations:对于 state 成员进行同步修改操作(也可以支持异步操作)。
- actions:进行异步操作,异步得到结果后通知 mutation 修改 state 成员。
- modules【模块】:模块化状态管理,多状态文件管理时使用,开发项目时多为多模块项目在多模块 vuex 中会有配置
namespaced:true
开启命名空间。
Vuex工作流程:
vue 组件会从 vuex 的 state 中获取数据,当组件修改数据时,会经过以下流程:
-
当触发同步操作时:vue 组件通过 commit 方法通知 mutations (同时 mutations 会在 Devtools 调试工具中记录发生的操作)设置 state 数据,数据设置完成后,state 响应式的让组件重新渲染。
注意:vuex 存储的数据是响应式的,只要 state 中的数据发成改变,视图就会重新渲染。
-
当触发异步操作时:vue 组件通过 dispatch 方法通知 actions 和 API【ajax调后端接口返回值】交互,从而得到数据,actions 得到数据之后通过 commit 方法通知 mutations (同时 mutations 会在 Devtools 调试工具中记录发生的操作)设置 state 数据,数据设置完成后,state 响应式的让组件重新渲染。
Devtools为vux官方提供的开发者调试工具,它跟Mutations进行对话。
案例1:vuex求和
- 【
流程的第一步
:从vc–通过派发dispatch(‘A’,value)–>actions】:我们看一下actions中jia(context, value)
传递的两个参数
子组件.vue
【vc】
// 组件派发【dispatch】任务到actions
this.$store.dispatch('字符串的事件类型',要传递的数据)
this.$store.dispatch('jia',this.n)
store/index.js中的actions部分
【store】
//准备actions——用于响应组件中的动作【接收组件派发过来的方法】
const actions = {
jia(context, value) {
console.log('actions中的jia被调用了')
context.commit('JIA',value)
console.log(context);
console.log(value);
},
};
- 第一个参数:context【像一个ministore】
- ministore中:有commit,dispatch,getters,state等等属性,actions里的操作空间很大【比如:我想在actions中判断一下state中存储数据sum的奇偶性,那么可以这样访问
context.state.sum
】
- ministore中:有commit,dispatch,getters,state等等属性,actions里的操作空间很大【比如:我想在actions中判断一下state中存储数据sum的奇偶性,那么可以这样访问
- 第二个参数:value【
this.n
】
- 【
流程的第二步
:从actions/组件–通过commit(‘A/B’,value)–>mutations,并在mutations中操作state中的数据】:我们看一下mutations中JIA(state, value)
传递的两个参数 - 当我们不需要在actions中拿到后台的数据时,可以省略第一步。
省略actions的情况:
子组件.vue
【省略后的vc中】
// 组件派发【commit】任务到mutations
this.$store.commit('字符串的事件类型',要传递的数据)
this.$store.commit('JIA',this.n)
store/index.js中的actions和mutations部分
【省略后store的mutations中】
- actions中就不需要写了,跳过actions这一步
const actions ={};
//准备mutations——用于操作数据(state)
const mutations = {
JIA(state, value){
console.log('mutations中的JIA被调用了')
state.sum+= value
},
};
正常不省略actions的情况:
子组件.vue
【不省略actions的vc中】
// 组件派发【dispatch】任务到actions
this.$store.dispatch('字符串的事件类型',要传递的数据)
this.$store.dispatch('jia',this.n)
store/index.js中的actions和mutations部分
【store】
//准备actions——用于响应组件中的动作【接收组件派发过来的方法】
const actions = {
jia(context, value) {
console.log('actions中的jia被调用了')
context.commit('JIA',value)
},
};
//准备mutations——用于操作数据(state)
const mutations = {
JIA(state, value){
console.log('mutations中的JIA被调用了')
state.sum+= value
console.log(state);
console.log(value);
}
};
- 第一个参数:state
- 第二个参数:value【
this.n
】
vuex求和案例展示;
vuex求和案例完整代码:
store/index.js中
//该文件用于创建Vuex中最为核心的store
import Vue from 'vue';
//引入Vuex
import Vuex from 'vuex';
//应用Vuex插件
Vue.use(Vuex);
//准备actions——用于响应组件中的动作【接收组件派发过来的方法】
const actions = {
/* jia(context, value) {
console.log('actions中的jia被调用了')
context.commit('JIA',value)
},
jian(context,value){
console.log('actions中的jian被调用了')
context.commit('JIAN',value)
}, */
jiaOdd(context,value){
console.log('actions中的jiaOdd被调用了')
// 这里可以访问到state里存储的数据 sum
if(context.state.sum % 2){
context.commit('JIA',value)
}
},
jiaWait(context,value) {
console.log('actions中的jiaWait被调用了')
setTimeout(() => {
context.commit('JIA',value)
}, 500);
},
};
//准备mutations——用于操作数据(state)
const mutations = {
JIA(state, value){
console.log('mutations中的JIA被调用了')
state.sum+= value
},
JIAN(state,value){
console.log('mutations中的JIAN被调用了')
state.sum -= value
},
};
//准备state——用于存储数据
//数据,相当于data
const state = {
sum: 0, //当前的和
};
//创建并暴露store
export default new Vuex.Store({
// property 简写 (用在对象某个 property 的 key 和被传入的变量同名时)
actions,
mutations,
state,
});
main.js
//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//引入vue-resource插件
import vueResource from 'vue-resource';
//引入store
import store from './store'
//关闭Vue的生产提示
Vue.config.productionTip = false
//使用插件
Vue.use(vueResource)
//创建vm
new Vue({
el:'#app',
render: h => h(App),
// property 简写 (用在对象某个 property 的 key 和被传入的变量同名时)
// 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
store,
// 生命周期钩子beforeCreate中模板未解析,且this是vm
beforeCreate() {
// this:指的是vm
Vue.prototype.$bus = this //安装全局事件总线$bus
}
})
App.vue
<template>
<div>
<Count/>
</div>
</template>
<script>
import Count from './components/Count'
export default {
name:'App',
components:{Count},
mounted() {
// console.log('App',this)
},
}
</script>
Count.vue
<template>
<div>
<h1>当前求和为:{{ $store.state.sum }}</h1>
<select v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="increment">+</button>
<button @click="decrement">-</button>
<button @click="incrementOdd">当前求和为奇数再加</button>
<button @click="incrementWait">等一等再加</button>
</div>
</template>
<script>
export default {
name: 'Count',
data() {
return {
n: 1,
};
},
methods: {
/* increment() {
// 组件派发【dispatch】任务到actions,然后在actions中触发mutations中的方法
this.$store.dispatch('jia',this.n)
},
decrement() {
this.$store.dispatch('jian',this.n)
}, */
increment() {
// 组件派发【dispatch】任务到actions,然后在actions中触发mutations中的方法
this.$store.commit('JIA', this.n);
},
decrement() {
this.$store.commit('JIAN', this.n);
},
incrementOdd() {
this.$store.dispatch('jiaOdd', this.n);
},
incrementWait() {
this.$store.dispatch('jiaWait', this.n);
},
},
mounted() {
console.log('Count', this);
},
};
</script>
<style scoped>
button {
margin-left: 10px;
}
select {
margin-left: 20px;
}
</style>