vue-4: コンポーネントの登録、コンポーネントへのパラメータの受け渡し、特別な属性 ref $parent $root、透過的な送信、組み込みコンポーネント、カスタム命令、ミックスイン

コンポーネントの登録、コンポーネントの使用(プロジェクトはすべてコンポーネントで記述されます)

コンポーネントを使用する理由: コンポーネントは再利用でき、各コンポーネントは独立しており、テンプレート、データ、CSS スタイルは相互に影響しません。

  • グローバルに登録されたコンポーネント コンポーネント: グローバル コンポーネントはコンポーネント名汚染を引き起こすため、グローバル コンポーネント inx を悪用しないでください。

    • Vue2: Vue.component("コンポーネント名", { } ) グローバルコンポーネント

    • Vue3: app.component("コンポーネント名", { } ) グローバルコンポーネント

    • vue3: 部分的な登録コンポーネントのコンポーネント

    <div id="app">
            <my-header></my-header>
    </div>
    
</html>
<script src="./lib/vue.global.js"></script>
<script>
    let app =  Vue.createApp({
        data () {
            return {
                
            }
        },
        components: { // 局部组件的注册
            // 组件的名字:对象形式的配置项
            'my-header':{
                template:`<div>{
   
   {msg}}</div>`,
                data() {
                    return {
                        msg:"子组件"
                    }
                },
            }
        }
     })
     app.mount("#app")
</script>

