Vueコンポーネントの3つのコア概念を深く理解する

10075 ワード

title:Vueコンポーネントの3大コア概念date:2019-06-25 11:00:07 tags:[vue]categories:Vueコンポーネントの3大コア概念を深く理解する
Vueコンポーネントの3つのコア概念を深く理解する
前言本文は主に属性、イベントとスロットの3つのvue基礎概念、使用方法と無視されやすいいくつかの重要な詳細を紹介する.他の人が書いたコンポーネントを読むか、この3つの部分から展開すると、1つのコンポーネントのすべての機能を迅速に理解することができます.
一、属性
1.カスタム属性props
propは、このコンポーネントにどのような構成可能な属性があるかを定義し、コンポーネントのコア機能も決定します.汎用コンポーネントを書く場合、propsはオブジェクトの書き方が望ましい.これにより、各プロパティに対してタイプ、デフォルト値、またはカスタム検証プロパティの値を設定することができる.これはコンポーネント開発において重要であるが、多くの人は無視し、propsの配列用法を直接使用する.このようなコンポーネントは厳密ではないことが多い.
//    
 
  
//    
  props: {
    name: String,
    type: {
   //       type,          'success', 'warning', 'danger'    ,           ,        
      validator: (value) => {
        return ['success', 'warning', 'danger'].includes(value)
      }
    },
    onChange: {
    //       ,         ,           
      type: Function,
      default: () => { }
    },
    isVisible: {
      type: Boolean,
      default: false
    },
    list: {
      type: Array,
      //                    
      default: () => []
    }
  }

上記の例から、propsは、1つまたは複数のデータを定義することを表示することができ、受信したデータに対しては、様々なデータ型であってもよく、同じように1つの関数を伝達することもできる.一般的な属性によって親対子通信を実現する.関数プロパティによる子の親への通信
2. inheritAttrs
これは2.4.0に追加されたAPIです.デフォルトでは、親ドメインのpropsとは認められないプロパティバインドが「ロールバック」され、サブコンポーネントのルート要素に通常のHTMLプロパティとして適用されます.これらのデフォルトの動作は、inheritAttrsをfalseに設定することで削除できます.注意:このオプションはclassとstyleバインドに影響しません.前の例では、titleプロパティがサブコンポーネントpropsで宣言されていない場合、次の図に示すように、サブコンポーネントのルート要素にデフォルトで掛けられます.
3.dataとpropsの違い
同じ点の両方のオプションには、さまざまなタイプのデータが格納されます.動作操作が変更されると、すべての動作操作で使用されるデータとテンプレートでレンダリングされるデータが同期して変化します.
異なるポイントdataは動的データと呼ばれ、それぞれのインスタンスでは、環境に影響されずに任意にデータ型とデータ構造を変更することができます.
propsは静的データと呼ばれ、それぞれの例では、初期化が定義されたタイプの場合、Vueベースは一方向データストリームであり、データ伝達時には常にそのデータ型を変更することができず、サブコンポーネントで伝達されたpropsデータを直接操作することは許されず、他の手段で伝達元のデータを変更する必要がある.どのように変更するかについては、次に詳しく説明します.
4.一方向データストリーム
この概念はコンポーネント通信に現れる.propsのデータは、親コンポーネントまたはより高いレベルのコンポーネントデータまたは字面量によって伝達され、それぞれのインスタンスのpropsデータを直接操作して変更することは許されず、他の手段によって伝達元のデータを変更する必要がある.もし私たちが伝えられたpropを修正したい場合、どのような方法がありますか?
方法1:dataオプションへの移行
サブコンポーネントのdataにpropをコピーし、dataは変更できます.
export default {
  props: {
    type: String
  },
  data () {
    return {
      currentType: this.type
    }
  }
}

dataオプションでcurrentTypeでprops中のtypeデータを受信することは、currentType=typeに対して付与操作を行うことに相当し、currentTypeのデータを取得するだけでなく、currentTypeデータを変更することもできる.
方法2:計算属性を利用する
export default {
  props: {
    type: String
  },
  computed: {
    normalizedType: function () {
      return this.type.toUpperCase();
    }
  }
}

以上の2つの方法は、サブコンポーネントでpropsの値を間接的に変更することができますが、サブコンポーネントがデータを変更し、親コンポーネントに同期的に更新したい場合は、何の役にも立ちません.場合によっては、1つのpropを「双方向バインド」する必要がある場合があります.この場合、次の2つの方法を推奨します.
方法3:使用.sync
//    



import Demo from "./demo.vue";
export default {
  name: "Hello",
  components: {
    Demo
  },
  data() {
    return {
      show: false,
      msg: "    model ",
      arr: [1, 2, 3]
    };
  }
};

//    


export default {
  props: {
    msg: {
      type: String
    },
    show: {
      type: Boolean
    },
    arr: {
      type: Array //                        
    }
  },
  methods: {
    closeModel() {
      this.$emit("update:show", false);
    }
  }
};

