代码之家  ›  专栏  ›  技术社区  ›  Tanmay

重构vue单文件组件

  •  1
  • Tanmay  · 技术社区  · 7 年前

    .vue 文件很大(800行+)。所以为了保持组件的干净,我尝试将对话框转换成专用的子组件( mydialog ). 我正在使用vuetify(不需要熟悉vuetify)。

    dialog v-model 它只在第一次起作用 . 那是因为当我点击 close 按钮,它改变了 的值 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/vue@2.5.17/dist/vue.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.2.0/vuetify.min.js"></script>
    </body>
    
    </html>
    1 回复  |  直到 7 年前
        1
  •  2
  •   FK82    7 年前

    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;
          },
        },
      }
    

    第一个改变就是 应用程序 dialog 道具 我的对话 .

    我添加了一个数据属性 dialog$ 这反映了 对话 道具(因为道具是不变的,不应该改变)。观察者会注意到 更新 . 这个 onClose 对话框$ 当对话框关闭并向订阅服务器(特别是 应用程序 ).

    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/vue@2.5.17/dist/vue.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.2.0/vuetify.min.js"></script>
    </body>
    
    </html>

    正如@raina77ow所提到的,您也可以使用 event bus 但在这种情况下没有必要。