时间:2023-04-21 02:27:01 | 来源:网站运营
时间:2023-04-21 02:27:01 来源:网站运营
Vuex4.0的基本使用方法:state: { count: 0, myObject: { time: '现在的时间' } }
一个简单类型(number)的count,还有一个引用类型的myObject。 const store = useStore() // 看看state的类型 console.log('state:', store.state) console.log('state.count:', store.state.count) console.log('state.myObject:', store.state.myObject)
state: { count: 0, myObject: { time: '现在的时间:' }, myArray: [1,2,2,3,4] },
简单类型、对象和数组,比较有代表性的类型。 // 整体获取 const allStateManage = () => { const store = Vuex.useStore() // 看看state的类型 console.log('state:', store.state) console.log('state.count:', store.state.count) console.log('state.myObject:', store.state.myObject) return { allState } }
整个state就是reactive的,成员又是什么样子的呢?import { useStore } from 'vuex'setup() { const store = useStore()}
这样获取store,然后就可以按照“$store”的习惯来操作了。 // 整体获取 const allStateManage = () => { const store = Vuex.useStore() // 获得整体的state const allState = store.state console.log('allState:', allState) console.log('================') // 定时修改 count 看响应性 setTimeout(() => { // store.commit('setCount') // allState.count += 101 // 会直接改vuex的state }, 1000) return { allState } }
// 直接获取成员 const stateMemberManage = () => { const store = Vuex.useStore() // 看看state的类型 let memberCount = store.state.count // 失去响应性 const memberObject = store.state.myObject console.log('memberCount', memberCount) console.log('memberObject', memberObject) console.log('================') // 定时修改 count 看响应性 setTimeout(() => { memberCount += 101 // const 定义的会报错,不允许赋值,常量。 // let 定义的可以修改,但是没有相应性 }, 1000) return { memberCount, memberObject } }
// 间接获取 const indirectManage = () => { const store = Vuex.useStore() // 用toRef获取 count,有相应性,可以直接修改state const refCount = Vue.toRef(store.state, 'count') // 计算属性获取count,有相应性,不可以直接修改state const comCount = Vue.computed(() => store.state.count) // 只读的对象,有相应性,浅层不可以修改,但是深层还是可以修改。 const readonlyObject = Vue.readonly(store.state.myObject) console.log('refCount:', refCount) console.log('comCount:', comCount) console.log('readonlyObject:', readonlyObject) console.log('================') // 定时修改 count 看响应性 setTimeout(() => { // store.commit('setCount') // refCount.value += 200 // 会直接改vuex的state }, 2000) return { refCount, comCount, readonlyObject } }
因为引用类型会自动变成reactive的形式,而reactive又可以直接修改state,那么就有可能误操作,导致修改state的情况,那么如何预防呢?可以使用vue提供的readonly。 // 处理后返回 const operationManage = () => { const store = Vuex.useStore() // 计算属性获取count const addCount = '' // Vue.computed(() => store.state.count++) const getAddCount = store.getters.getAddCount const comGetAddCount = Vue.computed(() => store.getters.getAddCount) const filterArray = store.getters.filterArray(2) const comFilterArray = Vue.computed(() => store.getters.filterArray(2)) console.log('addCount :', addCount) console.log('getAddCount :', getAddCount) console.log('comGetAddCount :', comGetAddCount) console.log('filterArray :', filterArray) console.log('================') return { addCount, getAddCount, comGetAddCount, filterArray, comFilterArray } }
const map = () => { const store = Vuex.useStore() /** * 获取count, * 用computed实现相应 */ const getCount = () => { return Vue.computed(() => store.state.count) } /** * 获取count, ** 用 ref 实现相应 */ const getRefCount = () => { return Vue.ref(store.state.count) } /** * 获取对象 */ const getObject = () => { return store.state.myObject } /** * 获取只读对象 */ const getReadonlyObject = () => { return Vue.readonly(store.state.myObject) } /** * 获取数组 */ const getArray = () => { return store.state.myArray } /** * 获取只读数组 */ const getReadonlyArray = () => { return Vue.readonly(store.state.myArray) } /** * 查询数组 ** id:要查询的数据 */ const filterArray = (id) => { return Vue.computed(() => store.getters.filterArray(id)) } return { getCount, getRefCount, getObject, getReadonlyObject, getArray, getReadonlyArray, filterArray }}export default map
这样就可以把麻烦事交给抽离处理的js来处理了,组件只需要调用就好,不用管其他的。 setup() { // 传说中的setup const store = Vuex.useStore() // 状态的控制事件 const setCount = () =>{ store.commit('setCount') store.commit('setTime') store.commit('setArray') store._mutations.setCount[0] // 这是什么? } // 获取state const { allState } = allStateManage() // 直接获取成员 const { memberCount, memberObject } = stateMemberManage() // 间接获取成员 const { refCount, comCount, readonlyObject } = indirectManage() // 间接获取成员 const { addCount, getAddCount, comGetAddCount, filterArray, comFilterArray } = operationManage() // 通过map 获取 count // 可以使用别名 const { getCount: mapGetCount } = map() const mapCount = mapGetCount() return { // 返回给模板,否则模板访问不到。 // 直接获取state allState, // 直接获取成员 memberCount,memberObject, // 间接获取 refCount, comCount,readonlyObject, // 操作后获取 addCount,getAddCount,comGetAddCount,filterArray,comFilterArray, // map mapCount, // 设置state setCount } }
具体实现方式写成各种函数,可以放在单独的js文件里面。 mutations: { // 计数器 setCount(state, num = 1) { state.count += num }, // 设置当前时间 setTime(state) { state.myObject.time = '现在时间:' + new Date() }, // 设置数组的值 setArray(state) { state.myArray[1] = 4 } },
store.commit('setCount', val)
我们还是看看内部结构:Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:官方这么说的,我水平有限,大概涉及到了原型链那方面的了。
// mutation-types.jsexport const Set_Count = 'set_count'
然后引入这个文件,并且定义事件import { Set_Count, Set_Count_sy } from './mutation-types.js' mutations: { // 计数器 setCount(state, num = 1) { state.count += num }, [Set_Count](state, num = 1) { state.count += num },
调用// 需要先引入 mutation-types.jsstore.commit(Set_Count_sy)
这样你就可以,,,等等,我要是故意写错会给出提示吗? actions: { // 异步获取数组 getArray(context) { console.log('================================') console.log('异步getArray——context', context) setTimeout(() => { context.commit('setArray', new Date().valueOf()) }, 1000) }, // 异步获取数组 getArrayPromise(context) { return new Promise((resolve, reject) => { console.log('================================') console.log('异步 getArrayPromise ——context', context) setTimeout(() => { const time = new Date().valueOf() context.commit('setArray', time) resolve(time) }, 2000) }) }
看看参数 // 异步操作 const actionManame = () => { const store = Vuex.useStore() const getArray = store.dispatch('getArray') console.log('外部调用 getArray', getArray) getArray.then((data) => { console.log('===========') console.log('getArray 异步操作完成,返回数据:', data) console.log('===========') }) const getArrayPromise = store.dispatch('getArrayPromise') console.log('外部调用 getArrayPromise', getArrayPromise) getArrayPromise.then((data) => { console.log('===========') console.log('getArrayPromise 异步操作完成,返回数据:', data) console.log('===========') }) return { getArray, getArrayPromise } }
如果不需要知道确定的完成时间的话,可以直接调用 store.dispatch('getArray')
如果要知道的话,可以写个then store.dispatch('getArrayPromise').then((data) => { console.log('异步操作完成,返回数据:', data) })
这个用法和axios非常相似。虽然我们没有返回 promise实例的时候,外部也可以用then,但是这个是默认的,并不是我们真正执行操作后返回的。我测试了一下,里面的 setTimeout 改成十秒,结果外面的then先执行了,十秒后内部操作完毕,外面没有任何反应。
// axios,返回自己 的 new promise getData(context) { return new Promise((resolve, reject) => { axios.get('demo.json') .then((response) => { const arr = response.data.company.formItem console.log('getData - axios - response', response) // context.commit('reloadArray', response.data.company.formItem) resolve(arr) }) .catch((error) => { console.log('getData - axios - error', error) }) }) }, // axios 返回 axios的promise getData(context) { const ajax = axios.get('demo.json') ajax.then((response) => { const arr = response.data.company.formItem console.log('getData - axios - response', response) // context.commit('reloadArray', response.data.company.formItem) }) .catch((error) => { console.log('getData - axios - error', error) }) return ajax // 直接返回 axios 的promise的实例 }
调用方式 store.dispatch('getData').then((data) => { console.log('===========') console.log('getData 异步操作完成,返回数据:', data) console.log('===========') })
这样内部和外部都可以得到axios返回的数据。const user = { // namespaced: true, // 避免重名 state: () => ({ userInfo: { userId: 123, userCode: '', userNick: '' }, userRole: [] }), mutations: { setUser(state, code) { state.userInfo.userCode = code } }, getters: { getUser(state) { return state.userInfo } }, actions: { // { state, commit, rootState } setUsera (store, code) { store.commit('setUser', code) } }}export default user
const userInfo = store.state.user.userInfo
const userInfo2 = store.getters.getUser
store.commit('setUser', '要修改的数据')
store.dispatch('setUsera', '要修改的数据')
export default Vuex.createStore({ state: { count: 0, myObject: { time: '现在的时间:' }, myArray: [1,2,2,3,4] }, getters: {}, mutations: {}, actions: {}, modules: { // 注意:这个myObject会覆盖掉根的myObject。 // 设置命名空间也没有用,还是会覆盖。 // 所以要避免重名。 myObject: user, user: user, person: user }})
store.commit('user/setUser', 'user的code')store.commit('myObject/setUser', 'myObject的code')store.commit('person/setUser', 'person的code')
可以分别给每个模块的state设置内容,那么其实就是一个模块。 store.dispatch('user/setUsera', 'action的user的code')
store.getters['user/getUser']
因为有斜线,所以需要用字符串的方式来访问。关键词:使用,方法,基本