vuex

求和案例

vue 版本

main.js
App.vue
Count.vue

import Vue from "vue";
import App from './App.vue'

import VueResource from "vue-resource";

Vue.use(VueResource)

new Vue({
    render: h => h(App),
    beforeCreate() {
        Vue.prototype.$bus = this
    }
}).$mount('#app')

<template>
  <div>
    <Count />
  </div>
</template> 

<script>
import Count from "./components/Count.vue";

export default {
  name: "App",
  components: { Count }
};
</script>

<style>
.container,
.foot {
  display: flex;
  justify-content: space-around;
}
video {
  width: 100%;
}
</style>

<template>
  <div>
    <h4>当前求和为:{{ count }}</h4>
    <select v-model.number="selectNum">
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
    </select>
    <button @click="increment">+</button>&nbsp;
    <button @click="decrement">-</button>&nbsp;
    <button @click="incrementIfOdd">当前为奇数再加</button>&nbsp;
    <button @click="incrementAsync">异步加</button>&nbsp;
  </div>
</template>

<script>
export default {
  name: "Count",
  data() {
    return {
      count: 0,
      selectNum: 1
    };
  },
  methods: {
    increment() {
        this.count += this.selectNum
    },
    decrement() {
        this.count -= this.selectNum
    },
    incrementIfOdd() {
        if (this.count % 2 !== 0) {
            this.count+= this.selectNum
        }
    },
    incrementAsync() {
        setTimeout(() => {
            this.count+= this.selectNum
        }, 1000);
    },
  },
};
</script>

<style>
</style>

vuex 基础版本

  • store

    • actions 响应组件动作,可以用 dispatch 分发
    • mutations 直接操作数据,可以commit 直接操作
    • state 存储数据

main.js
store/index.js
App.vue
Count.vue

import Vue from "vue";
import App from './App.vue'

import store from './store'

new Vue({
    render: h => h(App),
    store,
}).$mount('#app')

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

// 创建store

// 响应组件动作
const actions = {
    increment(context, value) {
        // console.log('in');
        context.commit('INCREMENT', value)
    },
    decrement(context, value) {
        context.commit('DECREMENT', value)
    },
    incrementIfOdd(context, value) { 
        if (value %2 !== 0) {
            context.commit('INCREMENT', value)
        }
    },
    incrementAsync(context, value) {
        setTimeout(() => {
            context.commit('INCREMENT', value)
        }, 500);
    }
}

// 用于操作数据
const mutations = {
    INCREMENT(state, value) {
        // console.log('in mutation');
        state.sum += value
    },
    DECREMENT(state, value) {
        state.sum -= value
    }
}

// 用于存储数据
const state = {
    sum: 0
}

export default new Vuex.Store({
    actions, mutations, state
})

<template>
  <div>
    <Count />
  </div>
</template> 

<script>
import Count from "./components/Count.vue";

export default {
  name: "App",
  components: { Count }
};
</script>

<style>
.container,
.foot {
  display: flex;
  justify-content: space-around;
}
video {
  width: 100%;
}
</style>

<template>
  <div>
    <h4>当前求和为: {{$store.state.sum}}</h4>
    <select v-model.number="n">
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
    </select>
    <button @click="increment">+</button>&nbsp;
    <button @click="decrement">-</button>&nbsp;
    <button @click="incrementIfOdd">当前为奇数再加</button>&nbsp;
    <button @click="incrementAsync">异步加</button>&nbsp;
  </div>
</template>

<script>
export default {
  name: "sum",
  data() {
    return {
      n: 1
    };
  },
  methods: {
    increment() {
        // this.$store.commit('increment', this.n)
        this.$store.commit('INCREMENT', this.n)
    },
    decrement() {
        // this.$store.commit('decrement', this.n)
        this.$store.commit('DECREMENT', this.n)
    },
    incrementIfOdd() {
        this.$store.dispatch('incrementIfOdd', this.n)
    },
    incrementAsync() {
        this.$store.dispatch('incrementAsync', this.n)
    },
  },
};
</script>

<style>
</style>

vuex 使用 getter

  • 增加10倍计数功能

  • getter 便于处理有依赖数据

