Vuejs 中的状态突变

State mutation in Vuejs

我正在使用 vuetifyvuejs 来使用 <v-navigation-drawer> 组件向我的网络应用程序添加侧边栏。一切都按预期工作,但是,当我在侧边栏组件外部单击时,我收到有关变异状态的警告(drawer 变量)。如果我使用添加到其中的按钮关闭边栏,则不会发生警告。您可以在此处看到警告: warning regarding state

你可以在这里看到我的代码:

// sidebar.vue

<template>
  <v-navigation-drawer
    v-if="li"
    v-model="drawer"
    clipped="clipped"
    app
    height="100vh"
    floating
    disable-route-watcher
    fixed
    temporary
  >
    <v-list-item class="px-2">
      <v-list-item-avatar>
        <v-img src="/assets/logo.svg" contain alt="logo"></v-img>
        <!-- <v-icon>mdi-account</v-icon> -->
      </v-list-item-avatar>
      <v-list-item-title>{{ username }}</v-list-item-title>
      <v-btn icon @click.stop="toggleDrawer">
        <v-icon>mdi-chevron-left</v-icon>
      </v-btn>
    </v-list-item>
    <v-divider></v-divider>
    <v-list dense>
      <v-list-item
        v-for="item in items"
        :key="item.title"
        link
        @click="changeRoute(item.route)"
      >
        <v-list-item-icon>
          <v-icon>{{ item.icon }}</v-icon>
        </v-list-item-icon>
        <v-list-item-content>
          <v-list-item-title>{{ item.title }}</v-list-item-title>
        </v-list-item-content>
      </v-list-item>
    </v-list>
    <v-spacer></v-spacer>
    <v-list dense style="position: absolute; bottom: 0; width: 100%">
      <v-list-item @click="logout">
        <v-list-item-icon>
          <v-icon>mdi-logout-variant </v-icon>
        </v-list-item-icon>
        <v-list-item-content>
          <v-list-item-title>Sign out</v-list-item-title>
        </v-list-item-content>
      </v-list-item>
      <v-list-item @click="toggleDarkMode">
        <v-list-item-icon>
          <v-icon>mdi-theme-light-dark </v-icon>
        </v-list-item-icon>
        <v-list-item-content>
          <v-list-item-title>{{ darkModeButtonText }}</v-list-item-title>
        </v-list-item-content>
      </v-list-item>
    </v-list>
  </v-navigation-drawer>
</template>

<script lang="ts">
import { Vue, Component, Prop, Emit } from "vue-property-decorator";

@Component
export default class Sidebar extends Vue {
  @Prop() li!: boolean; // li = Logged In
  @Prop() username!: string;
  @Prop() darkModeButtonText!: string;
  @Prop() darkModeState!: boolean;
  @Prop() drawer!: boolean;
  @Prop() clipped!: boolean;

  @Emit("toggleDarkMode")
  toggleDarkMode() {
    return;
  }

  @Emit("logout")
  logout() {
    console.log(""); // method needs something in to avoid prettier rules, doesn't need to do anything, just emits
  }

  @Emit("toggleDrawer")
  toggleDrawer() {
    return;
  }

  changeRoute(newPath: string) {
    if (this.$route.path !== newPath) {
      this.$router.push(newPath);
    }
    return;
  }

  data() {
    return {
      items: [
        {
          title: "New Assessment",
          icon: "mdi-molecule-co2",
          route: "/assessment",
        },
        { title: "Home", icon: "mdi-home", route: "/landing" },
        { title: "About", icon: "mdi-information-outline", route: "/about" },
      ],
    };
  }
}
</script>

drawer 变量在 sidebar.vue 的父组件的 data() 中定义,我正在使用 @Emit 来更改变量状态(toggleDrawer() 函数)。

我做的有什么明显的错误吗?我正在按照示例 HERE

我应该提到我是 vuejs 和 vuetify 的新手。

提前致谢。

改变 parent 数据的正确方法是向它发送一条消息,让 'owns' 数据改变它的组件。 v-model 通常只是 :value@input 的糖,所以替换并转发。

边栏

prop 添加到名为 drawer

的边栏
<v-navigation-drawer
    v-if="li"
    :value="drawer"
    @input="$emit('update:drawer', $event)"
props: {
  drawer:{}
}

parent

<sidebar :drawer='drawer' @update:drawer='drawer=$event' />
data() {
 return {
   drawer: false
 }
}

其他选项

您还可以使用响应式存储,例如 Vuex 来保存值,然后您的消息和绑定将被定向到存储而不是发送到 parent。