我们日常网页中,登录总会需要的吧,那么登录后显示的自身图像logo+名称总会显示在页面右上角,表明我们正在登录状态中。
那么,便需要全局共享的变量来显示。
这里用vuex管理全局变量,其他定义全局变量的方法不是很常见。
我打算从看文档(开始 | Vuex (vuejs.org))开始,边看边测试,以及借用其他博主的力量,希望能把vuex学稳点。
唠唠嗑 vuex
官方解释:是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
我的感觉就是npm vuex之后,用它实例化创建一个仓库(store),然后在仓库里对数据进行管理,而且重点在于,它是全局且共享的(==在任何组件component都可以访问并且修改它),类似于单例模式;并且,最令人兴奋的一点是,它会在页面上响应式更新。
下载 vuex
ps:我用的开发工具为hbuilder,创建的是vue2项目。
npm install vuex@next --save
一开始美美的按照文档直接下载了最新版本(next可确保下载的是最新版本),但是这会出现版本冲突的问题。
vue和vuex版本对应问题_vuex和vue的版本关系-CSDN博客
vue3对应vuex4版本。
而vue2要对应vuex3版本。
npm install vuex@3 --save
ok,安装成功。
vuex 唠唠嗑项目结构
为了避免以后项目过大而导致store太大,还是推荐进行模块化store,也是说,每一个module都拥有自己的 state、mutation、action、getter。
这么说可能有点儿抽象,换句话说,当你创建一个购物平台项目的时候,你的后台数据库是咋样的,应该是很多个表吧,有管理用户登录注册的表,管理商品的表等等,那么,store也是一样的,它可以被分成很多个module,每个module分别管理不同表的数据状态。
但是呢,即使在不同的module中定义了各自的state、mutation、action、getter,如果你没有给它命名空间(类似给予它自己的名字给了它可以单独存在的空间),那么它们的mutation、action、getter还是全局的,只有state是局部的。我个人还是比较喜欢设置namespaced: true的,还是大家有点分界感,相互给自己独处的空间比较好,这样就意味着state、mutation、action、getter都是局部的。
ps:我用的开发工具为hbuilder,创建的是vue2项目。(再说明一次)
所以,我目前的项目结构是这样的:
好了,终于到激动人心的代码阶段了!
vuex - main.js
import Vue from 'vue'
import App from './App.vue'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import '@wangeditor/editor/dist/css/style.css'
//1-引入store文件
import store from './store'
Vue.config.productionTip = false
Vue.use(ElementUI);
//2-配置好store
new Vue({
store,
render: h => h(App),
}).$mount('#app')
vuex - store/index.js
这里我假设弄的是教育平台,有登录信息表以及课程信息表。
import Vue from 'vue'
import Vuex from 'vuex' //1-引入vuex
import Login from './modules/login.js'//登录信息表
import Lesson from './modules/lesson.js'//课程信息表
Vue.use(Vuex)//2-在vue中使用vuex
export default new Vuex.Store({
//3-在这里配置好整体仓库中的各个表
modules:{
Login,
Lesson
}
//这里可以创建全局信息表
state:{
name:'it\'s me'
}
...(省略getter\mutation\action哈)
})
vuex - store/modules
登录信息表 /login.js
export default {
namespaced: true, // 为当前模块开启独立的 命名空间
state: {
user:{
username: 'aaa',
password:'123456'
}
},
getters: {},
mutations: {
changeUser(state, user) {
console.log(user);
state.user = user;
}
},
actions: {
actChangeUser(context, user) {
console.log(user);
context.commit('changeUser', user);
}
}
}
课程信息表 /lesson.js
export default {
namespaced: true, // 为当前模块开启独立的 命名空间
state: {
Les:{
lname: '1',//课程名称
lcategory:'2'//课程所属科目
}
},
getters: {},
mutations: {
changeLes(state, les) {
console.log(les);
state.Les = les;
}
},
actions: {
actChangeLes(context, les) {
console.log(les);
context.commit('changeLes', les);
}
}
}
你可能会问,mutation是什么,action又是什么,目前为止,我是这样理解的,在mutation定义函数,然后在action中运行mutation函数更改state的值,而且还可以进行异步操作。
先这样简单理解,以后可能又会回来更改这个笔记。
找到一篇简洁的博主文章,说得很全面又详细。(前端 - 超详细!Vuex手把手教程 - 个人文章 - SegmentFault 思否)
vuex - 在component中使用store
获得数据
法1-获得store的数据 - $store.state.
<template>
<div>
<p>{{tip}} </p>//网页显示 这里会显示state数据的值哦。
<p>{{$store.state.name}} </p> //网页显示 it‘s me
<p>{{$store.state.Lesson.Les}} </p>//网页显示 {"lname":"1","lcategory":"2"}
<p @click="show">点击在控制台显示获取store数据<p>
</div>
</template>
<script>
export default{
data(){
return{
tip:'这里会显示state数据的值哦。'
}
},
methods:{
show(){
console.log(this.$store.state.name);
},
}
}
</script>
<style>
</style>
法2-获得store的数据 - 用mapState获得
<template>
<div>
<p>{{tip}} </p>//网页显示 这里会显示state数据的值哦。
<p>{{$store.state.name}} </p> //网页显示 it‘s me
<p>{{$store.state.Lesson.Les}} </p>//网页显示 {"lname":"1","lcategory":"2"}
<p>{{Les}}</p>//网页显示 {"lname":"1","lcategory":"2"}
</div>
</template>
<script>
//1-引入mapState映射
import { mapState } from 'vuex'
export default{
data(){
return{
tip:'这里会显示state数据的值哦。'
}
},
//2-在copmuted中使用mapState映射函数
computed: {
//mapState默认会把state当第一个参数传进来
...mapState({
Les:state=>state.Lesson.Les
})
},
}
</script>
<style>
</style>
修改数据
这里我目前比较喜欢组件直接调用,如果是在mutation里头,我就用commit;如果是actions里头,我就用dispatch。
<template>
<div>
<p>{{tip}} </p>//网页显示 这里会显示state数据的值哦。
<p>{{Les}}</p>//一开始,网页显示 {"lname":"1","lcategory":"2"}
//之后会根据我点击了哪个按钮而改变Les中的值
<p>test1--mutation-commit</p>
<button @click="editLesByMutation">改变</button>
<p>test1--action-dispatch</p>
<button @click="editLesByAction">改变</button>
</div>
</template>
<script>
//1-引入mapState映射
import { mapState } from 'vuex'
export default{
data(){
return{
tip:'这里会显示state数据的值哦。'
}
},
//2-在copmuted中使用mapState映射函数
computed: {
//mapState默认会把state当第一个参数传进来
...mapState({
Les:state=>state.Lesson.Les
})
},
methods:{
editLesByMutation(){
const Les={
lname:'hello',
lcategory:'我是由mutation修改的'
}
this.$store.commit('Lesson/changeLes',Les);//这里用透过路径进而可以访问到module中的mutation
},
editLesByAction(){
const Les={
lname:'hello',
lcategory:'我是由action修改的'
}
this.$store.dispatch('Lesson/actChangeLes',Les);//这里用透过路径进而可以访问到module中的action
},
},
}
</script>
<style>
</style>
好了,学习vuex就这样先告一段落了把,现在要去干点正事了,赶紧把需求完成。