vue全家桶项目学习(三、veux)

一、使用

在这里插入图片描述

首先通过import引入vuex,然后通过Vue.use(Vuex)加载,最后创建Vuex实例并导出。

二、state

可以理解为vue组件中的data,在其中定义的变量可以在各个组件中使用。

  1. 简单使用
...
state: {
	name: 'anni'
},
...

组件中使用:

<template>
    <div>{{ name }}</div>
</template>

<script>
export default {
    computed: {
        name () {
            return this.$store.state.name;
        }
    }
}
</script>

使用module中定义的state变量

modules: {
    user: {
        state: {
            name: 'tom'
        }
    }
}
computed: {
    modulesName () {
        // 加上模块名
        return this.$store.state.user.name;
    }
}
  1. mapState
<template>
    <div>{{ name }}</div>
</template>

<script>
import { mapState } from 'vuex';
export default {
    computed: {
    	// 传入数组
        ...mapState([
            'name'
        ])
        // 也可传入对象 state为vuex中的state
        ...mapState({
            name: state => state.name
        })
        // 访问模块中的变量
        ...mapState({
            modulesName: state => state.user.name
        }),
    }
}
</script>
  1. 模块中使用命名空间
modules: {
    user: {
    	// 开启命名空间
        namespaced: true,
        state: {
            name: 'tom'
        }
    }
}
// 模块名当作第一个参数传入
...mapState('user',{
	// 此时state直接为user模块中的state,使用时便不需要在点出模块名
    modulesName: state => state.name
}),

或者

import { createNamespacedHelpers } from 'vuex';
const { mapState } = createNamespacedHelpers('user');
export default {
    computed: {
        ...mapState({
            modulesName: state => state.name
        })
    }
}

三、getter

相当于组件中的计算属性。

  1. 简单使用
getters:{
	// state为同级下的vuex state
    allName: (state) => state.name + 'jack'
},
<template>
    <div>
        <div>{{ allName }}</div>
    </div>
</template>

<script>
export default {
    computed: {
        allName () {
            return this.$store.getters.allName
        }
    }
}
</script>
  1. mapGetters
import { mapGetters } from 'vuex';
export default {
    computed: {
        ...mapGetters([
            'allName'
        ])
    }
}
  1. 访问模块中getter
getters:{
    allName: (state) => state.name + 'jack'
},
modules: {
    user: {
        namespaced: true,
        getters: {
            modulesAllName: (state) => state.name + 'modules'
        }
    }
}
// 如果模块未开启命名空间可直接访问,注意各个模块和根getter中的名字不要重复,之后的matations和actions同。
...mapGetters([
	'allName',
    'modulesAllName'
])
// 如果开启了命名空间
...mapGetters('user', [
    'modulesAllName'
])
// 或
...mapGetters({
	modulesAllName: 'user/modulesAllName'
})

四、mutation

更改 Vuexstore 中的状态的唯一方法是提交 mutation

  1. 简单使用
state: {
    name: 'anni'
},
mutations: {
    setName (state, params) {
        state.name = params;
    }
},
<template>
    <div>
        <p>{{ name }}</p>
        <button @click="clickHandle">修改state值</button>
    </div>
</template>

<script>

export default {
    computed: {
        name () {
            return this.$store.state.name;
        },
    },
    methods: {
        clickHandle () {
        	// 参数为一个
            this.$store.commit('setName', 'reset');
            // 参数为多个
            this.$store.commit('setName', {
            	name: 'reset',
            	name2: 'reset2'
			});
			// 对象写法
			this.$store.commit({
				type: 'setName',
				name: 'reset'
			});
        }
    }
}

当前state中只有name一个值,如果想新添变量

setNew (state) {
    Vue.set(state, 'newParam', 123);
}
  1. mapMutations
import { mapMutations } from 'vuex';
...
methods: {
    ...mapMutations([
        'setName',
        'setNew'
    ]),
    clickHandle () {
        this.setName('new name');
        this.setNew();
    }
}
  1. 访问模块中的mutation
