VUE 中常用的 4 種高級特性!

作者:阿虎兒

https://juejin.cn/post/7225921305597820985

  1. provide/inject =================

provide/inject 是 Vue.js 中用於跨組件傳遞數據的一種高級技術,它可以將數據注入到一個組件中,然後讓它的所有子孫組件都可以訪問到這個數據。通常情況下,我們在父組件中使用 provide 來提供數據,然後在子孫組件中使用 inject 來注入這個數據。

使用 provide/inject 的好處是可以讓我們在父組件和子孫組件之間傳遞數據,而無需手動進行繁瑣的 props 傳遞。它可以讓代碼更加簡潔和易於維護。

但需要注意的是,provide/inject 的數據是非響應式的,這是因爲 provide/inject 是一種更加底層的 API,它是基於依賴注入的方式來傳遞數據,而不是通過響應式系統來實現數據的更新和同步。

具體來說,provide 方法提供的數據會被注入到子組件中的 inject 屬性中,但是這些數據不會自動觸發子組件的重新渲染,如果 provide 提供的數據發生了變化,子組件不會自動感知到這些變化並更新。

如果需要在子組件中使用 provide/inject 提供的數據,並且希望這些數據能夠響應式地更新,可以考慮使用 Vue 的響應式數據來代替 provide/inject。例如,可以將數據定義在父組件中,並通過 props 將其傳遞給子組件,子組件再通過 $emit 來向父組件發送數據更新的事件,從而實現響應式的數據更新。

下面是一個簡單的例子,展示瞭如何在父組件中提供數據,並在子孫組件中注入這個數據:

<!-- 父組件 -->
<template>
  <div>
    <ChildComponent />
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  provide: {
    message: 'Hello from ParentComponent',
  },
  components: {
    ChildComponent,
  },
};
</script>

//上面provide還可以寫成函數形式
export default {
    provide(){
        return {
              message: this.message
        }
    }
}
<!-- 子組件 -->
<template>
  <div>
    <GrandchildComponent />
  </div>
</template>

<script>
import GrandchildComponent from './GrandchildComponent.vue';

export default {
  inject: ['message'],
  components: {
    GrandchildComponent,
  },
};
</script>
<!-- 孫子組件 -->
<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

<script>
export default {
  inject: ['message'],
};
</script>

在上面的例子中,父組件中提供了一個名爲 message 的數據,子孫組件中都可以使用 inject 來注入這個數據,並在模板中使用它。注意,子孫組件中的 inject 選項中使用了一個數組,數組中包含了需要注入的屬性名。

在這個例子中,我們只注入了一個 message 屬性,所以數組中只有一個元素。

  1. 自定義 v-model ==============

要使自定義的 Vue 組件支持 v-model,需要實現一個名爲 value 的 prop 和一個名爲 input 的事件。在組件內部,將 value prop 綁定到組件的內部狀態,然後在對內部狀態進行修改時觸發 input 事件。

下面是一個簡單的例子,展示如何創建一個自定義的輸入框組件並支持 v-model:

<template>
  <input :value="value" @input="$emit('input', $event.target.value)" />
</template>

<script>
export default {
  name: 'MyInput',
  props: {
    value: String
  }
};
</script>

在上面的組件中,我們定義了一個 value prop,這是與 v-model 綁定的數據。我們還將內置的 input 事件轉發爲一個自定義的 input 事件,並在事件處理程序中更新內部狀態。

現在,我們可以在父組件中使用 v-model 來綁定這個自定義組件的值,就像使用普通的輸入框一樣:

<template>
  <div>
    <my-input v-model="message" />
    <p>{{ message }}</p>
  </div>
</template>

<script>
import MyInput from './MyInput.vue';

export default {
  components: {
    MyInput
  },
  data() {
    return {
      message: ''
    };
  }
};
</script>

在上面的代碼中,我們通過使用 v-model 指令來雙向綁定 message 數據和 MyInput 組件的值。當用戶在輸入框中輸入文本時,MyInput 組件會觸發 input 事件,並將其更新的值發送給父組件,從而實現了雙向綁定的效果。

  1. 事件總線(EventBus) =================

Vue 事件總線是一個事件處理機制,它可以讓組件之間進行通信,以便在應用程序中共享信息。在 Vue.js 應用程序中,事件總線通常是一個全局實例,可以用來發送和接收事件。