コンポーネントパラメータの受け渡し:コンポーネント間でデータを共有できない問題を解決(一方向データフロー原則)

  • Vue は一方向のデータ フローに従い、データの流れは親から子となり、親コンポーネントのデータが変更されると、props 内のデータが即座に更新されます。

    • props: 親から子に渡す (読み取り専用属性): 親コンポーネントは子コンポーネントのカスタム プロパティを通じて値を渡す必要があり、子コンポーネントは内部の props を通じて値を受け取ります (props 検証)

      • 親の子コンポーネント v-bind (カスタム属性) は属性スタイルをバインドし、属性値は子コンポーネントに渡される親のデータです。

      • 会場からプロパティ名を受け取るために子に props を定義します。

      • 受け取った props のすべてのデータは、サブコンポーネントのテンプレートで直接使用することも、メソッド、ウォッチ、計算されたオプション (必ずこれを持参すること) で使用することもできます。

      • eg:::
        1.父组件传递 (也可以自定义属性传值 :xiaoming="")
        <ZiCom xiaoming="我是传递的数据a" xiaohong='我是传递的第二个b'/>
        
        
        
        2.子组件设置接收 props,直接使用
        export default 
            // 1.使用props定义接收参数
            props:["xiaoming","xiaohong"]
        }

        小道具の検証:

      •     <!-- 父传子 -->
            <div id="app">
                {
                 
                 {fMsg}}
                <!-- 子组件 -->
                <my-kun :title="fMsg" :hei="list[0].title" :num="list[0].price"></my-kun>
            </div>
        
        </html>
        <script src="./lib/vue.global.js"></script>
        <script>
            let app = Vue.createApp({
                data() {
                    return {
                        fMsg: '父的数据在此',
                        list: [{ title: '小黑子', price: 5 }, { title: '坤坤', price: 5 }, { title: '凡凡', price: 5 }]
                    }
                }
            })
            app.component('myKun', {
                template: `<div> {
                 
                 {zMsg}}-----{
                 
                 {title}}-----{
                 
                 {hei}}-----{
                 
                 {num}} </div>`,
                // props: ['title','hei','num'],
                props: {
                    'title': [String],
                    'hei': String,
        
                    // 自定义类型校验函数
                    'num': {
                        validator(value) {
                            // The value must match one of these strings
                            return ['你好', '不好',5].includes(value)
                        }
                    },
                },
                data() {
                    return {
                        zMsg: '爱坤才会赢'
                    }
                }
            })
        
            app.mount('#app')
        </script>
    • 放出: 子から親に渡す (イベントを監視): 親コンポーネントは子コンポーネントにカスタム イベントをバインドする必要があり、子コンポーネントはイベントをトリガーし、$emit を介して値を渡します (エフェクトを放出できます)

      • 親コンポーネントと子コンポーネントのバインディング イベント @myclick="fuMethod"
      • 親のメソッドで fuMethod( val ){ } メソッドを使用します。子によって渡されたデータを受信して​​処理を行うために使用されます
      • イベント名 myclick は、サブコンポーネントの Emits で受信し、メソッドをバインドしてから使用 (または直接使用) し、2 つの方法で使用する必要があります。 1 つ目:
        Emits:['myClick'], //受信メソッド:{ ziMethod (){ this.$emit('myclick', this.zMsg) } }、HTML で使用: @click="ziMethods" 2 番目: 受信後、<button @click="$emit
        ( ' HTML で直接 someEvent')">クリックしてください</button> -
      • 親で受信し、メソッド内のfuMethodメソッドで受信処理を行います。処理後、次のようになります。 一方向データ フローの原則に従って、ビューも自動的に更新されます。
      • 親コンポーネント
        <template>
          <div>
            fufuf
            <!-- 3.绑定自定义事件 -->
            <!-- <ZiCom @自定义事件=“函数”/> -->
            <ZiCom @xiaoming="demo"/>
          </div>
        </template>
        
        <script>
        import ZiCom from "./ZiCom.vue"
        export default {
            components:{
                ZiCom
            },
            methods:{
                // 4定义函数 并且接收自定义事件上面的数据
                demo(val){
                    console.log(val)
                }
            }
        }
        </script>

        サブアセンブリ

      • <template>
          <div>
            zizi
            <!-- 1.逆向传值必须必须必须要使用事件来触发 -->
            <button @click="fun()">点我把数据给父组件</button>
          </div>
        </template>
        
        <script>
        export default {
            data(){
                return {
                    zitext:"我是子组件的数据么么哒!!!!!"
                }
            },
            methods:{
                fun(){
                    // 2.自定义事件 携带我们子组件的数据
                    // this.$emit("给自定义事件起个名字",你传递的数据)
                    this.$emit("xiaoming",{a:this.zitext})
                }
            }
        }
        </script>
      •     <!-- 父传子 -->
            <div id="app">
                {
                 
                 {fMsg}}
                <!-- 子组件 -->
                <my-kun @myclick="fuMethod"></my-kun>
            </div>
        
        </html>
        <script src="./lib/vue.global.js"></script>
        <script>
            let app = Vue.createApp({
                data() {
                    return {
                        fMsg: '父的数据在此',
                        list: [{ title: '小黑子', price: 5 }, { title: '坤坤', price: 5 }, { title: '凡凡', price: 5 }]
                    }
                },
                methods: {
                    fuMethod(msg) {
                        console.log(111);
                        this.fMsg = msg
                    }
                }
            })
            app.component('myKun', {
                template: `<div> {
                 
                 {zMsg}} <button @click="ziMethod">哈哈</button> </div>`,
                // 直接写template中
                // <button @click="$emit('someEvent')">click me</button>
        
                // emits:["myclick"],
                emits: {
                    // 
                    click: null,
        
                    // 校验 submit 事件
                    'myclick': (payload) => {
                        if (payload) {
                            return true
                        } else {
                            console.warn('忘记传参了')
                            return false
                        }
                    }
                },
                data() {
                    return {
                        zMsg: '爱坤才会赢'
                    }
                },
                methods: {
                    ziMethod() {
                        this.$emit('myclick', this.zMsg)
                    }
                }
            })
        
            app.mount('#app')
        </script>

             兄弟コンポーネントのパス値:

                      まず、パブリック コミュニケーション オブジェクト (中央イベント プレジデント) のeventBus.js をインスタンス化します。

                      兄弟コンポーネントの 1 つが $emit を通じてトリガー イベントを送信します。

                      コンポーネントは $on 経由でリスナー イベントを受け取ります

                                      Vue3: 兄弟コンポーネントに値を渡すための明確な解決策はなく、状態のプロモーションを使用できます

                                    (これら 2 つのコンポーネントの共通の親コンポーネントを見つけて、親と子の間で値を渡すことによって実装します)

//utils文件夹下:eventBus.js