main.js
store/index.js
App.vue
Count.vue

import Vue from "vue";
import App from './App.vue'

import store from './store'

new Vue({
    render: h => h(App),
    store,
}).$mount('#app')

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

// 创建store

// 响应组件动作
const actions = {
    increment(context, value) {
        // console.log('in');
        context.commit('INCREMENT', value)
    },
    decrement(context, value) {
        context.commit('DECREMENT', value)
    },
    incrementIfOdd(context, value) { 
        if (value %2 !== 0) {
            context.commit('INCREMENT', value)
        }
    },
    incrementAsync(context, value) {
        setTimeout(() => {
            context.commit('INCREMENT', value)
        }, 500);
    }
}

// 用于操作数据
const mutations = {
    INCREMENT(state, value) {
        // console.log('in mutation');
        state.sum += value
    },
    DECREMENT(state, value) {
        state.sum -= value
    }
}

// 用于存储数据
const state = {
    sum: 0
}

// 准备getters 用于对state 数据进行加工
const getters = {
    bigSum(state){
        return state.sum * 10
    }
}

export default new Vuex.Store({
    actions, mutations, state, getters
})

<template>
  <div>
    <Count />
  </div>
</template> 

<script>
import Count from "./components/Count.vue";

export default {
  name: "App",
  components: { Count }
};
</script>

<style>
.container,
.foot {
  display: flex;
  justify-content: space-around;
}
video {
  width: 100%;
}
</style>

<template>
  <div>
    <h4>当前求和为: {{$store.state.sum}}</h4>
    <h4>当前求和10倍为: {{$store.getters.bigSum}}</h4>
    <select v-model.number="n">
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
    </select>
    <button @click="increment">+</button>&nbsp;
    <button @click="decrement">-</button>&nbsp;
    <button @click="incrementIfOdd">当前为奇数再加</button>&nbsp;
    <button @click="incrementAsync">异步加</button>&nbsp;
  </div>
</template>

<script>
export default {
  name: "sum",
  data() {
    return {
      n: 1
    };
  },
  methods: {
    increment() {
        // this.$store.commit('increment', this.n)
        this.$store.commit('INCREMENT', this.n)
    },
    decrement() {
        // this.$store.commit('decrement', this.n)
        this.$store.commit('DECREMENT', this.n)
    },
    incrementIfOdd() {
        this.$store.dispatch('incrementIfOdd', this.n)
    },
    incrementAsync() {
        this.$store.dispatch('incrementAsync', this.n)
    },
  },
};
</script>

<style>
</style>

vuex 使用 vuexmap

  • mapState 将 store 数据通过 mapState 映射到组件中,可以设置别名来避免冲突, 分为 对象形式 和 数组形式
  • mapGetters 将 store getter 数据通过 mapGetters 映射到组件中,可以设置别名来避免冲突, 分为 对象形式 和 数组形式

main.js
store/index.js
App.vue
Count.vue
MapCount.vue

import Vue from "vue";
import App from './App.vue'

import store from './store'

new Vue({
    render: h => h(App),
    store,
}).$mount('#app')

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

// 创建store

// 响应组件动作
const actions = {
    increment(context, value) {
        // console.log('in');
        context.commit('INCREMENT', value)
    },
    decrement(context, value) {
        context.commit('DECREMENT', value)
    },
    incrementIfOdd(context, value) { 
        if (value %2 !== 0) {
            context.commit('INCREMENT', value)
        }
    },
    incrementAsync(context, value) {
        setTimeout(() => {
            context.commit('INCREMENT', value)
        }, 500);
    }
}

// 用于操作数据
const mutations = {
    INCREMENT(state, value) {
        // console.log('in mutation');
        state.sum += value
    },
    DECREMENT(state, value) {
        state.sum -= value
    }
}

// 用于存储数据
const state = {
    sum: 0,
    school: '小学',
    addr: 'earth'
}

// 准备getters 用于对state 数据进行加工
const getters = {
    bigSum(state){
        return state.sum * 10
    }
}

export default new Vuex.Store({
    actions, mutations, state, getters
})

