重构vue单个文件组件

坦美

随着单个文件组件变得越来越大,我尝试对其进行一些重构。原来,我有几个对话框使.vue文件变得巨大(800行以上)。因此,为了保持组件的清洁,我试图将对话框变成专用的子组件(mydialog)。我正在使用vuetify(不需要熟悉vuetify)。

我在父组件中有一个启用对话框的按钮。我将dialog道具发送到子组件,然后将其附加到v-model对话框的。问题是,它只能在第一次使用那是因为当我单击该close按钮时,它将dialog的值更改为false并且false由于子组件与父组件失去了联系,它将永远存在在这种情况下,我该如何解决?

这是代码段:

Vue.component('mydialog', {
  props:{
    dialog: {
      type: Boolean,
      default: false
    }
  },

  template: `
<div class="text-xs-center">
    <v-dialog
      v-model="dialog"
      width="500"
    >

      <v-card>
        <v-card-title
          class="headline grey lighten-2"
          primary-title
        >
          A Dialog
        </v-card-title>

        <v-card-text>
          Lorem ipsum dolor sit amet,
        </v-card-text>

        <v-divider></v-divider>

        <v-card-actions>
          <v-spacer></v-spacer>
          <v-btn
            color="primary"
            flat
            @click="dialog = false"
          >
            Close
          </v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
  </div>
`,
  data: function() {
    return {
      // dialog: false,
    }
  }

});

new Vue({
  el: '#app',
  data: {
    dialog: false
  }

});
<!doctype html>
<html>

<head>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.2.0/vuetify.min.css" />
</head>

<body>
  <div id="app">
    <v-app id="inspire">
      <v-btn color="red lighten-2" dark @click="dialog=true">Click Me</v-btn>
      <mydialog :dialog="dialog"></mydialog>
    </v-app>

  </div>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.2.0/vuetify.min.js"></script>
</body>

</html>

FK82

您的组件通讯有点中断:基本上,您的对话框没有通知应用程序组件它已关闭。以下两项更改可启用模式与应用程序之间的上游通信:

app模板中:

  <mydialog :dialog.sync="dialog"></mydialog>

mydialog控制器中:

data: function() {
    return {
      dialog$: false,
    };
  },
  methods: {
    onClose() {
      this.dialog$ = false;
      this.$emit('update:dialog', this.dialog$);
    },
  },
  watch: {
    dialog: {
      immediate: true,
      handler() {
        this.dialog$ = this.dialog;
      },
    },
  }

第一个更改使app组件侦听有关dialog道具的更新mydialog

mydialogdialog$其中添加了一个反映dialog道具的数据属性(因为道具被认为是恒定的,不应更改)。观察者要确保下游在dialogupdate上进行更新dialog$onClose方法dialog$在关闭对话框时更新,并向订阅者(特别是app发出更新

Vue.component('mydialog', {
  props:{
    dialog: {
      type: Boolean,
      default: false
    }
  },

  template: `
<div class="text-xs-center">
    <v-dialog
      v-model="dialog$"
      width="500"
    >

      <v-card>
        <v-card-title
          class="headline grey lighten-2"
          primary-title
        >
          A Dialog
        </v-card-title>

        <v-card-text>
          Lorem ipsum dolor sit amet,
        </v-card-text>

        <v-divider></v-divider>

        <v-card-actions>
          <v-spacer></v-spacer>
          <v-btn
            color="primary"
            flat
            @click="onClose"
          >
            Close
          </v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
  </div>
`,
  data: function() {
    return {
      dialog$: false,
    };
  },
  methods: {
    onClose() {
      this.dialog$ = false;
      this.$emit('update:dialog', this.dialog$);
    },
  },
  watch: {
    dialog: {
      immediate: true,
      handler() {
        this.dialog$ = this.dialog;
      },
    },
  }
});

new Vue({
  el: '#app',
  data: {
    dialog: false
  },
  template: `
    <v-app id="inspire">
      <v-btn color="red lighten-2" dark @click="dialog=true">Click Me</v-btn>
      <mydialog :dialog.sync="dialog"></mydialog>
    </v-app>
  `,

});
<!doctype html>
<html>

<head>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.2.0/vuetify.min.css" />
</head>

<body>
  <div id="app"></div>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.2.0/vuetify.min.js"></script>
</body>

</html>


正如@ raina77ow所提到的,您也可以使用事件总线解决此类问题,但在这种情况下不是必须的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章