import {createApp} from 'vue'
// 实例化通信对象,导出
export default createApp()

         

 

          コンポーネント間で値を渡す: 方法 1: 依存関係の注入: 外部コンポーネントは Provide オプションを介して値を渡し、内部コンポーネントは Inject を介して値を受け取ります。

依存関係の注入は推奨されませんデータ追跡が難しいため、どのレベルでこれが宣言されているか、どのレベルまたは複数のレベルが使用されているかが不明です。データを複数のコンポーネントで使用する必要がある場合は、状態管理に vueX を使用できます。子コンポーネントのみが親コンポーネントのデータを使用したい場合、親コンポーネントは props を通じて直接子コンポーネントに値を渡すことができます。

          コンポーネント間で値を渡す: 方法 2: vuex 状態管理ツールも実装できます。一方向のデータフロー

             vue ファイルが提供するものは 1 つ(同じレベルのデータ)しか書き込めず、複数書き込む場合は最後のものだけが有効になるため、他のメソッド、

             計算されたプロパティについても同様で、コードは上から下に実行され、最後のものだけが有効になります。

特別な属性 ref $parent $root

  1. ref要素またはサブコンポーネントを登録するための参照。基本的なページ DOM 操作を実行する

    1. ref="タグの dom の上に" を使用します。

    2.this.$refs. 指定した要素をあなたの名前で見つけることができます

これをラベルに配置すると、ラベルの dom ノードが取得されます。

<template>
  <div>
    <!-- 1.绑定 -->
    <h1 ref="wangcai">找到我</h1>
  <button @click="fun()">点我修改上面的内容</button>

  </div>
</template>

<script>
export default {
  methods:{
    fun(){
      // 2.找到他
      this.$refs.wangcai.style.color="red";
    }
  }
}
</script>

これをコンポーネントに配置し、サブコンポーネントのメソッド属性を取得します。このメソッドを使用するときは、() を使用してメソッドを呼び出す必要があることに注意してください。印刷を繰り返さないでください

<template>
  <div>
    <h1>我是home</h1>
    <!-- 1.把ref绑定到组件身上 -->
    <Rc ref="com"/>
    <button @click="fun()">点我</button>
  </div>
</template>

<script>
import Rc from "@/components/refcom.vue"
export default {
  components:{
    Rc
  },
  methods:{
    fun(){
      // 2.把ref绑定到组件身上父组件就可以得到子组件的所有属性和方法
      console.log(this.$refs.com)
    }
  }
}
</script>


$parent:親コンポーネントのメソッド属性は書き込みサブコンポーネントで取得できます。存在する場合は取得され、存在しない場合はnullになります。

$set : This.$set("誰を追加しますか", "x によって追加されたキー", "追加したい値")

Vue でデータを変更しないようにしようとする問題を解決するにはどうすればよいですか?

<template>
  <div>
      <h2>数据变试图不会改变</h2>
      <h3>{
   
   {obj.age}}</h3>
      <button @click="funb()">点我</button>
  </div>
</template>

<script>
// 在vue2.0中  数据的双向绑定 是基于数据劫持与发布者订阅者模式的
// 其中数据劫持是通过Object.defineProperty()这个方法来拦截劫持data中的数据的  因为有了这个方法
// 所以数据改变试图也会更新

// 但是 Object.defineProperty()有个问题   他是会监听初始化的数据  如果中途给数组或者对象
// 添加新属性的时候  Object.defineProperty() 就不会监听到  不会监听到就没有数据劫持  没有
// 数据劫持就没有双向绑定  没有双向绑定就没有数据变试图变

export default {
    methods:{
        funb(){
            // this.obj.age=18

            // console.log(this.obj.age)

            this.$set(this.obj,"age",18)
        }
    },
    data(){
        return {
            obj:{
                name:"xixi"
            }
        }
    }
}
</script>

 

透過透過(属性):Vue3:透過透過属性。透過送信は、自動透過送信バインドと手動バインドに分けられます。

透明属性とは何ですか?透明プロパティとは、コンポーネントの使用中にコンポーネントに作用し、下に流れてコンポーネント内のラベルにバインドされるプロパティを指します。
透過的な送信: 親コンポーネントが子コンポーネントにデータを渡すと、子コンポーネントは親コンポーネントから渡された属性 $attrs を受け取ります。

