目录
git:https://gitee.com/cxy-xupeng/vue-vuex.git
一、什么是Vuex
Vuex是一个状态管理的工具。当一个组件被多个其他组件调用,而这个组件的状态到底是什么,这需要被管理吧(有点并发内味),vuex就用来管理这个状态,并且可以是响应式。
二、安装谷歌插件
先来说一下理想的步骤:
1.点击谷歌浏览器右上角的三个点号:(不会吧不会吧,不会真的有人用的不是谷歌浏览器吧?如果不是,可以使用火狐)
2.选择“更多工具”,选择“扩展程序”
3.点击左上角“扩展程序”
4.点击左下角打开Chrome网上应用商店。然后如果你能打开的话,查找Vue.js devtools进行下载(当然我没打得开。。。)
上面我愿称之为:皇帝的商店。因为根本就打不开。
下面讲解我是怎么安装的:
1.百度搜索:极简谷歌插件
2.下载vue插件
3.下载完之后是一个压缩包,解压这个压缩包
4.打开谷歌浏览器,右上角三个点,选择“更多工具”,选择“扩展程序”。在这个页面把我们上一步的CRX文件往浏览器里拖动就行。安装好后就行了
三、Vuex的基本使用
1.创建项目
此处是否需要router的?大家可以选择N
我们适当修改首页,删除helloworld,再把main.js里面关于router的删除,查看结果:
2.安装vuex
npm install vuex --save
3.目录
4.index.js中写了vuex的插件,其中state表示全局状态,mutations表示方法
import Vue from 'vue'
import Vuex from 'vuex'
//1.安装插件
Vue.use(Vuex)
//2.创建对象
const store = new Vuex.Store({
state:{//状态
count:1000
},
mutations:{//方法
increment(state){
state.count++;
},
decrement(state){
state.count--;
},
},
actions:{
},
getters:{
},
modules:{
}
})
//3.导出store对象
export default store
5.HelloVuex.vue父传子的方法使用属性,只是父里面也是用了全局的state
<template>
<div>
{
{$store.state.count}}
</div>
</template>
<script>
export default{
name:'HelloVuex',
props:{
count:Number
}
}
</script>
<style>
</style>
6.main.js:引入store
import Vue from 'vue'
import App from './App'
import store from './store/index.js'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
store,
render: h => h(App)
})
7.App.vue:使用属性的方法
<template>
<div id="app">
<h2>{
{message}}</h2>
<h2>{
{counter}}</h2>
<h2>{
{$store.state.count}}</h2>
<button @click="addition">+</button>
<button @click="substraction">-</button>
<hello-vuex :count="counter"></hello-vuex>
</div>
</template>
<script>
import HelloVuex from './components/HelloVuex.vue'
export default {
name: 'App',
data(){
return{
message:'徐鹏',
counter:0
}
},
components:{
HelloVuex
},
methods:{
addition(){
this.$store.commit('increment')
},
substraction(){
this.$store.commit('decrement')
}
}
}
</script>
<style>
</style>
8.查看结果:
四、Vuex的核心概念
1.State
- 单一状态树:我们vuex插件创建的对象,只创建一个,不要创建多个
- 一开始放到state里面的数据,都会被响应式监听。当属性变化,会通知所有用到该属性的页面。但是未定义的属性,不会响应式
2.Getters
- 对属性值有计算的,放在这里处理
3.Mutation
- vue的store状态更新的唯一方式:提交Mutation
- Mutation主要包括两部分:字符串的事件类型(type)+回调函数(handler)(第一个参数为state)
- Mutation更新:需要commit
- 通过type提交:在store里面,传参就是payload,其中payload包含你需要的参数
- 如果想要state里没定义的属性也能响应式,Vue.set()方法可以实现增加属性。Vue.delete()删除属性
- index.js和App.vue里面方法名其实一样,我们可以抽取常量
- Mutation中的方法必须是同步方法,不然devtools将不好跟踪
4.Action
- 因为Mutation不使用异步方法,对于异步方法,我们在action中使用
5.Module
- 因为state使用单一状态树,但是后面会很臃肿。因此可以将store分割成多个模块
四、对象的结构
//对象的结构
const obj = {
name:'aa',
age:11,
height:1.8
}
const {name,age} = obj
五、vuex的实例
HelloVuex.vue
<template>
<div>
{
{$store.state.count}}
</div>
</template>
<script>
export default{
name:'HelloVuex',
props:{
count:Number
}
}
</script>
<style>
</style>
mutationstype.js
export const INCREMENT = 'increment'
main.js
import Vue from 'vue'
import App from './App'
import store from './store/index.js'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
store,
render: h => h(App)
})
App.vue
<template>
<div id="app">
<h2>{
{message}}</h2>
<h2>{
{counter}}</h2>
<h2>HelloVuex的值:<hello-vuex :count="counter"></hello-vuex></h2>
<h2>-----------vuex的state----------------</h2>
<h2>{
{$store.state.count}}</h2>
<h2>-----------vuex的getters----------------</h2>
<h2>count的平方:{
{$store.getters.powerCounter}}</h2>
<h2>年龄大于等于20的学生:{
{$store.getters.more20stu}}</h2>
<h2>年龄大于等于20的学生数量:{
{$store.getters.more20stucount}}</h2>
<h2>年龄大于指定数字的学生:{
{$store.getters.moreAgeStu(5)}}</h2>
<h2>-----------vuex的mutations----------------</h2>
<button @click="addition">+</button>
<button @click="substraction">-</button>
<button @click="addCount(5)">+5</button>
<button @click="addCount(10)">+10</button>
<button @click="addStudent">添加学生</button>
<button @click="updateStudent">响应式修改学生</button>
<h2>-----------vuex的modules----------------</h2>
<h2>{
{$store.state.a.name}}</h2>
<button @click="updateName">修改名字</button>
<h2>{
{$store.getters.fullname}}</h2>
<h2>{
{$store.getters.fullname2}}</h2>
<h2>{
{$store.getters.fullname3}}</h2>
<button @click="asyncUpdateName">异步修改名字</button>
</div>
</template>
<script>
import HelloVuex from './components/HelloVuex.vue'
import {INCREMENT} from './store/mutationstype.js'
export default {
name: 'App',
data(){
return{
message:'徐鹏',
counter:0
}
},
components:{
HelloVuex
},
methods:{
//1.普通提交封装
addition(){
this.$store.commit(INCREMENT)
},
substraction(){
this.$store.commit('decrement')
},
// addCount(count){
// this.$store.commit('incrementCount',count)
// },
//2.特殊的提交封装
addCount(count){
this.$store.commit({
type:'incrementCount',
count
})
},
addStudent(){
const stu = {id:4,name:'ddd',age:40}
this.$store.commit('addStudent',stu)
},
updateStudent(){
// this.$store.commit('updateStudent')
this.$store.dispatch('aUpdateStudent','我是payload')
},
updateName(){
this.$store.commit('updateName','李四')
},
asyncUpdateName(){
this.$store.dispatch('aaUpdateStudent')
}
}
}
</script>
<style>
</style>
index.js
import Vue from 'vue'
import Vuex from 'vuex'
import {INCREMENT} from './mutationstype.js'
//1.安装插件
Vue.use(Vuex)
//2.创建对象
const moduleA = {
state:{
name:'张三'
},
mutations:{
updateName(state,payload){
state.name = payload
}
},
actions:{
aaUpdateStudent(context){
console.log(context.rootGetters)
setTimeout(()=>{
context.commit('updateName','王五')
},1000)
}
},
getters:{
fullname(state){
return state.name+'111'
},
fullname2(state,getters){
return getters.fullname+'222'
},
fullname3(state,getters,rootState){
return getters.fullname2+rootState.count
}
}
}
const store = new Vuex.Store({
state:{//状态
count:1000,
students:[
{id:1,name:'aaa',age:10},
{id:2,name:'bbb',age:20},
{id:3,name:'ccc',age:30},
]
},
mutations:{//方法
[INCREMENT](state){
state.count++;
},
decrement(state){
state.count--;
},
//type提交风格
incrementCount(state,payload){
state.count += payload.count;
},
addStudent(state,stu){
state.students.push(stu)
},
updateStudent(state){
//响应式增加state里面没有的属性
Vue.set(state.students[0],'address','上海')
//响应式删除state的属性
Vue.delete(state.students[1],'name')
}
},
actions:{
//context:上下文
aUpdateStudent(context,payload){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
context.commit('updateStudent')
console.log(context)
resolve('111')
},1000)
}).then(res=>{
console.log('完成提交')
console.log(res)
})
}
},
getters:{//变化状态的值
powerCounter(state){
return state.count * state.count
},
more20stu(state){
return state.students.filter(s=>s.age>=20)
},
more20stucount(state,getters){
return getters.more20stu.length
},
//自己传参
moreAgeStu(state){
return function(age){
return state.students.filter(s=>s.age>=age)
}
}
},
modules:{//模块
a:moduleA,
b:{
state:{},
mutations:{},
actions:{},
getters:{}
},
}
})
//3.导出store对象
export default store
五、项目结构
我们之前是吧所有的代码都写在一个文件里,太乱,需要一个合理的结构:
我们把之前的都抽出来。
具体代码可以通过git自行查看