<template>
  <div>
    <h1>原始形式</h1>
    <Count />
    <hr>
    <h1>map简写形式</h1>
    <MapCount />
  </div>
</template> 

<script>
import Count from "./components/Count.vue";
import MapCount from "./components/MapCount.vue";

export default {
  name: "App",
  components: { Count, MapCount }
};
</script>

<style>
.container,
.foot {
  display: flex;
  justify-content: space-around;
}
video {
  width: 100%;
}
</style>

<template>
  <div>
    <h4>当前求和为: {{$store.state.sum}}</h4>
    <h4>当前求和10倍为: {{$store.getters.bigSum}}</h4>
    <select v-model.number="n">
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
    </select>
    <button @click="increment">+</button>&nbsp;
    <button @click="decrement">-</button>&nbsp;
    <button @click="incrementIfOdd">当前为奇数再加</button>&nbsp;
    <button @click="incrementAsync">异步加</button>&nbsp;
  </div>
</template>

<script>
export default {
  name: "sum",
  data() {
    return {
      n: 1
    };
  },
  methods: {
    increment() {
        // this.$store.commit('increment', this.n)
        this.$store.commit('INCREMENT', this.n)
    },
    decrement() {
        // this.$store.commit('decrement', this.n)
        this.$store.commit('DECREMENT', this.n)
    },
    incrementIfOdd() {
        this.$store.dispatch('incrementIfOdd', this.n)
    },
    incrementAsync() {
        this.$store.dispatch('incrementAsync', this.n)
    },
  },
};
</script>

<style>
</style>

<template>
  <div>
    <h4>当前求和为: {{sum}}</h4>
    <h4>当前求和10倍为: {{bigSum}}</h4>
    <h4>学校为: {{school}}</h4>
    <h4>在哪里: {{addr}}</h4>
    <select v-model.number="n">
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
    </select>
    <button @click="increment">+</button>&nbsp;
    <button @click="decrement">-</button>&nbsp;
    <button @click="incrementIfOdd">当前为奇数再加</button>&nbsp;
    <button @click="incrementAsync">异步加</button>&nbsp;
  </div>
</template>

<script>
import {mapState, mapGetters} from 'vuex'
export default {
  name: "MapCount",
  data() {
    return {
      n: 1
    };
  },
  computed: {
    // 对象形式
    // ...mapState({sum:'sum', school: 'school', addr: 'addr'})

    // 数组形式
    ...mapState(['sum', 'school', 'addr']),

    // 与上同理
    ...mapGetters(['bigSum'])
  },
  methods: {
    increment() {
        // this.$store.commit('increment', this.n)
        this.$store.commit('INCREMENT', this.n)
    },
    decrement() {
        // this.$store.commit('decrement', this.n)
        this.$store.commit('DECREMENT', this.n)
    },
    incrementIfOdd() {
        this.$store.dispatch('incrementIfOdd', this.n)
    },
    incrementAsync() {
        this.$store.dispatch('incrementAsync', this.n)
    },
  },
};
</script>

<style>
</style>

vuex 使用 vuexmap 2

  • mapMutations 将 store mutations 数据通过 mapMutations 映射到组件中,可以设置别名来避免冲突, 分为 对象形式 和 数组形式
  • mapActions 将 store actions 数据通过 mapActions 映射到组件中,可以设置别名来避免冲突, 分为 对象形式 和 数组形式

main.js
store/index.js
App.vue
Count.vue
MapCount.vue

import Vue from "vue";
import App from './App.vue'

import store from './store'

new Vue({
    render: h => h(App),
    store,
    beforeCreate() {
        Vue.prototype.$bus = this
    }
}).$mount('#app')

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

// 创建store

// 响应组件动作
const actions = {
    increment(context, value) {
        // console.log('in');
        context.commit('INCREMENT', value)
    },
    decrement(context, value) {
        context.commit('DECREMENT', value)
    },
    incrementIfOdd(context, value) { 
        if (value %2 !== 0) {
            context.commit('INCREMENT', value)
        }
    },
    incrementAsync(context, value) {
        setTimeout(() => {
            context.commit('INCREMENT', value)
        }, 500);
    }
}