</code></pre> 
  <p>        props      msg   show    ,   .sync    ,      。</p> 
  <p>  .sync   ,     ,  :</p> 
  <p>1)          ( v-bind:title.sync="doc.title + ‘!’“    );<br> 2)          ( v-bind.sync=”{ title: doc.title }"        )。</p> 
  <h6>  4:                   </h6> 
  <p>      JavaScript               ,               prop   ,                           。                      arr,          。</p> 
  <ol start="5"> 
   <li>               v-bind?<br>             ,                             v-bind      。</li> 
  </ol> 
  <p>v-bind:msg = ‘msg’</p> 
  <p>     v-bind                      ,              ,                 (          )。</p> 
  <p>msg=’    ’</p> 
  <p>      v-bind              ,         String   ,     。                ,      String  ,  props     v-bind,        ,             ,           。</p> 
  <p>:msg=‘11111’ //Number<br> :msg=‘true’ //Bootlean<br> :msg=’()=>{console.log(1)}’ //Function<br> :msg=’{a:1}’ //Object</p> 
  <h3> 、  </h3> 
  <h4>1.          </h4> 
  <p>   JavaScript            :</p> 
  <p>                    ->             <br>          (  ,  ,    ) ->    JavaScript      <br>                 ,                  ,                。    ,           ,       ,           。</p> 
  <p>Vue            。      ,             ,        ,       DOM,        ,     :</p> 
  <p>         ->     VM   (     Model   ) -> VM    ,                   </p> 
  <p>       :           ,                   。         ,                 (          ),           。</p> 
  <h4>2.      </h4> 
  <p>Vue              ,             。</p> 
  <p>Vue                    ,        ,         、   ,             。          :           custom-component         click   ?</p> 
  <pre><code><custom-component>    </custom-component>
</code></pre> 
  <p>       <custom-component @click=“xxx”>,    。    @click        click,        click。      click     :</p> 
  <pre><code><custom-component @click.native="xxx">    </custom-component>
</code></pre> 
  <p>               ,            :</p> 
  <p>     </p> 
  <h6>1).lazy</h6> 
  <p>      ,v-model     input                    。      lazy    ,        change      。           ,            。</p> 
  <h6>2).trim</h6> 
  <p>                  ,    v-model    trim    :</p> 
  <pre><code><input v-model.trim="msg">
</code></pre> 
  <p>                            。      ,          !  ,         。</p> 
  <h6>3).number</h6> 
  <p>                  ,    v-model    number    :</p> 
  <pre><code><input v-model.number="value" type="text" />
</code></pre> 
  <p>     ,            ,               。         ,         .number</p> 
  <pre><code>     
<!--            -->
<a v-on:click.stop="doThis"></a>

<!--            -->
<form v-on:submit.prevent="onSubmit"></form>

<!--         -->
<a v-on:click.stop.prevent="doThat"></a>
</code></pre> 
  <p> 、  <br>               ,       ,                      。</p> 
  <ol> 
   <li>     <br>         todolist           。   item   ,      (     ),      ?</li> 
  </ol> 
  <pre><code>//    
<template>
  <div class="toList">
    <input v-model="info" type="text" /> <button @click="addItem">  </button>
    <ul>
      <TodoItem v-for="(item, index) in listData" :key="index">
        <template v-slot:item="itemProps"> //        
        //   itemProps              
          <span
            :style="{
              fontSize: '20px',
              color: itemProps.checked ? 'yellow' : 'blue'
            }"
            >{{ item }}</span
          >
        </template>
      </TodoItem>
    </ul>
  </div>
</template>
<script>
import TodoItem from "./TodoItem";
export default {
  components: {
    TodoItem
  },
  data() {
    return {
      info: "",
      listData: []
    };
  },
  methods: {
    addItem() {
      this.listData.push(this.info);
      this.info = "";
    }
  }
};

//    


export default {
  data() {
    return {
      checked: false
    };
  }
};


注意:v-bind:styleのオブジェクト構文は直感的です.CSSによく似ていますが、JavaScriptオブジェクトです.CSSプロパティ名は、キャメル(camelCase)または短い横線で区切られた(kebab-case、引用符で囲まれた)名前で指定できます.
  • v-slotの新しい構文2.6.0では、名前付きスロットと役割ドメインスロットに新しい統一された構文(すなわち、v-slot命令)を導入しました.それはslotとslot-scopeに取って代わりました.デフォルトスロット、名前付きスロット、および役割ドメインスロットの新しい構文を一例で説明します.
  • //    
    
    
    import Slot from "./slot";
    export default {
      components: {
        SlotDemo: Slot
      }
    };
    
    //    
    
    
    export default {
      data() {
        return {
          propData: {
            value: "    "
          }
        };
      }
    };