Vuex 复习笔记
Vuex命名空间及如何获取根模块、兄弟模块状态管理器_vuex获取兄弟类 state-CSDN博客
什么是 Vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
核心概念
- State: 存储应用的状态数据。
- Getters: 从 state 中派生出一些状态,这些状态可以视为 state 的计算属性。
- Mutations: 更改 Vuex 的 store 中的状态的唯一方法。
- Actions: 与 mutation 类似,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
- Modules: 将 store 分割成模块(module),每个模块有自己的 state、mutation、action 和 getter,甚至可以嵌套子模块。
使用步骤
- 安装 Vuex
npm install vuex --save
- 创建 store
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
// 全局状态
},
getters: {
// 全局 getter
},
mutations: {
// 全局 mutation
},
actions: {
// 全局 action
},
modules: {
// 模块
}
});
- 在 Vue 实例中使用 store
import store from './store';
new Vue({
store,
render: h => h(App),
}).$mount('#app');
结合代码详细讲解
目录结构
├── components
│ ├── login.js
│ └── panel.js
├── css
│ └── style.css
├── index.html
├── lib
│ ├── vue.min.js
│ └── vuex.min.js
└── store
├── BaseModule.js
├── UserModule.js
└── index.js
BaseModule.js
export default {
state: {
welcome: ''
},
mutations: {
say(state, message) {
state.welcome = message;
}
},
getters: {
welcome: state => state.welcome
}
}
UserModule.js
export default {
state: {
username: '',
token: ''
},
mutations: {
login(state, { username, token }) {
state.username = username;
state.token = token;
}
},
getters: {
username: state => state.username,
token: state => state.token
}
}
index.js
import Vue from 'vue';
import Vuex from 'vuex';
import BaseModule from './BaseModule';
import UserModule from './UserModule';
Vue.use(Vuex);
export default new Vuex.Store({
modules: {
base: BaseModule,
user: UserModule
}
});
index.html
<!DOCTYPE html>
<html lang="zn-CH">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="./lib/vue.min.js"></script>
<script src="./lib/vuex.min.js"></script>
<script src="./store/BaseModule.js"></script>
<script src="./store/UserModule.js"></script>
<script src="./store/index.js"></script>
<link rel="stylesheet" href="./css/style.css">
</head>
<body>
<div id="app">
<div class="wrapper" style="width: 900px;">
<!-- 2. 登录成功后的欢迎界面 -->
<Panel v-if="token" :username="username">
{{ welcome }}
</Panel>
<!-- 1. 登录界面 -->
<Login v-else @confirm="login">
{{ welcome }}
</Login>
</div>
</div>
<script src="./components/login.js"></script>
<script src="./components/panel.js"></script>
<script>
import store from './store/index.js';
var app = new Vue({
el: '#app',
store, // 添加 store
computed: {
welcome() {
return this.$store.getters['base/welcome'];
},
username() {
return this.$store.getters['user/username'];
},
token() {
return this.$store.getters['user/token'];
}
},
methods: {
// 回车/点击确认的回调事件
login(username) {
if (username) {
this.$store.commit('user/login', { username, token: 'sxgWKnLADfS8hUxbiMWyb' });
this.$store.commit('base/say', '登录成功,欢迎你回来!');
}
}
}
});
</script>
</body>
</html>
解释
- 模块化存储:在
BaseModule.js
和UserModule.js
中定义了两个模块,分别管理不同的状态和 mutation,使用namespaced: true
可以避免命名冲突。 - 集中化状态管理:在
index.js
中创建了 Vuex store,并将模块注册到 store 中。 - 绑定 store:在 Vue 实例中绑定了 store,使得组件可以通过
this.$store
访问 Vuex store。 - 响应式数据绑定:在
index.html
中的 Vue 实例使用computed
计算属性从 Vuex store 中获取状态数据,并在模板中使用。 - 方法绑定:在 Vue 实例的方法中调用 Vuex 的
commit
方法提交 mutation,更改状态。
例题:消失的 Token
介绍
小蓝开发了一个登录功能,但是在登录界面中输入用户名后点击“确认”按钮并没有如预期般成功进入欢迎界面。但是从出现欢迎语来看,数据已经发生了改变,到底是怎么回事呢?请帮助小蓝排查代码,让登录功能回归正常吧!
准备
目录结构如下:
├── components
│ ├── login.js
│ └── panel.js
├── css
│ └── style.css
├── index.html
├── lib
│ ├── vue.min.js
│ └── vuex.min.js
└── store
├── BaseModule.js
├── UserModule.js
└── index.js
其中:
index.html
是主页面。components
是为示例组件文件夹。lib
是存放项目相关依赖的文件夹。store
是 Vuex 状态管理文件夹。css
是存放项目样式的文件夹。
注意:打开环境后发现缺少项目代码,请复制下述命令至命令行进行下载。
cd /home/project
wget https://labfile.oss.aliyuncs.com/courses/18164/dist_03.zip
unzip dist_03.zip
mv dist/* ./
rm -rf dist*
在浏览器中预览 index.html
页面效果如下:
此时输入用户名后回车/点击确定,数据发生改变,但还是停留在登录页,无法正确显示登录成功界面。
目标
找到 index.html
中的 TODO
部分,仔细阅读 store
文件夹下的相关代码并结合 Vuex
相关知识,排查代码中存在的问题,修改后使得登录界面输入 admin 时,点击确认按钮/回车可以正确显示如下界面:
规定
- 请按照给出的步骤操作,切勿修改默认提供的文件名称、文件夹路径等。
- 满足需求后,保持 Web 服务处于可以正常访问状态,点击「提交检测」系统会自动检测。
判分标准
- 本题完全实现题目目标得满分,否则得 0 分。
- 在 Vuex 中,访问 state 需要通过正确的路径和语法。你提到的
this.$store.state['user/username']
不能访问是因为state
对象是一个普通的 JavaScript 对象,不能用这种形式访问嵌套的属性。 - 正确的访问方式如下:
- 访问模块的 state
console.log(this.$store.state.user.username); console.log(this.$store.state.user.token);
- 访问带命名空间的 getter
javascript console.log(this.$store.getters['user/username']); console.log(this.$store.getters['user/token']);
- 这里是一个完整的示例,说明如何正确访问 Vuex store 中的 state 和 getter。
- BaseModule.js
- UserModule.js
- index.js
- index.html
- 解释
- 访问模块 state:
console.log(this.$store.state.user.username); console.log(this.$store.state.user.token);
这是正确的方式,因为state
对象中user
模块是一个子对象,直接访问子对象的属性即可。 - 访问模块 getter:
javascript console.log(this.$store.getters['user/username']); console.log(this.$store.getters['user/token']);
使用带命名空间的 getter 访问方式,这样可以确保访问到正确的 getter。 - 使用这些正确的方式,可以避免访问错误并确保能够正确读取 Vuex store 中的状态和 getter。
<!DOCTYPE html>
<html lang="zn-CH">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="./lib/vue.min.js"></script>
<script src="./lib/vuex.min.js"></script>
<script src="./store/BaseModule.js"></script>
<script src="./store/UserModule.js"></script>
<script src="./store/index.js"></script>
<link rel="stylesheet" href="./css/style.css">
</head>
<body>
<div id="app">
<div class="wrapper" style="width: 900px;">
<!-- 2. 登录成功后的欢迎界面 -->
<Panel v-if="token" :username="username">
{{welcome}}
</Panel>
<!-- 1. 登录界面 -->
<Login v-else @confirm="login">
{{welcome}}
</Login>
</div>
</div>
<script src="./components/login.js"></script>
<script src="./components/panel.js"></script>
<script>
var app = new Vue({
el: '#app',
store, // 添加 store
computed: {
welcome() {
return this.$store.getters['welcome'];
},
username() {
return this.$store.getters['user/username'];
},
token() {
console.log(this.$store.state['user/username'])
console.log(this.$store.state.user.username)
return this.$store.getters['user/token'];
}
},
methods: {
// 回车/点击确认的回调事件
login(username) {
if (username) {
this.$store.commit('user/login', { username, token: 'sxgWKnLADfS8hUxbiMWyb' });
this.$store.commit('say', '登录成功,欢迎你回来!');
}
}
}
});
</script>
</body>
</html>
© 版权声明
THE END
暂无评论内容