在 Vuetify 中管理 Overlay Dismissed 组件的状态

Managing State for Overlay Dismissed Components in Vuetify

我是第一次构建 vuetify/nuxt 前端,我已经将 v-navigation-drawer 组件从 default.vue 布局中移出,并移到了它自己的组件中,以便它可以在多个布局中重复使用。

这个抽屉的激活器仍然保留在 default.vue 组件中,所以我在 vuex 中添加了一个 sidebar 状态:

export const state = () => ({
    baseurl: 'http://example.com/api/',
    sidebar: false,
    authenticated: false,
    token: null,
    user: null,
})

边栏的修改器如下所示:

export const mutations = {
    toggleSidebar(state) {
        state.sidebar = !state.sidebar;
    }
}

这在打开抽屉时工作得很好,但是因为抽屉是通过点击叠加层或点击侧边栏(如果你关闭了叠加层)而关闭的,vuex 会抛出一个巨大的错误:

如何通过 vuex 使其正常工作?

不要将抽屉的模型直接绑定到 $store.state.sidebar,而是在抽屉组件中使用计算的 setter。请注意,您必须 从抽屉本身传入新值,不要只是切换商店中已有的任何内容。

<template>
  <v-navigation-drawer v-model="drawer" ...>
</template>

<script>
  export default {
    computed: {
      drawer: {
        get () {
          return this.$store.state.sidebar
        },
        set (val) {
          this.$store.commit('sidebar', val)
        }
      }
    }
  }
</script>
// vuex mutation
sidebar (state, val) {
  state.sidebar = val
}

https://vuejs.org/v2/guide/computed.html#Computed-Setter
https://vuex.vuejs.org/en/forms.html

另一种选择是将道具和事件分开绑定

<template>
  <v-navigation-drawer :value="$store.state.sidebar" @input="$store.commit('sidebar', $event)" ...>
</template>

https://vuejs.org/v2/guide/components.html#Using-v-model-on-Components

另一种解决方案是使用 vuex-map-fields 包,它为保存在 Vuex 存储中的状态启用双向数据绑定。

它使代码比正常方式(如接受的答案)更清晰、可读。

基本示例:

在您的商店文件中


// Import the `getField` getter and the `updateField`
// mutation function from the `vuex-map-fields` module.
import { getField, updateField } from 'vuex-map-fields';

export const state = () => ({
    baseurl: 'http://example.com/api/',
    sidebar: false,
    authenticated: false,
    token: null,
    user: null,
})

export const getters = {
   // Add the `getField` getter to the
   // `getters` of your Vuex store instance.
   getField,
}

export const mutations = {
   // Add the `updateField` mutation to the
   // `mutations` of your Vuex store instance.
   updateField,
}

在你的组件中

template>
  <v-navigation-drawer v-model="sidebar" ...>
</template>

<script>
import { mapFields } from 'vuex-map-fields';

export default {
  computed: {
    // The `mapFields` function takes an array of
    // field names and generates corresponding
    // computed properties with getter and setter
    // functions for accessing the Vuex store.
    ...mapFields([
      'baseurl',
      'sidebar',
      // etc...
    ]),
    }
  }
</script>

更多详情,您可以查看其githab page