modules: {
    user: {
        state: {
            name: 'tom'
        },
        getters: {
            modulesAllName: (state) => state.name + 'modules'
        },
        mutations: {
            setModuleName (state, params) {
                state.name = params;
            }
        }
    }
}
// 如未开启模块命名空间,直接访问
...mapMutations([
    'setModuleName'
]),
// 开启命名空间
...mapMutations('user', [
    'setModuleName'
]),

clickHandle () {
    this.setModuleName('new module name');
}

五、action

Action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作。
// 模拟请求
const request =  () => {
    return new Promise((res, rej) => {
        const err = null;
        if (!err) res({code: '200', data: { name: 'new name' }});
        else rej('错误!');
    })
}
...
mutations: {
    setName (state, params) {
        state.name = params;
    }
},
actions: {
    getName ({ commit }) {
        request().then((res) => {
            commit('setName', res.data.name);
        }).catch((err) => {
            console.log(err);
        })
    }
},
import { mapActions } from 'vuex';
...
methods: {
    ...mapActions([
        'getName'
    ]),
    handleClick () {
    	this.$store.dispatch('getName');
    	// 或
        this.getName();
    }
}

六、module

  1. module中建立module
modules: {
	namespaced: true,
    user: {
        ...
        modules: {
        	namespaced: true,
            childUser: {
                actions: {
                    getModuleName ({ commit, state, rootState, dispatch }) {
                        ...
                    }
                },
            }
        }
    }
}
// 如全部开启命名空间
...mapActions('user/childUser', [
    'getModuleName'
])
  1. 其他参数
modules: {
	namespaced: true,
    user: {
        ...
        modules: {
        	namespaced: true,
            childUser: {
                actions: {
                    getModuleName ({ commit, state, rootState, dispatch }) {
                       	commit: 用来调用当前模块mutation
                       	state: 当前模块state
                       	rootState: 根state
                       	dispathc: 用来调用当前模块action
                    }
                },
            }
        }
    }
}
  1. 动态注册模块
this.$store.registerModule('newModule', {
    state: {
        ...
    },
    getters: {
		...
    }
    ...
})
// 给模块注册模块
this.$store.registerModule(['newModule', 'childModule'], {
    ...
})

七、插件

Vuexstore 接受 plugins 选项,这个选项暴露出每次 mutation 的钩子。Vuex 插件就是一个函数,它接收 store 作为唯一参数。

// 持久化存储
const saveInlocal = store => {
    // 当 store 初始化后调用
    if (localStorage.state) store.replaceState(JSON.parse(localStorage.state));
    store.subscribe((mutation, state) => {
        // 每次 mutation 之后调用
        // mutation 的格式为 { type, payload }
        localStorage.state = JSON.stringify(state);
    })
}
...
export default new Vuex.Store({
	...
    plugins: [
        saveInlocal
    ]
})

八、严格模式

开启严格模式,仅需在创建 store 的时候传入 strict: true:

const store = new Vuex.Store({
	// ...
	strict: true
})

在严格模式下,无论何时发生了状态变更且不是由 mutation 函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。

不要在发布环境下启用严格模式!严格模式会深度监测状态树来检测不合规的状态变更——请确保在发布环境下关闭严格模式,以避免性能损失。

类似于插件,我们可以让构建工具来处理这种情况:

const store = new Vuex.Store({
	// ...
	strict: process.env.NODE_ENV !== 'production'
})

九、vuex + 双向绑定

...
<input :value="name" @input="handleInput" />
...
computed: {
	...mapState({
	    name: state => state.name
	}),
}
methods: {
...mapMutations([
	    'setName'
	]),
	handleInput (e) {
	    this.setName(e.target.value);
	}
}

// 或

...
<input v-model="name" />
...
computed: {
    name: {
        get () {
            return this.$store.state.name
        },
        set (val) {
            this.setName(val)
        }
    }
},
methods: {
...mapMutations([
	    'setName'
	]),
}

猜你喜欢

转载自blog.csdn.net/qq_42555578/article/details/107862238