vuex 基础知识
1.vuex相关
vuex是数组之间传值共享的方案,方便组件传值。【方便】
可以怎么用?
把使用的多的值集中起来,用的时候直接调就行。vuex都是响应式的,还能实时保持数据在各个页面上的同步。
Vuex的使用
1.安装vuex依赖包(讲道理大家都是脚手架 略)
npm install vuex --save
2.导入vuex包(放store.js里 略)
store.js文件我们是自己可以创建的哈,有的人的代码习惯就是。登录注册一个文件、其他的模块再创建一个文件.... 文件名可以自己定义的不一定非要store啥的。可以建一个文件夹,将他们统一管理起来,方便以后自己找到。
import vuex from 'vuex'
vue.use(vuex)
3.创建store对象(放store.js里 略)
const store =new vuex.store({
//state中存放的就是全局共享的数据
state:{count:0}
})
4.因为我们创建的出来的store这个对象跟vue实例还没有关联(连线),所以我们还要将这个store实例对象挂载到vue实例中(放main.js里 略)
new Vue({
el:'#app',
render:h=>h(app),
router,
//将创建的共享数据对象,挂载到vue实例中 (放main.js里)
//所有的组件,就可以直接从store中获取全局数据了
store
})
vuex的核心概念
vuex中的主要核心概念如下:
State // Mutations // Action // Getter
const store =new Vuex.store({
state:{},
mutations:{},
action:{},
getter:{},
})
state--------------------------------------------------------------------------------------------------------------------------
state提供唯一的公共数据源,所有共享的数据都要统一放在Store的state中进行存储
为什么需要state?
因为作为vuex作为一个数据的继承器,我们需要一个保存数据的地方。
//创建store数据源 ,提供唯一的公共数据(代码位置/在store.js里)
const store =new Vuex.store({
state:{
count:0
}
})
组件访问State中数据的第一种方式
this.$store.state 全局数据名称
(注:在template内this是可以省略去的)
(注:在script内this是必须要的 )
组件访问State中的数据的第二种方式
//从vuex中按需导入mapState函数
import { mapState} from 'vuex'
通过导入mapstate函数 ,将当前组件需要的全局数据,映射为当前组件的computed计算属性
//将全局数据,映射为当前组件的计算属性
computed:{
...mapState(['count'])
}
(以下为作者写的第二种方法代码,为了避免混乱,仅供参考。)
Mutations------------------------------------------------------------------------------------------------------------------
Mutations用于变更Store中的数据
1.只能通过mutations变更Store中的数据,不可以直接操作Store中的数据(规定!)
2.通过这种方式虽然操作起来稍微繁琐一些,但是可以集中监控所有数据的变化(因为mutations是写在store里面的,而不是写在每个实例中的。方便我们集中管理,要使用的话不用到处找了)
以下为mutations的使用
为什么需要Mutations?
因为如果将所有的方法都分散到每个细分组件中的话,这样不方便统一的管理。所以我们将数据集成到了vuex中,这个为以后的代码维护减轻了不少负担。减低了代码的阅读难度。
在组件中调用Mutation的第一种方式
Mutations如何使用?(举例,我们需要做一个点击按钮,自动++的操作)
this.$store.commit()
组件中可以使用 this.$store.commit()来调用add这个函数
<template> //组件文件
<div>
<p>这是一个加法的组件{{ $store.state.count }}</p>
<button @click="addcount">+1</button>
</div>
</template>
<script>
export default {
data() {
return {
// count: 0,
}
},
methods: {
addcount() {
//触发mutations的一种方法
this.count = this.$store.commit('add')
},
},
}
</script>
<style lang="less" scoped></style>
import Vue from 'vue' //store文件
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 10000,
},
mutations: {
add(state) {
//变更状态 在这里像是封装了一个方法
state.count++
},
},
actions: {},
modules: {},
})
【注意:this.$store.commit(state,step)中是可以有两个参数的】
参1:state中的数据调用 参2:更改/变化的数据 参考以下实例
<template> //组件代码
<div>
<p>这是一个加法的组件{{ $store.state.count }}</p>
<button @click="addcount2">+n</button>
</div>
</template>
<script>
export default {
data() {
return {
// count: 0,
}
},
methods: {
addcount2() {
this.count = this.$store.commit('addN', 3)
},
},
}
</script>
<style lang="less" scoped></style>
import Vue from 'vue' //store中的代码
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 10000,
},
mutations: {
addN(state, step) { //两个参数的应用
state.count += step
}
},
actions: {},
modules: {},
})
在组件中调用Mutation的第二种方式
1.通过导入mapMutations函数,将需要的mutations函数,映射为当前组件的methods方法
//1.从vuex中按需导入mapMatations函数
import {mapMatations} from vuex
通过刚才导入的mapMutations函数,将需要的mutations函数,映射我当前组件的methods方法
2.将指定的mapMutations函数,将需要的mutations函数,映射为当前组件的methods方法
//2.将指定的mutations函数,映射为当前的组件的methods函数
methods:{
...mapMutations(['add','addN'])
}
以下作为参考 (点击按钮,页面上的数字呈现减减)
<template> //组件文件
<div>
<p>这个是一个减法的组件{{ count }}</p>
<button @click="subcount">-1</button>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex' //这里引入mapMutations
export default {
data() {
return {}
},
computed: {
...mapState(['count']),
},
methods: {
...mapMutations(['sub']), //这里进行Mutations的引入
subcount() {
this.sub()
},
},
}
</script>
<style lang="less" scoped></style>
import Vue from 'vue' //store里面的文件
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 10000,
},
mutations: {
sub(state) { //写入方法
state.count--
}
},
actions: {},
modules: {},
})
第二种方法也可以传两个参数吗?(当然可以)
<template> //组件文件
<div>
<p>这个是一个减法的组件{{ count }}</p>
<button @click="subcount1">-n</button>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
data() {
return {}
},
computed: {
...mapState(['count']),
},
methods: {
...mapMutations(['subN']), //这边进入Mutations引入
subcount1() {
this.subN(3) //里面的3 就相当于的第二个数值的
},
},
}
</script>
<style lang="less" scoped></style>
import Vue from 'vue' //store中的文件
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 10000,
},
mutations: {
subN(state,step) { //这里设置好两个参数
state.count-=step
},
},
actions: {},
modules: {},
})
Actions----------------------------------------------------------------------------------------------------------------------
为什么需要Actions?
因为我们在写方法的时候一定会使用到异步,而我们的Mutations不能使用异步做出处理。我们特别的独立出来Actions区域,细节知识点是,Actiions还是要通过触发Mutation的方式间接的变更数据的。(因为只有mutations才有权利修改state中的数据)
//定义Actions
const store = new Vuex.store({ //store文件
//...省略其他的代码
mutations:{
add(state){
state.count++ //假设我们写一个++的方法
}
},
actions:{ //我们这里设置一个形参 context 接收之后在下面引用
addAsync(context){ //这里做了一个1秒中触发一下的异步操作
setTimeout(()=>{
context.commit('add') //我们只能通过commit触发mutations
},1000)
}
}
})
怎么调用actions呢?
触发actions的第一种方法
//触发Action
methods:{
handle(){
//触发actions的第一种方式
this.$store.dispatch('addAsync') //dispatch的使用
}
}
触发actions异步任务时候 如何接待参数
actions使用两个参数 会有什么样的效果呢?
<template> //组件代码
<div>
<p>这个是一个减法的组件{{ count }}</p>
<button @click="subcount">-1 Async</button>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
data() {
return {}
},
computed: {
...mapState(['count']),
},
methods: {
...mapMutations(['sub']),
subcount() {
this.$store.dispatch('subAsync', 5) //第三步:向store的Actions中传入两个参数
},
},
}
</script>
<style lang="less" scoped></style>
import Vue from 'vue' //store文件
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 10000,
},
mutations: {
sub(state,step) { //第一步:还是使用mutations包裹一个方法
state.count-=step
},
},
actions: {
subAsync(context,step) { //第二步:在使用subAsync的方法包裹 mutations内的方法
setTimeout(() => {
context.commit('sub',step) //我们通过commit触发或者说引用mutations
},1000)
}
},
modules: {},
})
触发actions的第二种方法?
this.$store.dispatch()是触发actions的第一种方法,以下为触发actions的第二种方法
//1.从vuex中按需导入mapActions函数 组件文件
import {mapActions} from 'vuex'
通过刚才导入的mapActions函数,将需要的actions函数,映射为当前组件的methods方法
//2.将指定的actions函数,映射为当前组件的methods函数 组件文件
methods:{
...mapActions({'addAsync','addNASync'})
}
Getter------------------------------------------------------------------------------------------------------------------------
Getter用于对Store中的数据进行加工处理形成的新的数据,Getter不会修改Store中的原来数据,只会起到包装数据的作用。
1.store中的数据发生变化,Getter的数据也会跟着发生变化
2.Getter可以对Store中已有数据加工处理之后形成新的数据,类似vue的计算属性
//定义Getter
const store = new Vuex.Store({
state:{
count:0
},
getters:{
showNum:state=>{
return '当前最小的数量是【'+state.count+'】'
}
}
})
那么我们怎么在组件中引用Getter中的数据呢?
第一种方法
<h1>{{ $store.getters.名称 }}</h1>
第二种方法
import (mapGetters) from 'vuex'
computed:{
...mapGetters(['showNum']) //这里直接引入组件文件 然后直接调用就可以的
}
-------------------------------------------------------------------------------------
关于vuex模块化开发
前端程序员随着项目的越做越大 vuex也会需要模块式开发 以此来清晰代码,将整个项目组成变得更容易维护
第一步:在store文件夹下面创建各个模块的小文件夹
(如图 我创建了home 和 search两个文件夹)
第二步:在刚刚创建的文件夹下面 各创建一个index.js文件
第三步:例子 在home文件夹下的index.js文件中编写
//home模块的小仓库
const state = {};
const mutations = {};
const actions = {};
const getters = {};
export default{ //对外暴露
state,
actions,
mutations,
getters,
}
第四步:在store文件夹下面的index.js文件下编写(主vuex文件下)
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
//引入小仓库
import home from './home';
import search from "./search";
export default new Vuex.Store({
state: {},
mutations: {},
actions: {},
//使用modules对象 来注册home search中的小模块
modules: {
home,
search
},
});
结束。。
现在我们可以在小模块中填值 测试
比如我们在 search文件夹下面的index.js文件中 赋值a:1
项目页面 ----打开资源管理器----打开vue----点开vuex-----在这里可以看到各个小模块的数据