// 用于操作数据
const mutations = {
    INCREMENT(state, value) {
        // console.log('in mutation');
        state.sum += value
    },
    DECREMENT(state, value) {
        state.sum -= value
    }
}

// 用于存储数据
const state = {
    sum: 0,
    school: '小学',
    addr: 'earth'
}

// 准备getters 用于对state 数据进行加工
const getters = {
    bigSum(state){
        return state.sum * 10
    }
}

export default new Vuex.Store({
    actions, mutations, state, getters
})

<template>
  <div>
    <h1>原始形式</h1>
    <Count />
    <hr>
    <h1>map简写形式</h1>
    <MapCount />
  </div>
</template> 

<script>
import Count from "./components/Count.vue";
import MapCount from "./components/MapCount.vue";

export default {
  name: "App",
  components: { Count, MapCount }
};
</script>

<style>
.container,
.foot {
  display: flex;
  justify-content: space-around;
}
video {
  width: 100%;
}
</style>

<template>
  <div>
    <h4>当前求和为: {{$store.state.sum}}</h4>
    <h4>当前求和10倍为: {{$store.getters.bigSum}}</h4>
    <h4>学校为: {{$store.state.school}}</h4>
    <h4>在哪里: {{$store.state.addr}}</h4>
    <select v-model.number="n">
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
    </select>
    <button @click="increment">+</button>&nbsp;
    <button @click="decrement">-</button>&nbsp;
    <button @click="incrementIfOdd">当前为奇数再加</button>&nbsp;
    <button @click="incrementAsync">异步加</button>&nbsp;
  </div>
</template>

<script>
export default {
  name: "sum",
  data() {
    return {
      n: 1
    };
  },
  methods: {
    increment() {
        // this.$store.commit('increment', this.n)
        this.$store.commit('INCREMENT', this.n)
    },
    decrement() {
        // this.$store.commit('decrement', this.n)
        this.$store.commit('DECREMENT', this.n)
    },
    incrementIfOdd() {
        this.$store.dispatch('incrementIfOdd', this.n)
    },
    incrementAsync() {
        this.$store.dispatch('incrementAsync', this.n)
    },
  },
};
</script>

<style>
</style>

<template>
  <div>
    <h4>当前求和为: {{sum}}</h4>
    <h4>当前求和10倍为: {{bigSum}}</h4>
    <h4>学校为: {{school}}</h4>
    <h4>在哪里: {{addr}}</h4>
    <select v-model.number="n">
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
    </select>
    <button @click="INCREMENT(n)">+</button>&nbsp;
    <button @click="DECREMENT(n)">-</button>&nbsp;
    <button @click="incrementIfOdd(n)">当前为奇数再加</button>&nbsp;
    <button @click="incrementAsync(n)">异步加</button>&nbsp;
  </div>
</template>

<script>
import {mapState, mapGetters, mapMutations, mapActions} from 'vuex'
export default {
  name: "MapCount",
  data() {
    return {
      n: 1
    };
  },
  computed: {
    // 对象形式
    // ...mapState({sum:'sum', school: 'school', addr: 'addr'})

    // 数组形式
    ...mapState(['sum', 'school', 'addr']),

    // 与上同理
    ...mapGetters(['bigSum'])
  },
  methods: {

    ...mapMutations(['INCREMENT', 'DECREMENT']),
    ...mapActions(['incrementIfOdd', 'incrementAsync'])

    // increment() {
    //     // this.$store.commit('increment', this.n)
    //     this.$store.commit('INCREMENT', this.n)
    // },
    // decrement() {
    //     // this.$store.commit('decrement', this.n)
    //     this.$store.commit('DECREMENT', this.n)
    // },
    // incrementIfOdd() {
    //     this.$store.dispatch('incrementIfOdd', this.n)
    // },
    // incrementAsync() {
    //     this.$store.dispatch('incrementAsync', this.n)
    // },
  },
};
</script>

<style>
</style>

vuex 组件通信

main.js
store/index.js
App.vue
Count.vue
MapCount.vue

import Vue from "vue";
import App from './App.vue'

