1

私の挨拶。

文脈を説明すると、この質問をする目的は、<app-selector>Vue コンポーネントの選択されたオプションに基づいて、フォーム内の子コンポーネントを単純でばかげたものにレンダリングできるようにすることです。

簡単にするために。私が理解しようとしていることを明らかにするために、ここにスニペットを作成しました。基本的に、目的は、計算されたプロパティを使用してレンダリングされるコンポーネント名を取得することですcardTypeComponent。ただし、cardTypeComponent最初の戻り値 ( return this.form) がオブジェクト ( this.form) に必要なプロパティ( ) を与えているcard_typeのに、2 番目の戻り値 ( return this.form.card_type ? this.form.card_type + 'Compose' : '') が最初の戻り値this.form.card_typeを見てundefined、実際にはそれをundefined.

オプションが選択されると、this.formオブジェクト内の値を設定する前にサーバーからの検証プロセスがあるため、より多くのコンテキストがあります。さらに、フォームの相互作用はステップを介して行われるため、ユーザーがオプションを選択すると、ボタンをクリックして、選択したタイプカードに対応するフォームフィールドに到達する必要があるため、ユーザーが最初にコンポーネントをレンダリングすることはありません。スニペットアプローチのようにオプションを選択します。しかし、それは私が求めていることを絡ませます。事前に感謝します。

以下の Fiddle リンクを使用することをお勧めします。

スニペット

var appSelector = Vue.component('app-selector', {
  name: 'AppSelector',
  template: `<div>
               <label for="card_type">Card Type:</label>
               <select :name="name" value="" @change="sendSelectedValue">
                 <option v-for="option in options" :value="option.value">
                  {{ option.name }}
                 </option>
           </select>
             </div>`,
  props: {
    name: {
      required: false,
      type: String,
    },
    options: {
      required: false,
      type: Array,
    }
  },
  methods: {
    sendSelectedValue: function(ev) {
      this.$emit('selected', ev.target.value, this.name)
    }
  }
});

var guessByImageCompose = Vue.component({
  name: 'GuessByImageComponse',
  template: `<p>Guess By Image Compose Form</p>`
});

var guessByQuoteCompose = Vue.component({
  name: 'GuessByQuoteComponse',
  template: `<p>Guess By Quote Compose Form</p>`
});

new Vue({
  el: '#app',
  components: {
    appSelector: appSelector,
    guessByImageCompose: guessByImageCompose,
    guessByQuoteCompose: guessByQuoteCompose,
  },
  data() {
    return {
      form: {},
      card_types: [
        {
          name: 'Guess By Quote',
          value: 'GuessByQuote'
        },
        {
          name: 'Guess By Image',
          value: 'GuessByImage'
        }
      ],
    }
  },
  computed: {
    cardTypeComponent: function() {
        return this.form; // return { card_type: "GuessByImage" || "GuessByQuote" }
        return this.form.card_type ? this.form.card_type + 'Compose' : ''; // return empty string ("") Why?
    }
  },
  methods: {
    setCardType: function(selectedValue, field) {
      this.form[field] = selectedValue;
      console.log(this.form.card_type); // GuessByImage || GuessByQuote
      console.log(this.cardTypeComponent); // empty string ("") Why?
    }
  },
  mounted() {
    console.log(this.cardTypeComponent); // empty string ("")
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <form action="#" method="post">
    <app-selector
      :name="'card_type'" 
      :options="card_types"
      @selected="setCardType"
    >
    </app-selector>
    {{ cardTypeComponent }} <!-- Always empty string !-->
    <component v-if="cardTypeComponent !== ''" :is="cardTypeComponent">
      
    </component>
  </form>
</div>

https://jsfiddle.net/k7gnouty/2/

4

1 に答える 1

1

this.formで最初に初期化されていないプロパティを設定していますdataこれは、Vue の変更検出の警告に遭遇したことを意味します。Vue.set設定するときに使用します。

methods: {
  setCardType: function(selectedValue, field) {
    Vue.set(this.form, field, selectedValue);
  }
}

または、それがうまく機能する場合は、最初にプロパティを宣言することもできます。

于 2020-11-18T13:20:15.303 に答える