首页 文章

Vue VUEX打字稿Vue路由器 . 组件未被破坏

提问于
浏览
2

Vue.js版本= 2.3.3

向大家提问 . 我有json,其中包含一个数据列表,基于json我创建表单输入 . 表单输入有一个绑定的模型,它基本上通过提交更新应用程序状态 .

我有一个组件,它呈现一个复选框列表,在一个页面上我有1个实例,在下一个页面上我有3个组件实例,每个都有他们的复选框列表和一个不同的名称 .

从第1页到第2页时,第1页的checkbox_list组件不会触发已销毁的生命周期挂钩(其他组件会触发此操作) .

在第2页,我有其他3个类型为checkbox_list的组件及其名称,型号和选项 . ( data 初始化为函数) . 不知何故,类型复选框列表的第三个组件不会触发 created 挂钩,无论是挂载还是w / e . 它被渲染,但没有激发创建的生命周期钩子)模型包含我在checkbox_list组件实例的第一页上检查的所有内容 .

在解析数据时,组件基本上呈现在循环中 . 任何人都有任何想法为什么会这样?谢谢 .

请参阅我的组件的下面的代码 . InputTypes.ts

import Vue from 'vue';
import Component from 'vue-class-component';

import TextInput from './text/TextInput.vue';
import EmailInput from './email/EmailInput.vue';
import RadioGroup from './radio/RadioGroup.vue';
import SelectInput from './select/SelectInput.vue';
import SelectAutocompleteInput from './select/SelectAutocompleteInput.vue';
import PasswordInput from './password/PasswordInput.vue';
import CheckboxGroup from './checkbox/CheckboxGroup.vue';
import AgreementSection from './custom/AgreementSection.vue';
import CvSection from './custom/CVSection.vue';
import SubmitSection from './custom/SubmitSection.vue';


@Component({
  name: 'input-types',
  props: ['field', 'lastPageIndex'],
  components: {
    TextInput,
    EmailInput,
    RadioGroup,
    SelectInput,
    SelectAutocompleteInput,
    PasswordInput,
    AgreementSection,
    CheckboxGroup,
    CvSection,
    SubmitSection
  },
  watch: {
    '$route'($to, $from) {
      let clearFields = this['clearFields'];
      clearFields();
    }
  }
})

export default class InputsTypes extends Vue {
  conditionalFields: object = {fields: []};

  clearFields(): void {
    this.$set(this.conditionalFields, 'fields', []);
  }

  changeHandler(fields): void {
    this.$set(this.conditionalFields, 'fields', fields);
  }

  updateModelValue(data): void {
    console.log(data);
  }
}

InputTypes.vue

<!-- InputTypesComponent -->
<template>
  <div>
    <text-input v-if="field.type == 'text'" :field="field"></text-input>

    <email-input v-else-if="field.type == 'email'" :field="field"></email-input>

    <checkbox-group v-else-if="field.type == 'checkbox_list'" :field="field"></checkbox-group>

    <radio-group v-else-if="field.type == 'radio'" :field="field" :onChange="changeHandler"></radio-group>

    <select-input  v-else-if="field.type == 'select'" :field="field" :onChange="changeHandler"></select-input>

    <select-autocomplete-input  v-else-if="field.type == 'select_autocomplete'" :field="field" :onChange="changeHandler"></select-autocomplete-input>

    <password-input v-else-if="field.type == 'password'" :field="field"></password-input>

    <agreement-section v-else-if="field.type == 'agreement'" :field="field"></agreement-section>

    <div v-else-if="field.type == 'complex_inputs'">
      <label>{{field.label}}</label>
      <div v-for="option, key in field.options" :key="key">
        <input-types :field="option" :onChange="changeHandler"></input-types>
      </div>
    </div>
    <cv-section v-else-if="field.type == 'cv_section'" :field="field"></cv-section>
    <submit-section v-else-if="field.type == 'next_page'" :field="field" :lastPageIndex="lastPageIndex"></submit-section>

    <div v-if="conditionalFields.fields" v-for="field, key in conditionalFields.fields" :key="key">
      <input-types :field="field" :onChange="changeHandler"></input-types>
    </div>
  </div>
</template>

<script lang="ts">
  import InputsTypes from './InputsTypes.ts'
  export default InputsTypes
</script>

CheckboxGroup.ts

import Vue from 'vue';
import Component from 'vue-class-component';


@Component({
  name: 'checkbox-group',
  props: ['field'],
  watch: {
    selected: (e) => {
      console.log(e);
    }
  },
  created(): void {
    let predefinedSelected: Array<string> = [];
    let data: object = {
      'name': this.$props.field.name,
      'value': predefinedSelected
    };

    let updateState = this['updateState'];
    updateState(data);
  }
})

export default class CheckboxGroup extends Vue {
  updateStore(): void {
    let data: object = {
      'name': this.$props.field.name,
      'value': this['selected']
    };
    this.updateState(data);
  }

  updateState(data): void {
    this.$store.commit('SIMPLE_FIELD_UPDATE', data);
  }

  data(): object {
    let predefinedSelected: Array<string> = this.$props.field.selected || [];
    return {
      selected: []
    }
  }
  created(): void {
    console.log('created');
  }
  mounted(): void {
    console.log('mounted');
  }
  destroyed(): void {
    console.log('destroyed');
  }
}

CheckboxGroup.vue

<template>
  <div class="checkbox-group">
    <div class="row" v-if="field.label">
      <div class="col">
        {{field.label}}
      </div>
    </div>
    <div class="row">
      <div class="form-check col-3" v-for="option, key in field.options" :key="key">
        <label class="form-check-label">
          <input class="form-check-input" v-model="selected" @change="updateStore" type="checkbox" :name="field.name" :value="option.label"/>
          {{option.label}}
        </label>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
  import CheckboxGroup from './CheckboxGroup.ts'
  export default CheckboxGroup
</script>

3 回答

  • 0

    这是一个可变组件的好地方,允许您拥有可以在运行时根据数据更改表单的组件 .

    因此,您需要将复合类型添加到自己的组件中,然后再使用集合组件 input-types

    <component :is="field.type" :field="field"></component>
    

    无论你在哪里使用

    <input-types :field="field"></input-types>
    

    您需要确保field.type与您的组件标签匹配 . 所以对于 text-input 组件,field.type必须是 text-input .

    如果您需要任何帮助,请告诉我们 .

  • 0

    这是一个非常庞大的描述/代码集,试图阅读/理解真正的问题是什么 . 我可能建议将来尽可能简单地尝试描述/情况 .

    我相信你的问题的根源可能与v-for和v-if在同一元素上的交互有关 . v-if语句将重新评估该v-for元素上的每个循环 . 最简单的答案是在你希望v-for运行的东西上面的 <template> 元素上执行你的v-if .

    https://vuejs.org/v2/guide/list.html#v-for-with-v-if

  • 1

    问题很容易解决 . 问题是我正在基于URL更改视图,并呈现不同的组件,但其中一些在视图中是持久的,因此Vue认为这些组件与先前视图中所需的组件相同 . 为了解决这个问题,我只是将 key 传递给了Page组件,因此在这种情况下它被视为一个不同的组件,并且在Page组件内部没有浅层比较 .

    Conclusion :别忘了钥匙男女生 .

相关问题