import store from './store'

new Vue({
    render: h => h(App),
    store,
    beforeCreate() {
        Vue.prototype.$bus = this
    }
}).$mount('#app')

import { nanoid } from 'nanoid'
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

// 创建store

// 响应组件动作
const actions = {
    increment(context, value) {
        // console.log('in');
        context.commit('INCREMENT', value)
    },
    decrement(context, value) {
        context.commit('DECREMENT', value)
    },
    incrementIfOdd(context, value) {
        if (value % 2 !== 0) {
            context.commit('INCREMENT', value)
        }
    },
    incrementAsync(context, value) {
        setTimeout(() => {
            context.commit('INCREMENT', value)
        }, 500);
    }
}

// 用于操作数据
const mutations = {
    INCREMENT(state, value) {
        // console.log('in mutation');
        state.sum += value
    },
    DECREMENT(state, value) {
        state.sum -= value
    },
    ADD_PERSON(state, value) {
        const person = {id: nanoid(), name: value}
        state.personList.unshift(person)
    }
}

// 用于存储数据
const state = {
    sum: 0,
    school: '小学',
    addr: 'earth',
    personList: [{ id: '001', name: '小张' }]
}

// 准备getters 用于对state 数据进行加工
const getters = {
    bigSum(state) {
        return state.sum * 10
    }
}

export default new Vuex.Store({
    actions, mutations, state, getters
})

<template>
  <div>
    <Count />
    <hr>
    <Person />
  </div>
</template> 

<script>
import Count from "./components/Count.vue";
import Person from "./components/Person.vue";

export default {
  name: "App",
  components: { Count, Person }
};
</script>

<style>
.container,
.foot {
  display: flex;
  justify-content: space-around;
}
video {
  width: 100%;
}
</style>

<template>
  <div>
    <h4>当前求和为: {{sum}}</h4>
    <h4>当前求和10倍为: {{bigSum}}</h4>
    <h4>学校为: {{school}}</h4>
    <h4>在哪里: {{addr}}</h4>
    <h4>下方组件人数呢: {{personList.length}}</h4>
    <select v-model.number="n">
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
    </select>
    <button @click="INCREMENT(n)">+</button>&nbsp;
    <button @click="DECREMENT(n)">-</button>&nbsp;
    <button @click="incrementIfOdd(n)">当前为奇数再加</button>&nbsp;
    <button @click="incrementAsync(n)">异步加</button>&nbsp;
  </div>
</template>

<script>
import {mapState, mapGetters, mapMutations, mapActions} from 'vuex'
export default {
  name: "Count",
  data() {
    return {
      n: 1
    };
  },
  computed: {
    // 对象形式
    // ...mapState({sum:'sum', school: 'school', addr: 'addr'})

    // 数组形式
    ...mapState(['sum', 'school', 'addr', 'personList']),

    // 与上同理
    ...mapGetters(['bigSum'])
  },
  methods: {

    ...mapMutations(['INCREMENT', 'DECREMENT']),
    ...mapActions(['incrementIfOdd', 'incrementAsync'])

    // increment() {
    //     // this.$store.commit('increment', this.n)
    //     this.$store.commit('INCREMENT', this.n)
    // },
    // decrement() {
    //     // this.$store.commit('decrement', this.n)
    //     this.$store.commit('DECREMENT', this.n)
    // },
    // incrementIfOdd() {
    //     this.$store.dispatch('incrementIfOdd', this.n)
    // },
    // incrementAsync() {
    //     this.$store.dispatch('incrementAsync', this.n)
    // },
  },
};
</script>

<style>
</style>

<template>
  <div>
      <h3>人员列表</h3>
      <h4>上方求和为:{{sum}}</h4>
      <input type="text" v-model="name" />
      <button @click="add">添加人员</button>
      <ul>
        <li v-for="p in personList" :key="p.id">{{p.name}}</li>
      </ul>
  </div>
</template>

