VUEX入门


vue.js中管理数据状态的库,集中数据存储,供所有组件访问;

  • 根组件 = > props =>子组件 => event事件 = > 根组件;
  • vuex(getter/mutation);
  • 借鉴了Flux、Redux、the Elm Architecture ;

npm淘宝镜像安装,提升速度;
npm i vuex --save / yarn add vuex

简单的使用:

  • state 驱动应用的数据源
  • view 声明方式将state映射到视图
  • actions 响应在view上的用户输入导致的状态变化

state

一般不用store.state._name此方法调用修改原始state数据,不利于检测和维护;使用getter获取数据,mutations/actions修改数据;

// store/store.js导出
    import Vue from 'vue'
    import Vuex from 'vuex'
    Vue.use(Vuex)
    export const store = new Vuex.Store({
        // 严格模式下,事件触发用mutations
        strict:true,
        state:{
            products:[
                {name:'马云',price:'200'},
                {name:'马化腾',price:'180'}
            ]
        }
    })

// main.js引入
    import {store} from './store/store.js'
    new Vue({
        store:store,
        el:'#app',
        render:h=>h(app)
    })
<!-- test1.vue -->
    <template>
        <ul>
            <li v-for="it in products">{{it}}</li>
        </ul>
    </template>
    <script>
        export default{
            computed:{
                products(){
                    return this.$store.state.products;
                },
            }
        }
    <script>
    <style scoped></style>
<!-- test2.vue -->
    <template>
        <ul>
            <li v-for="it in sale">{{it}}</li>
        </ul>
    </template>
    <script>
        export default{
            computed:{
                products(){
                    return this.$store.state.products;
                },
                sale(){
                    var saleProducts = this.$store.state.products.map(
                        it =>{
                            return {
                                name : "**" + it.name + "**",
                                price: it.price / 2
                            }
                        }
                    );
                    return saleProducts;
                }
            }
        }
    <script>
    <style scoped></style>

getters

如果多组件使用saleProducts数据,可以抽离放入store.js
组件引用 => computed 动态获取;
通过store.getters._name调用;
state数据更新触发getters的更新问题?貌似官方已经解决;删除state下“数组/对象”属性的时候,组件里需要watch数据的变化,以重新DOM渲染;

    // store.js
        import Vue from 'vue'
    import Vuex from 'vuex'
    Vue.use(Vuex)
    export const store = new Vuex.Store({
        state:{
            products:[
                {name:'马云',price:'200'},
                {name:'马化腾',price:'180'}
            ]
        },
        getters:{
            saleProducts:(state)=>{
                var saleProducts = state.products.map(
                    it =>{
                        return {
                            name : "**"+it.name+"**",
                            price:it.price/2
                        }
                    }
                );
                return saleProducts;
            }
        }
    })
<!-- test3.vue -->
    <template>
        <ul>
            <li v-for="it in sale">{{it}}</li>
        </ul>
    </template>
    <script>
        export default{
            computed:{
                products(){
                    return this.$store.state.products;
                },
                sale(){
                    return this.$store.getters.saleProducts;
                }
            }
        }
    <script>
    <style scoped></style>

mutation

存储数据用state类似date;获取数据用getter类似computed;触发事件改变数据用mutation类似methods,可以追查事件;action => 分发异步触发mutation;
通过store.commit("_name",{传参})调用;

Chrome浏览器插件vue devtools安装

第一位参数固定为state,其他为传入参数,顺传;

    // store.js
        import Vue from 'vue'
    import Vuex from 'vuex'
    Vue.use(Vuex)
    export const store = new Vuex.Store({
        state:{
            products:[
                {name:'马云',price:'200'},
                {name:'马化腾',price:'180'}
            ]
        },
        getters:{
            saleProducts:(state)=>{
                var saleProducts = state.products.map(
                    it =>{
                        return {
                            name : "**"+it.name+"**",
                            price:it.price/2
                        }
                    }
                );
                return saleProducts;
            }
        },
        mutations:{
            reducePrice:(state)=>{
                state.products.forEach(it =>{
                    it.price -=1;
                })
            }
        }
    })
