试图将道具与V模型结合



我正在使用vuetify.js,并尝试创建一个可以在整个应用程序中重复使用的组件。尽管它的工作原理绝对很好,但我不确定这是正确的方法。

我正在创建一个始终具有相同菜单选项的导航抽屉组件,但可以从UI元素打开。

以下是代码。

//navigationbar.vue

<template>
  <v-navigation-drawer
    temporary
    v-model="drawerFlag"
    light
    overflow
    fixed
  >
    <v-list>
      <v-list-tile>
        <v-list-tile-action @click.stop="toggleDrawer()">
          <v-btn icon>
            <v-icon>close</v-icon>
          </v-btn>
        </v-list-tile-action>
      </v-list-tile>
    </v-list>
    <v-list class="pt-0">
      <template v-for="item in items">
        <v-list-tile :key="item.title" :to="item.link">
          <v-list-tile-action>
            <v-icon>{{ item.icon }}</v-icon>
          </v-list-tile-action>
          <v-list-tile-content>
            <v-list-tile-title>{{ item.title }}</v-list-tile-title>
          </v-list-tile-content>
        </v-list-tile>
        <v-divider></v-divider>
      </template>
    </v-list>
  </v-navigation-drawer>
</template>
<script>
  export default {
    props: ['drawer'],
    data() {
      return {
        items: [
          { title: 'Home', icon: 'home', link: '/home'},
          { title: 'History', icon: 'history', link: '/history' },
          { title: 'Wallet', icon: 'account_balance_wallet', link: '/wallet' },
          { title: 'My Profile', icon: 'person', link: '/profile' },
          { title: 'Settings', icon: 'settings', link: '/settings' },
          { title: 'About', icon: 'error', link: '/about' },
          { title: 'Logout', icon: 'power_settings_new', link: '/logout' },
        ]
      };
    },
    computed: {
      drawerFlag: {
        get: function() {
          return this.drawer
        },
        set: function() {
        }
      }
    },
    methods: {
      toggleDrawer: function() {
        this.$emit('emitToggleDrawer');
      }
    }
  }
</script>

//home.vue

<template>
  <div class="full-screen">
    <navigation-bar :drawer="drawer" v-on:emitToggleDrawer="toggleDrawer"></navigation-bar>
    <v-btn icon class="mt-3 fixed-position" @click.stop="drawer = !drawer">
      <v-icon>menu</v-icon>
    </v-btn>
  </div>
</template>
<script>
  export default {
    name: 'home',
    data() {
      return {
        drawer: null
      };
    },
    computed: {
      user() {
        return this.$store.getters.user;
      }
    },
    methods: {
      toggleDrawer: function () {
        this.drawer = !this.drawer;
      }
    }
  };
</script>

在上述代码中。

在父组件中,我有按钮可以打开导航 - 抽屉,并且导航抽屉的状态在称为"抽屉"的父组件中维护。然后,我将"抽屉"传递给儿童组件的道具,以及一种从子组件到父母组件触发事件的方法,称为" emittoggledrawer"。

在儿童组件中,我使用的是Vuetify.js导航 - 吸引V-Model =" drawerflag",其中抽屉是计算属性。当我尝试使用v-model ="抽屉"时,即绑定到道具我会遇到错误。然后,我们可以通过单击导航抽屉内的元素来关闭导航抽屉。为了实现这一目标,我正在调用一种组件的方法,该方法后来在发出的事件上发出,该事件由父部件收听。

我这样解决了:

app.vue

<my-drawer ref="drawer"></my-drawer>
<my-header @toggle-drawer="$refs.drawer.drawer = !$refs.drawer.drawer"></my-header>

mydrawer.vue

<v-navigation-drawer v-model="drawer">
...
data() {
  drawer: true
}

myheader.vue

<v-toolbar-side-icon @click.stop="$emit('toggle-drawer')"></v-toolbar-side-icon>

在我看来,我们在自定义抽屉组件上需要`v-model ="抽屉"`,以便它可以在所有屏幕尺寸上正确使用。

因此,我们需要以某种方式从父(或同级)更改其值,这就是为什么我在抽屉组件上使用ref的原因。也许不是更改$refs.drawer.drawer数据,而是可以调用抽屉功能。我不确定什么会更好。但这是在所有屏幕尺寸上都适合我的唯一简单解决方案。

因此,在我的情况下,我只从标题上更改抽屉状态,但是我认为您可以使用它并根据需要进行适合。

i解决了以下类似的问题。

  • 仅使用drawer而不是使用drawerdrawerFlag
  • 在儿童组件上没有额外的按钮
  • 没有从孩子到父母发射event
  • 在儿童组件中使用watch

home.vue

<template>
  <div class="full-screen">
    <navigation-bar :drawer="drawer"></navigation-bar>
    <v-btn icon class="mt-3 fixed-position" @click.stop="drawer = !drawer">
      <v-icon>menu</v-icon>
    </v-btn>
  </div>
</template>
<script>
  import NavigationBar from '@/components/NavigationBar';
  export default {
    name: 'home',
    data() {
      return {
        drawer: true
      };
    },
    components: {
      NavigationBar
    }
  }
</script>

navigationbar.vue

<template>
  <v-navigation-drawer
    temporary
    v-model="drawer"
    light
    overflow
    fixed
  >
    <v-list class="pt-0">
      <template v-for="item in items">
        <v-list-tile :key="item.title" :to="item.link">
          <v-list-tile-action>
            <v-icon>{{ item.icon }}</v-icon>
          </v-list-tile-action>
          <v-list-tile-content>
            <v-list-tile-title>{{ item.title }}</v-list-tile-title>
          </v-list-tile-content>
        </v-list-tile>
        <v-divider></v-divider>
      </template>
    </v-list>
  </v-navigation-drawer>
</template>
<script>
  export default {
    props: ['drawer'],
    data() {
      return {
        items: [
          { title: 'Home', icon: 'home', link: '/home'},
          { title: 'History', icon: 'history', link: '/history' },
          { title: 'Wallet', icon: 'account_balance_wallet', link: '/wallet' },
          { title: 'My Profile', icon: 'person', link: '/profile' },
          { title: 'Settings', icon: 'settings', link: '/settings' },
          { title: 'About', icon: 'error', link: '/about' },
          { title: 'Logout', icon: 'power_settings_new', link: '/logout' },
        ]
      };
    },
    watch: {
       drawer (value) {
          return value;
       }
    }
  }
</script>

最新更新