ダイナミックコンポーネント、Vue.スーパーパワー


コード内のタブに遭遇した場合は、実装されている3つのことがあります
  • V IFとV - Ether
  • ネストしたルート
  • のダイナミックなコンポーネント
  • あなたが一度に1つの構成要素を条件つきで示す必要がある何かを実装しなければならない状況で、あなたがv-if and v-elseを使用することを考えているならば、ダイナミックなコンポーネントを使用することを考えてください.
    動的コンポーネントは、よく使用されている場合は、あなたのテンプレートでより少ないコードを必要とし、すべてのすべてのあなたのHTMLの条件を維持し、あなたのJavaScriptに維持するのは簡単です.
    概念はコードで最もよく説明されます、したがって、基本的にダイナミックなコンポーネントのためにユースケースの1つを例示するプロジェクトであるコード

  • インデックス.他のコンポーネント
  • のラッパーであるVue

  • 個人.個人の詳細
  • を収集するためのフォームを含むVue

  • 仕事.作業内容を収集するための形態を含むVue

  • ViewSubmit.収集されたデータ
  • を表示するためのVue
    フォーカスの主なポイントは
  • <component />
  • <keep-alive></keep-alive>
  • <component />は単一の支柱、isを必要とします、それはちょうどあなたがあなたが構築する他のカスタム構成要素のように振舞う以外に、あなたがストリングとして表示したいコンポーネントの名前です、それは他のコンポーネントのようなカスタム小道具を取ります
    コンポーネントをDOM内のすべての状態で保持することができるようにするには、keep-aliveでそれをラップすることができます.これにより、コンポーネントが切り替えられた場合、すべてのデータがそのままそのまま保持されます.
    あなたが複数のセクションにフォームを分割する方法を疑問に思っているが、まだあなたのデータを維持する場合は、これはそれを行うための一つの方法です.
    //index.vue
    <template>
      <div class="w-full p-10 flex flex-col justify-center items-center">
        <div class="p-2 w-1/2">
          <div class="flex">
            <button
              v-for="button in buttons"
              :key="button.name"
              class="flex-1 p-2 border"
              :class="{
                'bg-white text-blue-500': button.component !== currentComponent,
                'bg-blue-500 text-white': button.component === currentComponent,
              }"
              @click.prevent="setCurrentComponent(button.component)"
            >
              {{ button.name }}
            </button>
          </div>
          <div class="">
     // keep state of components 
            <keep-alive>
              <Component
                :is="currentComponent"
                :personal="personal"
                :work="work"
                :save-personal-details="savePersonalDetails"
                :save-work-details="saveWorkDetails"
                :set-current-component="setCurrentComponent"
              />
            </keep-alive>
          </div>
        </div>
      </div>
    </template>
    
    <script>
    import Personal from '@/components/Personal.vue'
    
    export default {
      components: {
        Personal,
        Work: () => import('~/components/Work.vue'),
        ViewSubmit: () => import('~/components/ViewSubmit.vue'),
      },
      data() {
        return {
          currentComponent: 'Personal',
          buttons: [
            { name: 'Personal Details', component: 'Personal' },
            { name: 'Work Details', component: 'Work' },
            { name: 'View and Submit', component: 'ViewSubmit' },
          ],
    
          personal: {},
          work: {},
        }
      },
      methods: {
        setCurrentComponent(component) {
          this.currentComponent = component
        },
        saveWorkDetails(form) {
          this.work = form
          this.currentComponent = 'ViewSubmit'
        },
        savePersonalDetails(form) {
          this.personal = form
          this.currentComponent = 'Work'
        },
      },
    }
    </script>
    
    
    ダイナミックなコンポーネントを使用するための余分なボーナスとして、すべてのあなたの小道具をすべてのコンポーネントにすべての時間を利用できるようになる、これは方法で、多くの繰り返しを節約できます.しかし、あなたが私のような場合、どの小道具がどのコンポーネントに利用可能な微調整したい場合は、特にシナリオでは、同じプロップの名前を別のデータを格納するには、この不吉な小さなトリックを使用することができます
    //index.vue optional
    <template>
      <div class="w-full p-10 flex flex-col justify-center items-center">
        <div class="p-2 w-1/2">
          <div class="flex">
            <button
              v-for="button in buttons"
              :key="button.name"
              class="flex-1 p-2 border"
              :class="{
                'bg-white text-blue-500': button.component !== currentComponent,
                'bg-blue-500 text-white': button.component === currentComponent,
              }"
              @click.prevent="setCurrentComponent(button.component)"
            >
              {{ button.name }}
            </button>
          </div>
          <div class="">
            <!-- keep state of components  -->
            <keep-alive>
              <Component :is="currentComponent" v-bind="changePropsByComponent" />
            </keep-alive>
          </div>
        </div>
      </div>
    </template>
    
    <script>
    import Personal from '@/components/Personal.vue'
    
    export default {
      components: {
        Personal,
        Work: () => import('~/components/Work.vue'),
        ViewSubmit: () => import('~/components/ViewSubmit.vue'),
      },
      data() {
        return {
          currentComponent: 'Personal',
          buttons: [
            { name: 'Personal Details', component: 'Personal' },
            { name: 'Work Details', component: 'Work' },
            { name: 'View and Submit', component: 'ViewSubmit' },
          ],
    
          personal: {},
          work: {},
        }
      },
      // focus here
      computed: {
        changePropsByComponent() {
          switch (this.currentComponent) {
            case 'Personal':
              return {
                savePersonalDetails: this.savePersonalDetails,
              }
            case 'Work':
              return {
                saveWorkDetails: this.saveWorkDetails,
                setCurrentComponent: this.setCurrentComponent,
              }
            case 'ViewSubmit':
              return {
                personal: this.personal,
                work: this.work,
              }
    
            default:
              return {}
          }
        },
      },
      // end
    
      methods: {
        setCurrentComponent(component) {
          this.currentComponent = component
        },
        saveWorkDetails(form) {
          this.work = form
          this.currentComponent = 'ViewSubmit'
        },
        savePersonalDetails(form) {
          this.personal = form
          this.currentComponent = 'Work'
        },
      },
    }
    </script>
    
    
    以下のコードは、表示されている現在のコンポーネントに基づいて小道具を返すことです.あなたの小道具をより細かく制御を得るためにこのメソッドを使用することができます
    //computed value
     changePropsByComponent() {
          switch (this.currentComponent) {
            case 'Personal':
              return {
                savePersonalDetails: this.savePersonalDetails,
              }
            case 'Work':
              return {
                saveWorkDetails: this.saveWorkDetails,
                setCurrentComponent: this.setCurrentComponent,
              }
            case 'ViewSubmit':
              return {
                personal: this.personal,
                work: this.work,
              }
    
            default:
              return {}
          }
        },
    

    //personal.vue
    <template>
      <div class="w-full p-20">
        <form @submit.prevent="savePersonalDetails(form)">
          <div class="grid grid-cols-2">
            <div class="p-2">
              <label for="name">Name</label>
              <input
                id="name"
                v-model="form.name"
                type="text"
                class="p-2 rounded border w-full"
              />
            </div>
            <div class="p-2">
              <label for="date">DOB</label>
              <input
                id="date"
                v-model="form.date"
                type="date"
                class="p-2 rounded border w-full"
              />
            </div>
            <div class="p-2">
              <label for="amount">ID Number</label>
              <input
                id="id"
                v-model="form.id"
                type="text"
                class="p-2 rounded border w-full"
              />
            </div>
            <div class="p-2">
              <label for="email">Email</label>
              <input
                id="email"
                v-model="form.email"
                type="email"
                class="p-2 rounded border w-full"
              />
            </div>
          </div>
          <div class="p-2 m-2">
            <button class="p-2 w-full bg-green-500 text-white" type="submit">
              Save and Continue <i class="fas fa-arrow-right"></i>
            </button>
          </div>
        </form>
      </div>
    </template>
    
    <script>
    export default {
      props: {
        savePersonalDetails: {
          type: Function,
          default: () => {},
        },
      },
      data() {
        return {
          form: {
            name: '',
            date: '',
            email: '',
            id: '',
          },
        }
      },
    }
    </script>
    
    

    // Work.vue
    <template>
      <div class="w-full">
        <div class="w-full p-20">
          <form @submit.prevent="saveWorkDetails(form)">
            <div class="grid grid-cols-2">
              <div class="p-2">
                <label for="company_name">Company Name</label>
                <input
                  id="company_name"
                  v-model="form.companyName"
                  type="text"
                  class="p-2 rounded border w-full"
                />
              </div>
              <div class="p-2">
                <label for="role">Role</label>
                <input
                  id="role"
                  v-model="form.role"
                  type="text"
                  class="p-2 rounded border w-full"
                />
              </div>
              <div class="p-2">
                <label for="work_adresss">Address</label>
                <input
                  id="work_adresss"
                  v-model="form.address"
                  type="text"
                  class="p-2 rounded border w-full"
                />
              </div>
              <div class="p-2">
                <label for="work_email">Email</label>
                <input
                  id="work_email"
                  v-model="form.email"
                  type="email"
                  class="p-2 rounded border w-full"
                />
              </div>
            </div>
            <div class="p-2 m-2 flex">
              <button
                class="p-2 w-full bg-gray-400 text-white m-1"
                type="button"
                @click.prevent="setCurrentComponent('Personal')"
              >
                Previous <i class="fas fa-arrow-left"></i>
              </button>
              <button class="p-2 w-full bg-green-500 text-white m-1" type="submit">
                Save and continue <i class="fas fa-arrow-right"></i>
              </button>
            </div>
          </form>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      props: {
        saveWorkDetails: {
          type: Function,
          default: () => {},
        },
        setCurrentComponent: {
          type: Function,
          default: () => {},
        },
      },
      data() {
        return {
          form: {
            companyName: '',
            role: '',
            email: '',
            address: '',
          },
        }
      },
    }
    </script>
    
    <style></style>
    
    
    

    
    // ViewSubmit.vue
    <template>
      <div class="w-full">
        <div>
          <div class="p-2 border rounded m-1">Name: {{ personal.name }}</div>
          <div class="p-2 border rounded m-1">DOB: {{ personal.date }}</div>
          <div class="p-2 border rounded m-1">Email: {{ personal.email }}</div>
          <div class="p-2 border rounded m-1">ID: {{ personal.id }}</div>
        </div>
        <div>
          <div class="p-2 border rounded m-1">
            Organization: {{ work.companyName }}
          </div>
          <div class="p-2 border rounded m-1">Role: {{ work.role }}</div>
          <div class="p-2 border rounded m-1">Email: {{ work.email }}</div>
          <div class="p-2 border rounded m-1">Address: {{ work.address }}</div>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      props: {
        work: {
          type: Object,
          default: () => {},
        },
        personal: {
          type: Object,
          default: () => {},
        },
      },
    }
    </script>
    
    
    
    私は、この助けがいくつかの新しくて面白い可能性を開くことを望みます
    このコードのためのGithubは以下の通りです
    ありがとう.😉

    reynoldadade / dynamic-components