<script>
import { nanoid } from 'nanoid'
import { mapMutations, mapState } from 'vuex'
export default {
    name: 'Person',
    data() {
        return {
            name: ''
        }
    },
    computed: {
        ...mapState(['personList', 'sum'])
    },
    methods: {
        ...mapMutations(['ADD_PERSON']),

        add() {
            this.ADD_PERSON(this.name)

            this.name = ''
        }
    },
}
</script>

<style>

</style>

vuex 模块化

main.js
store/index.js
App.vue
Count.vue
MapCount.vue

import Vue from "vue";
import App from './App.vue'

import store from './store'

new Vue({
    render: h => h(App),
    store,
    beforeCreate() {
        Vue.prototype.$bus = this
    }
}).$mount('#app')

import { nanoid } from 'nanoid'
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

// 创建store
const countOptions = {
    namespaced: true, // 调用map 函数 使用名称空间能简写,否则调用要写全名 module/function
    state: {
        sum: 0,
        school: '小学',
        addr: 'earth'
    },
    actions: {
        increment(context, value) {
            // console.log('in');
            context.commit('INCREMENT', value)
        },
        decrement(context, value) {
            context.commit('DECREMENT', value)
        },
        incrementIfOdd(context, value) {
            if (context.state.sum % 2 !== 0) {
                context.commit('INCREMENT', value)
            }
        },
        incrementAsync(context, value) {
            setTimeout(() => {
                context.commit('INCREMENT', value)
            }, 500);
        }
    },
    mutations: {
        INCREMENT(state, value) {
            state.sum += value
        },
        DECREMENT(state, value) {
            state.sum -= value
        }
    },
    getters: {
        bigSum(state) {
            return state.sum * 10
        }
    }
}

const personOptions = {
    namespaced: true, // 调用map 函数 使用名称空间能简写,否则调用要写全名 module/function
    state: {
        personList: [{ id: '001', name: '小张' }]
    },
    actions: {
        // 添加一个姓王的人
        addPersonWang(context, value) {
            if (value.charAt(0) !== '王') return alert('输入的必须姓王')

            context.commit('ADD_PERSON', value)
        }
    },
    mutations: {
        ADD_PERSON(state, value) {
            console.log('in state:', state, 'value:', value);
            const person = { id: nanoid(), name: value }
            state.personList.unshift(person)
        }
    },
    getters: {
        firstPerson(state) {
            if (state.personList.length === 0) return
            return state.personList[0]
        }
    }
}

export default new Vuex.Store({
    modules: { countOptions, personOptions }
})

<template>
  <div>
    <Count />
    <hr>
    <Person />
  </div>
</template> 

<script>
import Count from "./components/Count.vue";
import Person from "./components/Person.vue";

export default {
  name: "App",
  components: { Count, Person }
};
</script>

<style>
.container,
.foot {
  display: flex;
  justify-content: space-around;
}
video {
  width: 100%;
}
</style>

<template>
  <div>
    <h4>当前求和为: {{sum}}</h4>
    <h4>当前求和10倍为: {{bigSum}}</h4>
    <h4>学校为: {{school}}</h4>
    <h4>在哪里: {{addr}}</h4>
    <h4>下方组件人数呢: {{personList.length}} </h4>
    <select v-model.number="n">
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
    </select>
    <button @click="INCREMENT(n)">+</button>&nbsp;
    <button @click="DECREMENT(n)">-</button>&nbsp;
    <button @click="incrementIfOdd(n)">当前为奇数再加</button>&nbsp;
    <button @click="incrementAsync(n)">异步加</button>&nbsp;
  </div>
</template>

<script>
import {mapState, mapGetters, mapMutations, mapActions} from 'vuex'
export default {
  name: "Count",
  data() {
    return {
      n: 1
    };
  },
  computed: {
    // 对象形式
    // ...mapState({sum:'sum', school: 'school', addr: 'addr'})

    // 数组形式
    ...mapState('countOptions', ['sum', 'school', 'addr']),

    ...mapState('personOptions', ['personList']),
    // ...mapState('personOptions', {personList: 'personOptions/personList'}),

    // 与上同理
    ...mapGetters('countOptions', ['bigSum'])
  },
  methods: {

    ...mapMutations('countOptions', ['INCREMENT', 'DECREMENT']),
    ...mapActions('countOptions', ['incrementIfOdd', 'incrementAsync'])

    // increment() {
    //     // this.$store.commit('increment', this.n)
    //     this.$store.commit('INCREMENT', this.n)
    // },
    // decrement() {
    //     // this.$store.commit('decrement', this.n)
    //     this.$store.commit('DECREMENT', this.n)
    // },
    // incrementIfOdd() {
    //     this.$store.dispatch('incrementIfOdd', this.n)
    // },
    // incrementAsync() {
    //     this.$store.dispatch('incrementAsync', this.n)
    // },
  },
  mounted() {
    console.log('this store:', this.$store);
    // console.log('personList:', this.personList);
  }
};
</script>

