共计 4398 个字符,预计需要花费 11 分钟才能阅读完成。
Vuex 是什么?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理器,采用 集中式存储 管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
Vue 核心概念
State
Vuex store 实例的根状态对象,用于定义共享的状态变量。
Getter
读取器,外部程序通过它获取变量的具体值,或者在取值前做一些计算(可以认为是 store 的计算属性)
Mutation
修改器,它只用于修改 state 中定义的状态变量。
Action
动作,向 store 发出调用通知,执行本地或者远端的某一个操作(可以理解为 store 的 methods)
Module
vuex 在 vue-cli 中的应用
第一步:npm 下载 vuex 资源包:
npm install vuex -S
第二步:在 src 下创建文件夹,在 src 下创建 store.js,官方推荐项目结构
store.js 文件
import Vue from ‘vue’
import Vuex from ‘vuex’
import * as getters from ‘./store/getters’ // 导入响应的模块,* 相当于引入了这个组件下所有导出的事例
import * as actions from ‘./store/actions’
import * as mutations from ‘./store/mutations’
Vue.use(Vuex)
// 首先声明一个需要全局维护的状态 state, 比如 titelName
const state = {
titelName: ‘ 小 A 的大标题 ’ // 默认值
// id: xxx 如果还有全局状态也可以在这里添加
// name:xxx
}
export default new Vuex.Store({
strict: process.env.NODE_ENV !== ‘production’, // 在严格模式下,无论何时发生了状态变更且不是由 mutation 函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。不要在发布环境下启用严格模式以避免性能损失!
state, // 共同维护的一个状态,state 里面可以是很多个全局状态
getters, // 获取数据并渲染
actions, // 数据的异步操作
mutations // 处理数据的唯一途径,state 的改变或赋值只能在这里
})
getter.js 文件
// 获取最终的状态信息
export const titelName = state => state.titelName
actions.js 文件
// 给 action 注册事件处理函数。当这个函数被触发时候,将状态提交到 mutations 中处理
export function modifyAName({commit}, name) {// commit 提交;name 即为点击后传递过来的参数,此时是 ‘A 餐馆 ’
return commit(‘modifyAName’, name)
}
// export const modifyAName = ({commit},name) => commit(‘modifyAName’, name)
export const modifyBName = ({commit}, name) => commit(‘modifyBName’, name)
mutations.js 文件
// 提交 mutations 是更改 Vuex 状态的唯一合法方法
export const modifyAName = (state, name) => {
state.titelName = name // 把方法传递过来的参数,赋值给 state 中的 titelName
}
export const modifyBName = (state, name) => {
state.titelName = name
}
router.js 文件
import Vue from ‘vue’
import Router from ‘vue-router’
import Home from ‘./views/Home.vue’
import componentA from ‘./components/componentA.vue’
import componentB from ‘./components/componentB.vue’
Vue.use(Router)
export default new Router({
routes: [
{
path: ‘/’,
name: ‘home’,
component: Home
},
{
path: ‘/about’,
name: ‘about’,
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: “about” */ ‘./views/About.vue’)
},
{
path: ‘/componentA’,
name: ‘componentA’,
component: componentA
},
{
path: ‘/componentB’,
name: ‘componentB’,
component: componentB
},
]
})
componentA.vue 文件
<template>
<div>
<span>A 页面名字 </span>
<input type=”text” name id v-model=”titelName” @keydown=”modifyAName(titelName)”>
<button @click=”modifyAName(‘ssds’)”> 改标题 </button>
<button @click=”jump()”> 调到 B 页面 </button>
</div>
</template>
<script>
// import {mapActions, mapGetters} from “vuex”;
import {mapActions} from “vuex”;
export default {
data() {
return {};
},
methods: {
…mapActions([‘modifyAName’]), // 相当于 this.$store.dispatch(‘modifyName’), 提交这个方法
jump() {
this.$router.push(“componentB”);
}
},
computed: {
// 注意 v-model v-if
// …mapGetters([“titelName”])
titelName: {
get() {
return this.$store.state.titelName;
},
set(val) {
console.log(val);
this.$store.commit(‘modifyAName’, val);
// this.$store.dispatch(‘modifyAName’);
console.log(this.$store.state.titelName);
}
}
}
};
</script>
<style scoped>
</style>
componentB.vue 文件
<template>
<div>
<span>B 页面名字 </span>
<input type=”text” name id v-model=”titelName” @keydown=”modifyBName(titelName)”>
<button @click=”jump()”> 调到 A 页面 </button>
</div>
</template>
<script>
// import {mapActions, mapGetters} from “vuex”;
import {mapActions} from “vuex”;
export default {
data() {
return {};
},
methods: {
…mapActions(
//
[“modifyBName”]
),
jump() {
this.$router.push(“componentA”);
}
},
computed: {
// …mapGetters([“titelName”])
titelName: {
get: function() {
return this.$store.state.titelName;
},
set: function(val) {
this.$store.commit(“modifyBName”, val);
}
}
}
};
</script>
<style scoped>
</style>
// 第三步:在 src/main.js 中引入
import Vue from ‘vue’
import App from ‘./App.vue’
import router from ‘./router’
import store from ‘./store’
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount(‘#app’)
如何在组件中去使用 vuex 的值和方法
直接获取、修改
//state
this.$store.state.count
//getter
this.$store.getters.count
// 调用 action 修改 state 值,不带参数
this.$store.dispatch(‘increment’);
// 调用 action 修改 state 值,带参数
this.$store.dispatch(‘increment’,{value :123});
通过 辅助函数 获取、修改 vuex
vuex 提供了三种辅助函数用于获取、修改 vuex:mapState、mapGetters、mapActions 即将 vuex 的变量或者方法映射到 vue 组件 this 指针上。
使用 state 获取共享变量
<script type=”text/javascript”>
import {mapState} from ‘vuex’
export default{
computed : {
…mapState([
‘count’,
‘buttonShow’
])
}
}
</script>
使用 getters 获取共享变量,
<script type=”text/javascript”>
import {mapGetters} from ‘vuex’
export default{
computed : {
…mapGetters([
‘count’,
‘buttonShow’
])
}
}
</script>
使用 actions 修改共享变量
<script type=”text/javascript”>
import {mapActions} from ‘vuex’
export default{
methods : {
…mapActions({increment:’increment’,decrement:’decrement’}),
}
}
</script>