1.Vuex初识
vuex是基于vue框架的一个状态管理库。可以管理复杂应用的数据状态,比如兄弟组件的通信、多层嵌套的组件的传值等等。vuex有这么几个核心概念——
State
、
Getter
、
Mutation
、
Action
、
Module
2.Store尝试
2.1 添加依赖
【 package.json 】:
"dependencies": {
"vue": "^2.5.2",
"vuex": "^3.4.0"
}
2.2 store
新建store文件夹底下的index.js
【 index.js 】:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
nickname:'李雪琴',
age:20,
gender:'女'
},
mutations: {},
actions: {},
modules: {}
})
export default store
2.3 main.js
index.html :主页,项目入口 App.vue:根组件 main.js:入口文件
在项目运行中,main.js作为项目的入口文件,运行中,找到其实例需要挂载的位置,即index.html中,刚开始,index.html的挂载点处的内容会被显示,但是随后就被实例中的组件中的模板中的内容所取代,所以我们会看到有那么一瞬间会显示出index.html中正文的内容。
main.js作用:实例化Vue;放置项目中经常会用到的插件和CSS样式。例如: 网络请求插件:
axios和vue-resource;
存储全局变量(基本信息)。
我看网上有人这样比喻main.js的作用:
main.js
是工会老大,你把奖励给了老大,老大有的道具会交给你使用,那么你就可以通过this来使用
【main.js】:
import store from './store'
import Utils from './util'
// main.js是工会老大,你把奖励给了老大,老大有的道具会交给你使用,那么你就可以通过this来使用
new Vue({
// el: '#app',
router,
store, //注册进全局
components: { App },
template: '<App/>'
}).$mount("#app")
2.4 mapState用法
第一种:
页面直接引用
<P>姓名:{{$store.state.nickname}} 性别:{{$store.state.gender}} 年龄:{{$store.state.age}}</
第二种:
computed
<P>姓名:{{nickname}} 性别:{{gender}} 年龄:{{age}}</P>
export default {
name: "ComponentC",
data() {
return {
msg: '这是组件'
}
},
computed: {//computed是不能传参数的
nickname(){return this.$store.state.nickname},
age(){return this.$store.state.age},
gender(){return this.$store.state.gender}
}
}
第三种:
mapState
<P>姓名:{{nickname}} 性别:{{gender}} 年龄:{{age}}</P>
import {mapState} from "vuex"
export default {
name: "ComponentC",
data() {
return {
msg: '这是组件C'
}
},
computed: {//computed是不能传参数的
...mapState([
'nickname', 'age', 'gender' // 映射哪些字段就填入哪些字段
])
}
第四种:
mapState
<P>姓名:{{nickname}} 性别:{{gender}} 年龄:{{age}}</P>
import {mapState} from "vuex"
export default {
name: "ComponentC",
data() {
return {
msg: '这是组件C'
}
},
computed: {//computed是不能传参数的
...mapState({
//使用箭头函数
age: state=>state.age+100,
//传入字符串 ‘nickname’ 等同于 `nickname => state.nickname`
nickname:'nickname',
// 为了能够使用 `this` 获取局部状态,必须使用常规函数
gender(state) {
return state.gender
}
])
}
2.5 mapGetters用法
getters:{
objGet(state) {
return {
nickname: state.nickname,
age: state.age+20,
gender: state.gender
}
}
}
组件引用:
<P>{{objGet}}</P>
import {mapGetters} from "vuex"
computed: {
...mapGetters([
'objGet' // 把vuex 中的 getters 筛选返回数据的方法加进来,{{objGet}}使用
])
}
注意:
如果你的值是需要加工的,那么用getter;反之直接通过 state 取值,只需要源值就用 mapState。
2.6 mutations用法
mutations: {
//类似于methods,调用的时候第二个参数最好写成对象形式,这样我们就可以传递更多信息
nameTest(state, name) {
state.nickname = name;
state.age+=10
},
commitTest(state, payload) {
alert(payload.number)
state.age = payload.number;
}
}
组件引用:
import {mapMutations} from "vuex"
methods: {
...mapMutations([
"nameTest" // 把 vuex 方法加进来,然后 this.nameTest(params) 就可以用
]),
tt() {
this.nameTest("女_update_update")
},
tt1(){
//commit 提交变化,修改数据的唯一方式就是显式的提交 mutations
this.$store.commit('commitTest',{
number:5
})
}
}
2.7 mapAction用法
actions: {
increment1({commit,state},number){
//提交一个名为 increment 的变化,名字可自定义,可以认为是类型名,与下方 mutations 中的 increment 对应
//commit 提交变化,修改数据的唯一方式就是显式的提交 mutations
alert(number)
},
increment({commit,state}){
//提交一个名为 increment 的变化,名字可自定义,可以认为是类型名,与下方 mutations 中的 increment 对应
//commit 提交变化,修改数据的唯一方式就是显式的提交 mutations
commit('nameTest',"commit")
},
dispatchTest({commit,state},name){
//提交一个名为 increment 的变化,名字可自定义,可以认为是类型名,与下方 mutations 中的 increment 对应
//commit 提交变化,修改数据的唯一方式就是显式的提交 mutations
state.nickname = name
},
dispatchTest1(context){//官方给出的指定对象, 此处context可以理解为store对象
debugger
}
}
组件引用:
<P>mapAction↓</P>
<button @click="increment">尝试mapMutations_1</button>
<button @click="increment1(696)">尝试mapMutations_2</button>
<button @click="tt5()">尝试mapAction_dispatch</button>
<button @click="tt6()">尝试mapAction_context</button>
import {mapActions} from "vuex"
methods: {
tt5(){
//打印res,结果打印出Promise,这表明,在actions中的方法,默认就是异步的,通过then获取数据
var res = this.$store.dispatch('dispatchTest',"haha")
console.log(res)
},
tt6(){
//打印res,结果打印出Promise,这表明,在actions中的方法,默认就是异步的,通过then获取数据
this.$store.dispatch('dispatchTest1')
},
...mapActions([
//该 increment 来自 store.js 中导出的 actions 和 mutations 中的 increment
'increment','increment1'
])
}
通过
2.6
和
2.7
可以得出:
*****
action
也有一个固有参数 context,但是 context 是 state 的父级,包含 state、getters
action
可以提交mutation(通过commit)
action
也不要直接去操作state,而是去操作mutation
action
包含异步操作,类似于axios请求,可以都放在action中写
action
中的方法默认的就是异步,并且返回promise
*****
mutations
有一个固有参数 state,接收的是 Vuex 中的 state 对象
mutations
只能写同步方法,不能写异步,比如axios、setTimeout等,这些都不能写,mutations的主要作用就是为了修改state的
3.数据丢失处理
因为store里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载vue实例,store里面的数据就会被重新赋值初始化
解决思路:
将state的数据保存在localstorage、sessionstorage或cookie中(
三者的区别
),这样即可保证页面刷新数据不丢失且易于读取。
- localStorage: localStorage的生命周期是永久的,关闭页面或浏览器之后localStorage中的数据也不会消失。localStorage除非主动删除数据,否则数据永远不会消失。
- sessionStorage:sessionStorage的生命周期是在仅在当前会话下有效。sessionStorage引入了一个“浏览器窗口”的概念,sessionStorage是在同源的窗口中始终存在的数据。只要这个浏览器窗口没有关闭,即使刷新页面或者进入同源另一个页面,数据依然存在。但是sessionStorage在关闭了浏览器窗口后就会被销毁。同时独立的打开同一个窗口同一个页面,sessionStorage也是不一样的。
- cookie:cookie生命期为只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。 存放数据大小为4K左右,有个数限制(各浏览器不同),一般不能超过20个。缺点是不能储存大数据且不易读取。