<style>
</style>

<template>
  <div>
      <h3>人员列表</h3>
      <h4>上方求和为:{{sum}}</h4>
      <input type="text" v-model="name" />
      <button @click="add">添加人员</button> <br />
      <input type="text" v-model="nameWang" />
      <button @click="addWang">添加姓王的成员</button>
      <h4>第一个成员是:{{firstPerson.name}}</h4>
      <ul>
        <li v-for="p in personList" :key="p.id">{{p.name}}</li>
      </ul>
  </div>
</template>

<script>
export default {
    name: 'Person',
    data() {
        return {
            name: '',
            nameWang: ''
        }
    },
    computed: {
        sum() {
            return this.$store.state.countOptions.sum
        },
        personList() {
            return this.$store.state.personOptions.personList
        },
        firstPerson() {
            return this.$store.getters['personOptions/firstPerson']
        }
    },
    methods: {
        add() {
            this.$store.commit('personOptions/ADD_PERSON', this.name)

            this.name = ''
        },
        addWang() {
            this.$store.dispatch('personOptions/addPersonWang', this.nameWang)

            this.nameWang = ''
        }
    },
}
</script>

<style>

</style>

vuex 模块化最终版

main.js
store/index.js
store/count.js
store/persons.js
App.vue
Count.vue
Person.vue

import Vue from "vue";
import App from './App.vue'

import store from './store'

new Vue({
    render: h => h(App),
    store,
    beforeCreate() {
        Vue.prototype.$bus = this
    }
}).$mount('#app')

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

// 创建store
import countOptions from './count'
import personOptions from './persons'

export default new Vuex.Store({
    modules: { countOptions, personOptions }
})

export default {
    namespaced: true, // 调用map 函数 使用名称空间能简写,否则调用要写全名 module/function
    state: {
        sum: 0,
        school: '小学',
        addr: 'earth'
    },
    actions: {
        increment(context, value) {
            // console.log('in');
            context.commit('INCREMENT', value)
        },
        decrement(context, value) {
            context.commit('DECREMENT', value)
        },
        incrementIfOdd(context, value) {
            if (context.state.sum % 2 !== 0) {
                context.commit('INCREMENT', value)
            }
        },
        incrementAsync(context, value) {
            setTimeout(() => {
                context.commit('INCREMENT', value)
            }, 500);
        }
    },
    mutations: {
        INCREMENT(state, value) {
            state.sum += value
        },
        DECREMENT(state, value) {
            state.sum -= value
        }
    },
    getters: {
        bigSum(state) {
            return state.sum * 10
        }
    }
}

import axios from "axios";
import { nanoid } from "nanoid";

export default {
    namespaced: true, // 调用map 函数 使用名称空间能简写,否则调用要写全名 module/function
    state: {
        personList: [{ id: '001', name: '小张' }]
    },
    actions: {
        // 添加一个姓王的人
        addPersonWang(context, value) {
            if (value.charAt(0) !== '王') return alert('输入的必须姓王')

            context.commit('ADD_PERSON', value)
        },
        
        addPersonServer(context){
            axios.get('https://api.uixsj.cn/hitokoto/get?type=social').then(
                response => {
                    // root 为 true 可以调用其他模块的信息  模块名/方法
                    context.commit('personOptions/ADD_PERSON', response.data, {root: true})
                },
                error => {
                    alert(error.message)
                }
            )
        }
    },
    mutations: {
        ADD_PERSON(state, value) {
            console.log('in state:', state, 'value:', value);
            const person = { id: nanoid(), name: value }
            state.personList.unshift(person)
        }
    },
    getters: {
        firstPerson(state) {
            if (state.personList.length === 0) return
            return state.personList[0]
        }
    }
}

