vuex的使用
Vuex的快速入门快速开始_安装依赖"vuex": "3.6.0"在store下添加index.js,然后再main.js引入store/index.jsimport Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)const store = new Vuex.Store({// 定义共享变量,所有页面都可以访问到,类似于datastate: {
Vuex的快速入门
快速开始_
安装依赖
"vuex": "3.6.0"
在store下添加index.js,然后再main.js引入
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
// 定义共享变量,所有页面都可以访问到,类似于data
state: {
},
// 定义同步方法
mutations: {
},
// 定义异步方法
actions: {},
// 计算属性,可以过滤;返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算
getters: {
},
// 模块化
modules: {}
})
export default store
main.js
import Vue from 'vue'
import App from './App.vue'
import store from './store/index'
new Vue({
store,
render: h => h(App),
}).$mount('#app')
state
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
name: '张三',
age: 18,
}
})
export default store
取值方式一
子组件通过 this.$store.state
获取
<template>
<div>
<!--直接通过this.$store.state获取变量 -->
{{ this.$store.state.name }}
</div>
</template>
<script>
export default {
mounted() {
//在js中直接通过this.$store.state.name获取
console.log(this.$store.state.name)
},
}
</script>
取值方式二
当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState
辅助函数帮助我们生成计算属性,让你少按几次键:
<template>
<div>
<!--通过mapState辅助函数获取-->
{{ age }}
</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
computed: {
...mapState(['age'])
},
}
</script>
getter
有时候我们需要从 store 中的 state 中派生出一些状态,例如对列表数据进行过滤,对名字进行二次加工等。
如果有多个组件需要用到此属性,我们要么复制这个函数,或者抽取到一个共享函数然后在多处导入它——无论哪种方式都不是很理想。
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
name: '张三',
list: [1, 2, 3, 4, 5, 6, 7, 8, 9]
},
getters: {
addHello(state) {
return state.name + " 你好";
},
filter8(state) {
return state.list.filter(item => item !== 8)
}
},
})
export default store
展示
<!--方式一-->
<template>
<div>
{{ this.$store.getters.addHello }}
{{ this.$store.getters.filter8 }}
</div>
</template>
<script>
export default {}
</script>
<!--方式二mapGetters 辅助函数-->
<template>
<div>
<!-- 名字二次加工-->
{{ addHello }}
<!-- 对数据进行过滤-->
{{filter8}}
</div>
</template>
<script>
import {mapGetters, mapState} from 'vuex'
export default {
computed: {
...mapGetters(['addHello','filter8'])
},
}
</script>
mutations
-
mutation是更改store 中的状态的唯一方法
-
mutation 必须是同步函数
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
age: 18,
},
mutations: {
//无参方法,调用
addAge(state) {
state.age += 5
}
},
})
export default store
展示
方式一
<template>
<div>
{{this.$store.state.age}} <br/>
<el-button @click="addAge1">无参点击+5</el-button>
<el-button @click="addAge2">有参点击+n</el-button>
</div>
</template>
<script>
export default {
methods: {
addAge1() {
this.$store.commit('addAge')
},
addAge2() {
this.$store.commit('addAgeN',2)
}
}
}
</script>
方式二
<template>
<div>
{{ this.$store.state.age }} <br/>
<el-button @click="addAge">无参点击+5</el-button>
<el-button @click="addAgeN(2)">有参点击+n</el-button>
</div>
</template>
<script>
import {mapMutations} from 'vuex'
export default {
methods: {
...mapMutations(['addAge', 'addAgeN'])
}
}
</script>
actions
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
age: 18,
},
mutations: {
//无参方法
addAge(state) {
state.age += 5
},
//有参方法
addAgeN(state, n) {
state.age += n
}
},
actions: {
addAge(context) {
context.commit('addAge')
},
addAgeN(context, n) {
context.commit('addAgeN', n)
},
//定义一个异步方法,3s过后才调用addAge(mutations)方法
addAgeAsync({commit}) {
setTimeout(() => {
commit('addAge')
}, 3000)
},
addAgeNAsync({commit}, n) {
setTimeout(() => {
commit('addAgeN', n)
}, 3000)
},
addAgeNAsync2(context, n) {
setTimeout(() => {
context.commit('addAgeN', n)
}, 3000)
}
},
})
export default store
展示
<template>
<div>
{{ this.$store.state.age }} <br/>
<span> 方法1</span>
<el-button @click="addAge1">无参点击+5</el-button>
<el-button @click="addAge2">有参点击+n</el-button>
<span>方法2</span>
<el-button @click="addAge">无参点击+5</el-button>
<el-button @click="addAgeN(2)">有参点击+n</el-button>
<el-button @click="addAgeAsync()">异步(3s后执行)无参方法+5</el-button>
<el-button @click="addAgeNAsync(10)">异步(3s后执行)有参方法+10</el-button>
</div>
</template>
<script>
import {mapActions} from 'vuex'
export default {
methods: {
//方法1
addAge1() {
this.$store.dispatch('addAge')
},
addAge2() {
this.$store.dispatch('addAgeN', 2)
},
//方法2
...mapActions(['addAge', 'addAgeN', 'addAgeAsync', 'addAgeNAsync'])
}
}
</script>
modules
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import app from './modules/app'
import getters from './getters'
Vue.use(Vuex)
const store = new Vuex.Store({
// 模块化
modules: {
app,
},
getters
})
export default store
store/modules/app.js
//定义变量
const state = {
app: 'app'
}
//定义同步方法,唯一更改state的地方
const mutations = {}
//定义异步方法
const actions = {}
export default {
state,
mutations,
actions
}
例子
<template>
<div>
<!--直接通过state获取变量 -->
{{ this.$store.state.app.name }}
{{ this.$store.state.app.age }}
<el-button @click="addAge1">调用方式一+5</el-button>
<el-button @click="addAge">调用方式二+5</el-button>
</div>
</template>
<script>
import { mapMutations} from 'vuex'
export default {
name: "vuex",
methods: {
addAge1() {
this.$store.commit('addAge')
},
...mapMutations(['addAge'])
}
}
</script>
命名空间
例子
const state = {
name: '张三',
age: 18
}
const mutations = {
addAge(state) {
state.age += 5
},
}
const actions = {}
export default {
//名字空间,防止不同模块方法名和变量名重复,后面访问变量方法都是带上模块前缀;如:this.$store.state.app.name 会加上app
namespaced: true,
state,
mutations,
actions
}
import Vue from 'vue'
import Vuex from 'vuex'
import app from './modules/app'
import getters from './getters'
Vue.use(Vuex)
const store = new Vuex.Store({
// 模块化
modules: {
app, //如:this.$store.state.app.name 会加上app,是这个app
},
getters
})
export default store
------来自 NPException对我的爱,我是爱乱写的嵩鼠
更多推荐
所有评论(0)