透過的な送信機能:::
- 属性の継承: 子は親を継承します: 例: クラス、ID、スタイル、属性、イベント、その他のヘッダーをコンポーネント内のタグに透過的に送信できます。
- クラスとスタイルをマージする

 v-on リスナーの継承
- 透過的な送信属性を無効にするかどうか:継承Attrs: false
- マルチルート ノードの継承: 子コンポーネントは props を使用して、親コンポーネントによって渡された属性を受け取ります。

内蔵コンポーネント

<KeepAlive> キャッシュ コンポーネント: 動的スイッチング コンポーネントをラップするために使用されます。

<KeepAlive> は、動的コンポーネントをラップするときに、非アクティブなコンポーネント インスタンスを破棄する代わりにキャッシュします。コンポーネントの再レンダリングを避ける (パフォーマンスの最適化)

キープアライブと含める、除外する

アクティブ化された 非アクティブ化された

 <component :is='coms[index]' /> 動的コンポーネント: どのコンポーネントがレンダリングされるかを決定します

      is:特殊Attribute用于绑定[动态组件]

      //动态组件:包裹挂载点即可
      <keep-alive>
           <component :is="Com"></component>
      </keep-alive>

      //路由:包裹路由出口即可
      <keep-alive>
          <router-view/>
      </keep-alive>

      //属性:如果 我把两个都写了  excloud的优先级大于incloude
            include 你要缓存谁
            exclude 你不想缓存谁	
     <keep-alive exclude="Db,xxxxx,cccc">
          <!-- 设置动态组件的挂载点 -->
          <component :is="com"></component>
     </keep-alive>


    #### 钩子函数
    activated:在进入到被kepp-alive管理的组件时候触发
    deactivated:在离开被kepp-alive管理的组件时候触发
    替代 `mounted`挂载后 和 `unmounted`销毁后。
    <template>
      <div>
        aaaaaaaa
        <input type="text" />
      </div>
    </template>

    <script>
        export default {
          activated() {
            console.log("进入到了被keep-alive管理的组件中了");
          },
          deactivated() {
            console.log("离开到了被keep-alive管理的组件中了");
          },
        };
    </script>

 

アニメーションコンポーネント <Transiton />: 内部に配置できるラベルまたはコンポーネントは 1 つだけです (表示するには vue 公式 Web サイトを使用してください)

name=" " カスタム アニメーション クラス名のプレフィックス、そうでない場合はデフォルト

mode="out-in" アニメーションの順序を設定します (in-out、out-in)。

トランジション効果を開始および終了するために適用される CSS クラスは合計 6 つあります。

<Transition>
  <p v-if="show">hello</p>
</Transition>

/* 下面我们会解释这些 class 是做什么的 */
.v-enter-active,
.v-leave-active {
  transition: opacity 0.5s ease;
}

.v-enter-from,
.v-leave-to {
  opacity: 0;
}

Socket <slot /> コンポーネント: コンポーネント内のコンテンツをカスタマイズします (詳細を説明するリンクを借用します)