<template>
  <div>
    <Count />
    <hr>
    <Person />
  </div>
</template> 

<script>
import Count from "./components/Count.vue";
import Person from "./components/Person.vue";

export default {
  name: "App",
  components: { Count, Person }
};
</script>

<style>
.container,
.foot {
  display: flex;
  justify-content: space-around;
}
video {
  width: 100%;
}
</style>

<template>
  <div>
    <h4>当前求和为: {{sum}}</h4>
    <h4>当前求和10倍为: {{bigSum}}</h4>
    <h4>学校为: {{school}}</h4>
    <h4>在哪里: {{addr}}</h4>
    <h4>下方组件人数呢: {{personList.length}} </h4>
    <select v-model.number="n">
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
    </select>
    <button @click="INCREMENT(n)">+</button>&nbsp;
    <button @click="DECREMENT(n)">-</button>&nbsp;
    <button @click="incrementIfOdd(n)">当前为奇数再加</button>&nbsp;
    <button @click="incrementAsync(n)">异步加</button>&nbsp;
  </div>
</template>

<script>
import {mapState, mapGetters, mapMutations, mapActions} from 'vuex'
export default {
  name: "Count",
  data() {
    return {
      n: 1
    };
  },
  computed: {
    // 对象形式
    // ...mapState({sum:'sum', school: 'school', addr: 'addr'})

    // 数组形式
    ...mapState('countOptions', ['sum', 'school', 'addr']),

    ...mapState('personOptions', ['personList']),
    // ...mapState('personOptions', {personList: 'personOptions/personList'}),

    // 与上同理
    ...mapGetters('countOptions', ['bigSum'])
  },
  methods: {

    ...mapMutations('countOptions', ['INCREMENT', 'DECREMENT']),
    ...mapActions('countOptions', ['incrementIfOdd', 'incrementAsync'])

    // increment() {
    //     // this.$store.commit('increment', this.n)
    //     this.$store.commit('INCREMENT', this.n)
    // },
    // decrement() {
    //     // this.$store.commit('decrement', this.n)
    //     this.$store.commit('DECREMENT', this.n)
    // },
    // incrementIfOdd() {
    //     this.$store.dispatch('incrementIfOdd', this.n)
    // },
    // incrementAsync() {
    //     this.$store.dispatch('incrementAsync', this.n)
    // },
  },
  mounted() {
    console.log('this store:', this.$store);
    // console.log('personList:', this.personList);
  }
};
</script>

<style>
</style>

<template>
  <div>
      <h3>人员列表</h3>
      <h4>上方求和为:{{sum}}</h4>
      <input type="text" v-model="name" />
      <button @click="add">添加人员</button> <br />
      <input type="text" v-model="nameWang" />
      <button @click="addWang">添加姓王的成员</button> <br/>
      <button @click="addNameFromServer">添加服务器返回的名字</button>
      <h4>第一个成员是:{{firstPerson.name}}</h4>
      <ul>
        <li v-for="p in personList" :key="p.id">{{p.name}}</li>
      </ul>
  </div>
</template>

<script>
export default {
    name: 'Person',
    data() {
        return {
            name: '',
            nameWang: ''
        }
    },
    computed: {
        sum() {
            return this.$store.state.countOptions.sum
        },
        personList() {
            return this.$store.state.personOptions.personList
        },
        firstPerson() {
            return this.$store.getters['personOptions/firstPerson']
        }
    },
    methods: {
        add() {
            this.$store.commit('personOptions/ADD_PERSON', this.name)

            this.name = ''
        },
        addWang() {
            this.$store.dispatch('personOptions/addPersonWang', this.nameWang)

            this.nameWang = ''
        },
        addNameFromServer() {
            this.$store.dispatch('personOptions/addPersonServer')
        }
    },
}
</script>

<style>

</style>

results matching ""

    No results matching ""