以下是使用 Vue 事件總線的步驟:

3.1  創建一個全局 Vue 實例作爲事件總線:

import Vue from 'vue';
export const eventBus = new Vue();

3.2  在需要發送事件的組件中,使用 $emit 方法觸發事件並傳遞數據:

eventBus.$emit('eventName', data);

3.3  在需要接收事件的組件中,使用 $on 方法監聽事件並處理數據:

eventBus.$on('eventName'(data) ={
  // 處理數據
});

需要注意的是,事件總線是全局的,所以在不同的組件中,需要保證事件名稱的唯一性。另外,需要在組件銷燬前使用 $off 方法取消事件監聽:

eventBus.$off('eventName');

這樣就可以在 Vue.js 應用程序中使用事件總線來實現組件之間的通信了。

  1. render 方法 ============

Vue 的 render 方法是用來渲染組件的函數,它可以用來替代模板語法,通過代碼的方式來生成 DOM 結構。相較於模板語法,render 方法具有更好的類型檢查和代碼提示。

下面詳細介紹 Vue 的 render 方法的使用方法:

4.1 基本語法

render 方法的基本語法如下:

render: function (createElement) {
  // 返回一個 VNode
}

其中 createElement 是一個函數,它用來創建 VNode(虛擬節點),並返回一個 VNode 對象。

4.2 創建 VNode

要創建 VNode,可以調用 createElement 函數,該函數接受三個參數:

標籤名或組件名

可選的屬性對象

子節點數組

例如,下面的代碼創建了一個包含文本節點的 div 元素:

render: function (createElement) {
  return createElement('div''Hello, world!')
}

如果要創建一個帶有子節點的元素,可以將子節點作爲第三個參數傳遞給 createElement 函數。

例如,下面的代碼創建了一個包含兩個子元素的 div 元素:

render: function (createElement) {
  return createElement('div'[
    createElement('h1''Hello'),
    createElement('p''World')
  ])
}

如果要給元素添加屬性,可以將屬性對象作爲第二個參數傳遞給 createElement 函數。

例如,下面的代碼創建了一個帶有樣式和事件處理程序的 button 元素:

render: function (createElement) {
  return createElement('button'{
    style: { backgroundColor: 'red' },
    on: {
      click: this.handleClick
    }
  }'Click me')
},
methods: {
  handleClick: function () {
    console.log('Button clicked')
  }
}

4.3 動態數據

render 方法可以根據組件的狀態動態生成內容。要在 render 方法中使用組件的數據,可以使用 this 關鍵字來訪問組件實例的屬性。

例如,下面的代碼根據組件的狀態動態生成了一個帶有計數器的 div 元素:

render: function (createElement) {
  return createElement('div'[
    createElement('p''Count: ' + this.count),
    createElement('button'{
      on: {
        click: this.increment
      }
    }'Increment')
  ])
},
data: function () {
  return {
    count: 0
  }
},
methods: {
  increment: function () {
    this.count++
  }
}

4.4 JSX

在使用 Vue 的 render 方法時,也可以使用 JSX(JavaScript XML)語法,這樣可以更方便地編寫模板。要使用 JSX,需要在組件中導入 Vue 和 createElement 函數,並在 render 方法中使用 JSX 語法。

例如,下面的代碼使用了 JSX 語法來創建一個計數器組件:

import Vue from 'vue'

export default {
    render() {
        return (
            <div>
                <p>Count:{this.count}</p>
                <button onClick={this.increment}>Increment</button>
            </div>
        )
    },
    data() {
        return { count: 0 }
    },
    methods: {
        increment() {
            this.count++
        }
    }
}

注意,在使用 JSX 時,需要使用 {} 包裹 JavaScript 表達式。

4.5 生成函數式組件

除了生成普通的組件,render 方法還可以生成函數式組件。函數式組件沒有狀態,只接收 props 作爲輸入,並返回一個 VNode。因爲函數式組件沒有狀態,所以它們的性能比普通組件更高。

要生成函數式組件,可以在組件定義中將 functional 屬性設置爲 true。

例如,下面的代碼定義了一個函數式組件,用於顯示列表項:

export default {
  functional: true,
  props: ['item'],
  render: function (createElement, context) {
    return createElement('li', context.props.item);
  }
}

注意,在函數式組件中,props 作爲第二個參數傳遞給 render 方法。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/ToUI80SLSO9FaXEWvWZoKA