<!-- test4.vue -->
    <template>
        <ul>
            <li v-for="it in saleProducts">{{it}}</li>
        </ul>
        <button type="button" @click="reduce">降价</button>
    </template>
    <script>
        export default{
            computed:{
                products(){
                    return this.$store.state.products;
                },
                saleProducts(){
                    return this.$store.getters.saleProducts;
                }
            },
            methods:{
                reduce(){
                    // this.$store.state.products.forEach(it =>{
                    //     it.price -= 1;
                    // })
                    this.$store.commit('reducePrice');
                }
            }
        }
    <script>
    <style scoped></style>

actions

类似于mutation,不同:
actions提交的时mutations,而不是直接变更状态;
可以包含任意异步操作;
dispath(fn,payload)分发方法触发actions中调用mutations函数;

mutations中直接setTimeout()实现异步不好调试,可以用actions实现异步调用mutations中函数;

    // store.js
    import Vue from 'vue'
    import Vuex from 'vuex'
    Vue.use(Vuex)
    export const store = new Vuex.Store({
        state:{
            products:[
                {name:'马云',price:'200'},
                {name:'马化腾',price:'180'}
            ]
        },
        getters:{
            saleProducts:(state)=>{
                var saleProducts = state.products.map(
                    it =>{
                        return {
                            name : "**"+it.name+"**",
                            price:it.price/2
                        }
                    }
                );
                return saleProducts;
            }
        },
        actions:{
            reduceLayout:(context,payload)=>{
                setTimeout(function(){
                    context.commit("reducePrice",payload)
                },3000)
            }
        },
        mutations:{
            reducePrice:(state,payload) => {
                state.products.forEach(it => {
                    it.price -= payload;
                })
            }
        }
    })
<!-- test5.vue -->
    <template>
        <ul>
            <li v-for="it in saleProducts">{{it}}</li>
        </ul>
        <button type="button" @click="reduce(4)">降价</button>
    </template>
    <script>
        export default{
            computed:{
                products(){
                    return this.$store.state.products;
                },
                saleProducts(){
                    return this.$store.getters.saleProducts;
                }
            },
            methods:{
                reduce(amount){
                    this.$store.dispatch('reduceLayout',amount);
                }
            }
        }
    <script>
    <style scoped></style>

mapState/mapGetters/mapMutations/mapActions 辅助函数

举个栗子:ES6中...mapGetters(['saleProducts'])...mapActions(['reduceLayout'])批量调用函数

mapState:

//test.vue
import {mapState} from "vuex";
data(){
	return {
			localCount:50;
		}
	},
computed:mapState({
	//箭头函数中this指向store中的state数据
	products:state => state.products,
	//为了this获取当前局部的data/compputed数据,使用常规函数
	salaProducts(state){
	return state.products + this.localCount;
	}
})

mapGetters、mapActions:

<!-- test5.vue -->
    <template>
        <ul>
            <li v-for="it in saleProducts">{{it}}</li>
        </ul>
        <button type="button" @click="reduce(4)">降价</button>
    </template>
    <script>
    	//先注入依赖
        import {mapGetters} from 'vuex'
        import {mapActions} from 'vuex'

        export default{
            computed:{
                // products(){
                //     return this.$store.state.products;
                // },
                // saleProducts(){
                //     return this.$store.getters.saleProducts;
                // },
                ...mapGetters(["products","saleProducts"])
            },
            methods:{
                reduce(amount){
                //this.$store.dispatch('reduceLayout',amount);
                var amount = 0.5;//五折
                this.reduceLayout(amount);
                },
                ...mapActions(["reduceLayout"])
            }
        }
    <script>
    <style scoped></style>

…mapGetters([“dataName1”,“dataName2”]),类似computed数据引用;
…mapMutatains([“methodName1”,“methodsName2”]),类似methods方法引用,并传参this.nethodName1(argu);…mapActions同理;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值