【Vue】011. Vuex状态管理(三)

296 阅读3分钟

01. Vuex插件

(1)如何使用

  • Vuex 插件是一个函数,接收 store 作为唯一参数

  • 在Vuex插件中,我们可以监听组件中提交的 mutationaction方法

    // 创建插件
    const myPlugin = store => {
        // do something
    }
    // 使用插件
    const store = new Vuex.Store({
        // ...
      plugins: [ myPlugin ]
    })
    
    // 外部定义
    export default function createPlugin(params) {
        return store => {
            // do something
        }
    }
    // 外部引入
    import createPlugin from './plugin.js'
    const myPlugin = createPlugin()
    const store = new Vuex.Store({
        // ...
        plugins: [myPlugin]
    })
    

(2)怎么监听提交事件?

  • 可以使用subscribe监听组件中提交的mutation,使用subscribeAction监听组件中提交的action

    这两个方法都可以接受两个参数,分别是mutation,stateaction,state

    同样的,在插件内部也只能通过mutation来提交更改state中的数据

    export default function createPlugin(params) {
        return store => {
            // 使用 subscribe 监听 mutation,有改变就执行内部的方法
            store.subscribe((mutation, state) => {
                console.log(mutation.type) // 提交的 mutation 的名称
                console.log(mutation.payload) // 提交的 mutation 的参数
                console.log(state) // State状态
            })
            store.subscribeAction((action, state) => {
               console.log(action.type) // 提交的 action 的名称
               console.log(action.payload) // 提交的 action 的参数
            })
            store.subscribeAction({
                // 提交 action 之前
                before: (action, state) => {
                    console.log(`before action ${action.type}`)
                },
                // 提交 action 之后
                after: (action, state) => {
                    console.log(`after action ${action.type}`)
                }
            })
        }
    }
    

02. Vuex的严格模式

(1)概念

  • 在严格模式下,无论何时发生了状态变更,只要不是由 mutation函数提交的,都会抛出错误
    • 这样可以保证所有的状态变更都能被调试工具跟踪到

(2)开启

  • 在Vuex.Store 构造器选项中开启,如下

    const store = new Vuex.Store({
        strict: true,
        state: {
            count: 1
        }
    })
    
    state.count = 2; // 严格模式下报错,不是通过 mutations 更改的
    

03. 表单处理

(1)问题

  • 表单的问题在于使用v-model时候
    • v-model会试图直接修改 state,而 Vuex 在严格模式下是不允许直接修改 state 的

(2)解决

  • 方法一:修改v-model指令

    • value属性绑定从 store 中映射来的计算属性
    • 然后监听input事件,用 commitmutation 的方式,来修改 store 里的 state
    <input :value="message" @input="updateMessage" />
    
    <script>
        export default {
            computed: {
                ...mapState(['message']) // 映射state数据
            },
            methods: {
                // 修改 input 方法,通过提交 mutation 来更新数据
                updateMessage (e) {
                    this.$store.commit('updateMessage', e.target.value)
                }
            }
        }
    </script>
    
  • 方法二:扩展计算属性

    export default {
        computed: {
            message: {
                get () {
                    return this.$store.state.message
                },
                set (value) {
                    this.$store.commit('updateMessage', value)
                }
            }
        }
    }
    

04. 其它问题

(1)关于Ajax请求

  • Ajax请求代码应该写在methods中还是vuex的actions中?
    • 如果请求的数据不会被其他组件公用,而仅在请求的组件内使用,就不需要放入action
    • 如果需要复用,就放入action里,方便其它组件使用
      • 包装成promise返回,在调用处通过async/await处理返回的数据

(2)Vuex刷新页面数据丢失?

  • Vuex 的数据是保存在运行内存中的,当页面刷新时,页面会重新加载Vue实例,这个时候Vuex中的数据就会被重新赋值

  • 解决办法:

    • (1)可以将数据保存在浏览器缓存中。如:sessionStoragelocalStorage
    • (2)可以在页面刷新时,再次请求远程数据,动态更新Vuex数据

(3)不用Vuex会带来什么问题?

  • 方便开发和后期维护,可以集中管理数据

  • 高效实现组件通信,提高开发效率

  • 可以响应式的更新数据


本人前端小菜鸡,如有不对请谅解 (PS:补昨天)