コンポーネントのswitchタグに挿入されたコンテンツがデフォルトで表示されない場合(コンポーネントは完全に独立した個体なので、特別な設定をしないとコンポーネントにコンテンツを挿入する方法はありませんスロットは親のテンプレートをミックスするために使用されますコンポーネントと子コンポーネント

デフォルトのスロット <slot />

名前付きスロット <slot name = "" />

この記事では Vue スロットの使い方と事例表示について詳しく解説しています 読むとよくわかりますスロット 2. 名前付きスロット 3. スコープスロット 4. バージョン変更 スロットは実際のプロジェクト開発でよく使われる、主に分けられますデフォルト スロット、名前付きスロット、スコープ指定スロットの 3 つのカテゴリに分類されており、使用も比較的簡単です。1. スロットの意味 スロットは、親コンポーネントが使用するために子コンポーネントのコードに記述されるプレースホルダーです。コードでは大まかに以下のような形で記述しますが、詳しい書き方は後ほど紹介します。<slot> </slot>スロットは実際には、スロットが書き込まれる場所に穴を掘り、コンポーネントのユーザー、つまり親グループを待ちます。https://blog.csdn.net/czjl6886/article/details/122094040#:~:text=%E4%BA%8C%E3%80%81%E6%8F%92%E6%A7%BD%E7% 9A%84%E4%B8%89%E7%A7%8D%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95%201%201.%E9%BB%98 %E8%AE%A4%E6%8F%92%E6%A7%BD%20%E6%9C%89%E4%B8%A4%E4%B8%AA%E7%BB%84%E4%BB%B6 %EF%BC%8CApp%E6%98%AF%E7%88%B6%E7%BB%84%E4%BB%B6%EF%BC%8CChild%E6%98%AF%E5%AD%90%E7 %BB%84%E4%BB%B6%20%E7%88%B6%E7%BB%84%E4%BB%B6%E4%BB%A3%E7%A0%81%E5%A6%82%E4 %B8%8B%EF%BC%9A%20%3Ctemplate%3E%20%3Cdiv%20class%3D%22parent%22%3E、3。%E4%BD%9C%E7%94%A8%E5%9F%9F%E6%8F%92%E6%A7%BD%20%E5%A6%82%E6%9E%9C%E6%95%B0 %E6%8D%AE%E5%9C%A8%E5%AD%90%E7%BB%84%E4%BB%B6%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5 %9C%A8%E5%AD%90%E7%BB%84%E4%BB%B6%E4%B8%AD%E7%9B%B4%E6%8E%A5%E4%BD%BF%E7%94 %A8%E6%95%B0%E6%8D%AE%EF%BC%8C%E4%BD%86%E6%A0%B9%E6%8D%AE%E6%95%B0%E6%8D%AE %E7%94%9F%E6%88%90%E7%9A%84%E7%BB%93%E6%9E%84%E9%9C%80%E8%A6%81%E7%BB%84%E4 %BB%B6%E7%9A%84%E4%BD%BF%E7%94%A8%E8%80%85%E6%9D%A5%E5%86%B3%E5%AE%9A%EF%BC %8C%E6%88%91%E4%BB%AC%E5%B0%B1%E9%9C%80%E8%A6%81%E7%94%A8%E5%88%B0%E4%BD%9C %E7%94%A8%E5%9F%9F%E6%8F%92%E6%A7%BD%EF%BC%8C%E5%90%8C%E6%97%B6%EF%BC%8C%E6 %88%91%E4%BB%AC%E4%B9%9F%E5%8F%AF%E4%BB%A5%E5%AE%9E%E7%8E%B0%E5%A4%9A%E7%A7 %8D%E7%BB%93%E6%9E%84%E3%80%82%20%E4%BE%8B%E5%A6%82%EF%BC%9Agames%E6%95%B0%E6%8D %AE%E5%9C%A8%E5%AD%90%E7%BB%84%E4%BB%B6%E4%B8%AD%EF%BC%8C%E4%BD%86%E4%BD%BF %E7%94%A8%E6%95%B0%E6%8D%AE%E6%89%80%E9%81%8D%E5%8E%86%E5%87%BA%E6%9D%A5%E7%9A%84%E7%BB%93%E6%9E%84%E7%94 %B1%E7%88%B6%E7%BB%84%E4%BB%B6App%E5%86%B3%E5%AE%9A%20%E5%AD%90%E7%BB%84%E4%BB %B6%E4%B8%AD%EF%BC%8C%E4%BD%BF%E7%94%A8%20%3Cスロット%20%3Aゲーム%3D%22ゲーム%22%3E%20%E6%8C%87 %E6%98%8E%E4%BD%BF%E7%94%A8%E4%BB%80%E4%B9%88%E6%95%B0%E6%8D%AE%EF%BC%8C%E5 %B9%B6%E5%B0%86%E6%95%B0%E6%8D%AE%E4%BC%A0%E7%BB%99%E6%8F%92%E6%A7%BD%E7%9A %84%E4%BD%BF%E7%94%A8%E8%80%85%20

プラグインプラグイン + カスタム命令ディレクティブ

プラグインを定義します。export default { install(app){ } }

アプリケーション プラグイン: app.use (プラグイン) use メソッドは、プラグインの実行時に自動的にプラグインのインストール メソッドを見つけ、このメソッドを実行してプラグインのアプリケーションを完了します。

ローカル ディレクティブ: ディレクティブによって定義: { プラグイン名: { フック関数 } } オプション。現在のコンポーネントでのみ使用できます。

コマンドの機能: 作成、マウント、更新されたコマンド フックのフック機能によって異なります。

例: Vue によって入力要素が DOM に挿入されると、自動的にフォーカスされます。

グローバル ディレクティブ: グローバル ディレクティブ v- ディレクティブ名が使用され、app.directive('cals' { }) メソッドで定義され、任意のコンポーネントで使用できます。ディレクティブの機能: 作成されたディレクティブのフック関数に依存します。 、マウント、更新....

ディレクティブの名前とともに v-automatically を使用します


    • //a
      export default{
          install(app){
              app.directive('focus',{
                  // 绑定元素的父组件
                  // 及他自己的所有子节点都挂载完成后调用
                  mounted(el, binding, vnode, prevVnode) {
                      el.focus(); //聚焦
                  },
              })
          }
      }
      // b
      export default{
          install(app){
              app.directive('cal',{
                  // 绑定元素的父组件
                  // 及他自己的所有子节点都挂载完成后调用
                  mounted(el, binding, vnode, prevVnode) {
                      el.value = el.value * 10 + '没钱' 
                      // 加钱
                  },
              })
          }
      }
      <template>
          <div class="childa">
            <!-- <h1 ref="title">{
             
             { count }}</h1> -->
            childa组件
            <input v-focus v-calc type="text" :value="4">哎哎哎啊
            <input type="text" v-sss :value="6">哎哎哎啊
            <h1 ref="title">{
             
             { count }}</h1> 
           
            <button @click="handleClick">传值</button>
          </div>
      </template>
        
      <script>
      
      export default {
        data() {
      return{
        p:'123',
        count:3
      }
        },
        methods:{
          handleClick(){
            this.count++,
            // console.log(this.$refs.title.innerHTML);
      
            this.$nextTick(()=>{
              console.log(this.$refs.title.innerHTML);
            })
          }
        },
      
      局部自定义指令
        directives: { //自定义局部指令,只能在当前组将中使用
            // 在模板中启用 v-focus
            focus:{
              // 在绑定元素的父组件
              // 及他自己的所有子节点都挂载完成后调用
              mounted(el, binding, vnode, prevVnode) {
                console.log(el);
                el.focus()
              }
            },
            sss:{
              // 在绑定元素的父组件
              mounted(el, binding, vnode, prevVnode) {
                el.value = el.value * 7+'元'
              }
            }
          }
      }
      
      </script>

ミックスイン : ミックスイン

役割: 複数コンポーネントの共通コード(オプション)を抽出し、コードの重複を回避

使用方法: 混合されたパブリック コードがコンポーネントのオプション位置に表示されます。

グローバル混合は推奨されません。地球規模の汚染を引き起こす可能性があります。次のローカル混合を使用してください。

import import mixins path、mix in: データは同じレベルで自動的にミックスインされ、ミックスインのメソッド属性を直接使用できます。

 

export default{
    // 能写在这里的都是组件已知选项 watch filter directives components data
    methods:{
        saveIndex(i){
            this.index = i
        }
    },
    computed:{
        calc(){
            return 2**10
        }
    }
}
    <footer>
      <span @click="saveIndex(index)" v-for="item, index in btns" :key="index">{
   
   { item }}</span>
    </footer>

// 导入mixins
import mixins from './mixins/index';

 // 应用混入
  mixins: [mixins],

  methods: {
    // 这个可以省略了。
    // saveIndex(i) {
    //   this.index = i
    // }
  },

2 つのコア API: (一般的には使用されません)

$forceUpdate(): コンポーネントを強制的に更新します (更新できない極端な場合は、書き方が間違っています)

$nextTick(): コンポーネントの次の更新サイクル後に特定のコードを実行できるようにします。

      <button @click="handleClick">传值</button>

  methods:{
    handleClick(){
      this.count++,
      // console.log(this.$refs.title.innerHTML);

      this.$nextTick(()=>{
        console.log(this.$refs.title.innerHTML);
      })
    }
  },

おすすめ

転載: blog.csdn.net/qq_60839348/article/details/130649187