First of all, you need to consider why you are on vuex
This is also a small problem I encountered during the development process. If there are multiple nested components like the following , it will be too cumbersome to use props
and:data="data"
And according to the official document,props
the data is one-way, and $emit('xxx')
it is very troublesome to change the data usage
demo
Directory Structure
prerequisite preparation
Vuex installation sure
store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
var store = new Vuex.Store({
state:{
// 类似于xxx.vue的data()
data: 'this is test'
},
getters:{
// 类似于xxx.vue的filters
fdata(state){
return state.data.toUpperCase()
}
},
mutations:{
// 类似于xxx.vue的methods
change(state){
state.data = 'change'
},
// 作为方法接受参数
replaceStr(state,str){
state.data = str
}
},
actions:{
// 需要和mutations配套使用
// 根据官方文档,这个是**可以异步的**
// mutations只支持**同步**
test(context){
context.commit('change')// 仅保留实例,实际上自己没有怎么用
}
}
})
export default store
main.js
import Vue from 'vue'
import App from './App.vue'
// 引入store.js
import store from './store'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
store
}).$mount('#app')
The simplest usage
app.vue
<template>
<div id="app">
<h1>app.vue</h1>
<p>state: {
{$store.state.data}}</p>
<p>getters: {
{$store.getters.fdata}}</p>
<div>
<p>mutations:</p>
<button @click="$store.commit('change')">change</button>
</div>
<div>
<p>mutations:方法</p>
<button @click="$store.commit('replaceStr','hahahah')">change</button>
</div>
<div>
<p>actions</p>
<button @click="$store.dispatch('test')">change</button>
</div>
</div>
</template>
<script>
export default {
name: 'app'
}
</script>
result
- initial
- click mutations
- Click mutations: method
- Click actions
this.$store
It can also be called in the methods of export default, etc.
Advanced usage
In fact, the simple usage above is the most stupid and troublesome
app.vue
<template>
<div id="app">
<h1>app.vue</h1>
<p>state: {
{data}}</p>
<comp-a/>
</div>
</template>
<script>
import {
mapState} from 'vuex'
import compA from './components/compA'
export default {
name: 'app',
computed:mapState({
data:'data'
}),
components:{
compA
}
}
</script>
compA.vue
<template>
<div class="comp-a">
<h2>comp-a</h2>
<p>state: {
{data}}</p>
<button @click="change">change</button>
</div>
</template>
<script>
import {
mapState,mapMutations} from 'vuex'
export default {
computed:mapState({
data:'data'
}),
methods:mapMutations({
change: 'change'
})
};
</script>
<style>
.comp-a{
border: 1px solid black;
}
</style>
About {mapState, mapMutations}
result
- initial
- click change
some explanation
about{mapState,mapMutations}
a1
This is to convert the state and mutations in the store into its own methods or values
For example, mapState
there are three types of state acquisition:
import {
mapState } from 'vuex'
export default {
// ...
computed: mapState({
// 箭头函数可使代码更简练
data: state => state.data,
// 传字符串参数 'count' 等同于 `state => state.count`
data: 'data',
// 为了能够使用 `this` 获取局部状态,必须使用常规函数
countPlusLocalState (state) {
return state.data + this.data
}
})
}
But the most commonly used is
computed: mapState(['data','example2'])
Even computed
with multiple
computed: {
...mapState(['data','example2']),
dd: ()=> 'dd'
}
About ...
operators
This is the deconstruction symbol of es6, which is similar to that {}
, and the method of use is very simple. The following uses chrome's DevTools to expand directly
- data deconstruction
- object deconstruction
in conclusion
Vuex is really convenient to manage global data and state, much more convenient $emit
than this:data="data"