在基于组件的框架中提取组件方法&终极版

时间:2017-10-01 10:05:31

标签: reactjs vue.js redux vue-component vuex

在React或Vue中,我遇到以下情况:类似的组件,例如处理登录的模态对话框(表单)和处理注册的模态对话框,具有以下共同点:< / p>

  1. 处理关闭模态对话框的按钮
  2. 单击时执行表单验证的按钮
  3. 根据验证结果显示的错误消息。
  4. 鉴于上述情况,我假设可能有一个基本组件或组件,其中传递了道具来定义其视觉风格和功能。

    我的问题是双重的:

    1 /当使用Redux(Vuex)架构时,您是否希望为每个版本的Modal Dialog保持一个单独的状态?和 2 /您如何实际避免代码重复?

    e.g。

    state: {
        items: [
        ],
        loginDialog: {
          isValid: true,
          isVisible: false,
          errorMsg: '',
        },
        signupDialog: {
          isValid: true,
          isVisible: false,
          errorMsg: '',
        }, 
    }
    

    在我看来,Redux架构能够分别调试应用程序的每一个部分,经常与组件/容器的构建方式相冲突。

    说明问题的Vuex组件(问题不是绝对必要的):

    <template>
      <v-dialog width="600"
                v-model="isVisible"
                persistent>
        <v-card>
          <v-card-title>
            <span class="headline">Register</span>
          </v-card-title>
          <v-card-text>
            <v-form v-model="valid">
    // form here           
            </v-form>
          </v-card-text>
          <v-alert v-if="!signupDialog.isValid" error value="true">
            {{ signupDialog.errorMsg }}
          </v-alert>
          <v-card-actions>
            <v-spacer></v-spacer>
            <v-btn class="blue--text darken-1"
                   flat
                   @click="toggleDialog()">Close
            </v-btn>
            <v-btn class="blue--text darken-1"
                   flat
                   @click="submitRegisterForm(signup)">Save
            </v-btn>
          </v-card-actions>
        </v-card>
      </v-dialog>
    </template>
    
    <script>
      import { mapState } from 'vuex';
    
      export default {
        name: 'signup',
        computed: {
          ...mapState([
            'signupDialog',
          ]),
          isVisible: {
            get() {
              return this.$store.state.signupDialog.isVisible;
            },
            set() {
              this.toggleDialog();
            },
          },
        },
        methods: {
          toggleDialog() {
            this.$store.dispatch('toggleDialog', { dialog: 'signupDialog' });
          },
        },
      };
    </script>
    

1 个答案:

答案 0 :(得分:0)

我在过去的项目中面对这个问题,我创建了1个函数来初始化状态以减少代码重复:

function initDialogState: () => ({
  isValid: true,
  isVisible: false,
  errorMsg: '',
})

state: {
    items: [
    ],

    dialog: {
      login: initDialogState(),
      signup: initDialogState(),
   }
}

然后你的突变可以(我将在Vuex结构中创建一个例子):

setDialog(state, { kind, type, value }) {
  Vue.set(state[kind], type, value)
}