Vue3-高級特性

一、Vue中自定義指令

1.認識自定義指令

在Vue的模板語法中我們學習過各種各樣的指令:v-showv-forv-model等等,除了使用這些指令之外,Vue也允許我們來 自定義自己的指令

  • 注意:在Vue中,代碼的復用和抽象主要還是通過組件
  • 通常在某些情況下,你需要對DOM元素進行底層操作,這個時候就會用到自定義指令

自定義指令分為兩種:

  • 自定義局部指令:組件中通過 directives 選項,只能在當前組件中使用;

  • 自定義全局指令:app的 directive 方法,可以在任意組件中被使用;

比如我們來做一個非常簡單的案例:當某個元素掛載完成后可以自動獲取焦點

  • 實現方式一:如果我們使用默認的實現方式;

  • 實現方式二:自定義一個 v-focus 的局部指令;

  • 實現方式三:自定義一個 v-focus 的全局指令;

1.1默認實現

<script setup>
import { onMounted, useTemplateRef } from "vue";const inputRef = useTemplateRef('inputRef');onMounted(() => {if (inputRef.value) {inputRef.value.focus();}console.log(inputRef.value);
})
</script><template><div class="app"><input type="text" ref="inputRef"></div>
</template><style scoped></style>

1.2自定義局部指令

  • 這個自定義指令實現非常簡單,我們只需要在組件選項中使用 directives 即可;

  • 它是一個對象,在對象中編寫我們自定義指令的名稱(注意:這里不需要加v-);

  • 自定義指令有一個生命周期,是在組件掛載后調用的 mounted,我們可以在其中完成操作;

<script setup>
// 任何以 v 開頭的駝峰式命名的變量都可以當作自定義指令使用
const vFocus = (el) => {el.focus();
};
</script><template><div class="app"><input type="text" v-focus /></div>
</template><style scoped></style>

1.3自定義全局指令

自定義一個全局的v-focus指令可以讓我們在任何地方直接使用

import { createApp } from 'vue'
import App from './App.vue'const app = createApp(App);
app.directive('focus', {mounted(el) {el.focus()}
})
app.mount('#app');

2.指令的生命周期

一個指令定義的對象,Vue提供了如下的幾個鉤子函數(都是可選的):

? created:在綁定元素的 attribute 或事件監聽器被應用之前調用;

? beforeMount:當指令第一次綁定到元素并且在掛載父組件之前調用;

? mounted:在綁定元素的父組件被掛載后調用;

? beforeUpdate:在更新包含組件的 VNode 之前調用;

? updated:在包含組件的 VNode 及其子組件的 VNode 更新后調用;

? beforeUnmount:在卸載綁定元素的父組件之前調用;

? unmounted:當指令與元素解除綁定且父組件已卸載時,只調用一次;

3.指令的參數和修飾符

如果我們指令需要接受一些參數或者修飾符應該如何操作呢?

  • foo是參數的名稱;

  • bar是修飾符的名稱;

  • 后面是傳入的具體的值;

在我們的生命周期中,我們可以通過 bindings 獲取到對應的內容

<script setup>const vFocus = {mounted(el, binding) {console.log('binding:', binding)/*{arg: "foo"dir: {mounted: ?}instance: Proxy(Object) {__v_skip: true}modifiers: {bar: true}oldValue: undefinedvalue: "admin"}*/el.focus()}
}
</script><template><div class="app"><input type="text" v-focus:foo.bar="'admin'" /></div>
</template>

4.自定義指令練習

自定義指令案例:時間戳的顯示需求:

  • 在開發中,大多數情況下從服務器獲取到的都是時間戳

  • 我們需要將時間戳轉換成具體格式化的時間來展示;

  • 在Vue2中我們可以通過過濾器來完成;

  • 在Vue3中我們可以通過 計算屬性(computed) 或者 自定義一個方法(methods) 來完成;

  • 其實我們還可以通過一個自定義的指令來完成;

我們來實現一個可以自動對時間格式化的指令v-format-time

  • 這里我封裝了一個函數,在首頁中我們只需要調用這個函數并且傳入app即可;

directives/v-format-time.js

import dayjs from "dayjs";export default function (app) {app.directive("format-time", {mounted(el, binding) {let format = 'YYYY-MM-DD';if (binding.value) {format = binding.value;}let timestamp = parseInt(el.textContent);if (!timestamp) return;if (timestamp.length === 10) {timestamp = timestamp * 1000;}// 對時間戳格式化el.textContent = dayjs(timestamp).format(format);}});
}

directives/index.js

import vFormatTime from './v-format-time.js';export default function (app) {vFormatTime(app);
}

main.js

import { createApp } from 'vue'
import App from './App.vue'
import directives from '@/directives'const app = createApp(App);
// 全局指令
directives(app);app.mount('#app');

二、Vue內置組件Teleport

1.認識Teleport

在組件化開發中,我們封裝一個組件A,在另外一個組件B中使用:

  • 那么組件A中template的元素,會被掛載到組件B中template的某個位置;

  • 最終我們的應用程序會形成一顆DOM樹結構

但是某些情況下,我們希望組件不是掛載在這個組件樹上的,可能是移動到Vue app之外的其他位置:

  • 比如移動到body元素上,或者我們有其他的div#app之外的元素上;

  • 這個時候我們就可以通過teleport來完成;

Teleport是什么呢?

它是一個Vue提供的內置組件,類似于react的Portals

teleport翻譯過來是心靈傳輸、遠距離運輸的意思; 它有兩個屬性:

  • to:指定將其中的內容移動到的目標元素,可以使用選擇器;
  • disabled:是否禁用 teleport 的功能;
<template>
<div class="hello"><teleport to="body"><div class="hello"><h2>Hello World</h2></div></teleport>
</div>
</template>

在這里插入圖片描述

2.和組件結合使用

當然,teleport也可以和組件結合一起來使用:

我們可以在 teleport 中使用組件,并且也可以給他傳入一些數據;

<template>
<div class="app"><h2>app</h2><teleport to="body"><HelloWorld message="Hello World" /></teleport>
</div>
</template>

3.多個Teleport一起使用

如果我們將多個teleport應用到同一個目標上(to的值相同),那么這些目標會進行合并:

<template>
<div class="app"><h2>app</h2><div class="content"><h3>content</h3></div><teleport to=".content"><HelloWorld message="Hello World" /></teleport><teleport to=".content"><HelloWorld message="abc" /></teleport>
</div>
</template>

三、Vue內置組件Suspense

注意:目前(2024-08-01)Suspense顯示的是一個實驗性的特性,API隨時可能會修改。

Suspense是一個內置的全局組件,該組件有兩個插槽:

  • default:如果default可以顯示,那么顯示default的內容;

  • fallback:如果default無法顯示,那么會顯示fallback插槽的內容;

<script setup>
import { defineAsyncComponent } from "vue";const AsyncHome = defineAsyncComponent(() => import("./AsyncHome.vue"))
</script><template>
<div class="app"><h2>app</h2><suspense><template #default><AsyncHome /></template><template #fallback><div>loading...</div></template></suspense>
</div>
</template><style scoped></style>

suspense用于加載異步組件

四、Vue中安裝插件的方式

1.認識Vue插件

通常我們向Vue全局添加一些功能時,會采用插件的模式,它有兩種編寫方式

  • 對象類型:一個對象,但是必須包含一個 install 的函數,該函數會在安裝插件時執行;

  • 函數類型:一個function,這個函數會在安裝插件時自動執行

插件可以完成的功能沒有限制,比如下面的幾種都是可以的:

  • 添加全局方法或者 property,通過把它們添加到 config.globalProperties 上實現;
  • 添加全局資源:指令/過濾器/過渡等;
  • 通過全局 mixin 來添加一些組件選項;
  • 一個庫,提供自己的 API,同時提供上面提到的一個或多個功能;

2.插件的編寫方式

對象類型寫法

export default {name: 'plugin_01',install(app) {console.log('plugin_01 install');}
}

函數類型寫法

export default function (app, options) {console.log('plugin_02 install', app, options);
}

五、Vue中渲染函數的使用

1.認識h函數

Vue推薦在絕大數情況下使用模板來創建你的HTML,然后一些特殊的場景,你真的需要JavaScript的完全編程的能力,這個時候你可以使用 渲染函數 ,它比模板更接近編譯器;

前面我們講解過VNode和VDOM的概念:

  • Vue在生成真實的DOM之前,會將我們的節點轉換成VNode,而VNode組合在一起形成一顆樹結構,就是虛擬DOM (VDOM);

  • 事實上,我們之前編寫的 template 中的HTML 最終也是使用渲染函數生成對應的VNode;

  • 那么,如果你想充分的利用JavaScript的編程能力,我們可以自己來編寫 createVNode 函數,生成對應的VNode;

那么我們應該怎么來做呢?使用 h()函數

  • h() 函數是一個用于創建 vnode 的一個函數;

  • 其實更準確的命名是 createVNode() 函數,但是為了簡便在Vue將之簡化為 h() 函數;

2.h函數的使用

h()函數 如何使用呢?它接受三個參數:

{String | Object | Function} tag

一個 HTML 標簽名、一個組件、一個異步組件、或一個函數式組件,必需的

eg: ‘div’

{Object} props

與 attribute、prop 和時間相對應的對象,我們會在模板中使用,可選的

eg: {}

{String | Array | Object} children

子 VNodes,使用 h() 構建,或使用字符串獲取 文本 Vnode 或者有插槽的對象可選的

eg:

['Some text comes first',h('h1', 'A headline'),h(MyComponent, {someprop: 'foobar'})
]

注意:

  • 如果沒有props,那么通常可以將children作為第二個參數傳入;

  • 如果會產生歧義,可以將null作為第二個參數傳入,將children作為第三個參數傳入;

3.使用示例

h函數可以在兩個地方使用:

  • render函數選項中;
  • setup函數選項中(setup本身需要是一個函數類型,函數再返回h函數創建的VNode);

render函數中

import { h } from 'vue'export default {data() {return {msg: 'Hello Vue 3.0 + Vite'}},render() {return h("div", { className: "app" }, [h("h2", { className: "title" }, "我是標題123"),h("p", { className: "content" }, "我是內容, 哈哈哈"),])}
}

setup函數

<script>
import { h } from "vue";export default {data() {return {msg: 'Hello Vue 3.0 + Vite'}},setup() {return () => h("div", { className: "app" }, [h("h2", { className: "title" }, "我是標題123"),h("p", { className: "content" }, "我是內容, 哈哈哈"),])}
}
</script>

setup script寫法

<script setup>
import { h } from 'vue'const render = () => h("div", { className: "app" }, [h("h2", { className: "title" }, "我是標題123"),h("p", { className: "content" }, "我是內容, 哈哈哈"),
])
</script><template><render></render>
</template>

4.h函數計數器案例

<script setup>
import { h, ref } from 'vue'const count = ref(0);const render = () => h("div", { className: "app" }, [h("h2", { className: "title" }, count.value),h("button", { className: "btn", onClick: () => count.value++ }, "+"),h("button", { className: "btn", onClick: () => count.value-- }, "-"),
])
</script><template><render></render>
</template>

六、Vue中編寫jsx的語法

如果我們希望在項目中使用jsx,那么我們需要添加對jsx的支持:

  • jsx我們通常會通過Babel來進行轉換(React編寫的jsx就是通過babel轉換的);
  • 對于Vue來說,我們只需要在Babel中配置對應的插件即可;

安裝Babel支持Vue的jsx插件:

npm install @vue/babel-plugin-jsx -D

如果是Vite環境,需要安裝插件:

npm install @vitejs/plugin-vue-jsx -D

在babel.config.js配置文件中配置插件:

module.export = {"presets": ["@vue/cli-plugin-ba"]"plugins": ["@vue/babel-plugin-jsx"]
}

jsx計數器案例

<script lang="jsx">
export default {data() {return {count: 0}},render() {return (<div><h1>{ this.count }</h1><button onClick={() => this.count++}>+</button><button onClick={() => this.count--}>-</button></div>)}
}
</script>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/898122.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/898122.shtml
英文地址,請注明出處:http://en.pswp.cn/news/898122.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【量化策略】動量突破策略

【量化策略】動量突破策略 &#x1f680;量化軟件開通 &#x1f680;量化實戰教程 技術背景與應用場景 動量突破策略是一種基于市場趨勢的量化交易策略&#xff0c;它通過識別資產價格的動量變化來預測未來的價格走勢。這種策略適用于那些價格波動較大、趨勢明顯的市場環境…

基于CPLD電力/軌道交通3U機箱開關量輸出板(DO)

板卡簡介&#xff1a; 本板為開關量輸出板&#xff08;DO&#xff09;&#xff0c;采用固態繼電器用于電平輸出或負載驅動&#xff0c;典型輸出高電平為DC110V&#xff0c;低電平為0V。 性能規格&#xff1a; 電源&#xff1a;DC5V&#xff0c;DC3.3V&#xff0c;DC15V&#…

【C++經典例題】反轉字符串中單詞的字符順序:兩種實現方法詳解

&#x1f493; 博客主頁&#xff1a;倔強的石頭的CSDN主頁 &#x1f4dd;Gitee主頁&#xff1a;倔強的石頭的gitee主頁 ? 文章專欄&#xff1a;C經典例題 期待您的關注 目錄 問題描述 基于快慢指針的解法 基于索引的解法 兩種方法的比較 問題描述 在處理字符串相關的問題…

Java基礎語法練習45(網絡編程)

目錄 一、網絡的相關概念 1.網絡通信 2.網絡 3.ip 地址 4.ipv4 地址分類 5.域名 6.網絡通信協議 7.TCP 和 UDP 二、InetAddress類 1.相關方法 2.代碼示例如下&#xff1a; 三、Socket 1.基本介紹 四、TCP 網絡通信編程 1.基本介紹 2.應用示例&#xff1a; 2.1…

【Json—RPC框架】:宏定義不受命名空間限制,續行符的錯誤使用造成的bug

為什么不受命名空間的限制&#xff1f; 宏處理在預處理階段&#xff0c; 預處理在編譯之前&#xff0c;編譯才進行語法分析&#xff0c;語義分析。命名空間也只能限制這部分。 在Json-RPC框架的實現中&#xff0c;遇到如下問題。一開始以為是在實現日志宏的時候&#xff0c;有…

四川省包含哪些水系

背景&#xff1a; 想知道四川省包含哪些水系&#xff0c;以及各個水系的分布&#xff0c;起點、流經省市、終點等 {label: "嘉陵江",value: "嘉陵江",},{label: "渠江",value: "渠江",},{label: "涪江",value: "涪江&q…

子序列問題寫法

子序列問題可以按照動態規劃的思想去寫。 子序列問題類型 子序列 是由數組派生而來的序列&#xff0c;刪除&#xff08;或不刪除&#xff09;數組中的元素而不改變其余元素的順序。 例如&#xff0c;[3,6,2,7] 是數組 [0,3,1,6,2,2,7] 的子序列。 寫法思路 創建兩層for循環…

C++ primer plus 使用類下

目錄 前言 一 轉換函數 總結 前言 接著上一章的內容 一 轉換函數 接著我們上一章節的內容&#xff0c;我們知道我們類里面有一個自動轉換利用這個運算符&#xff0c;這樣就可以使得對象可以接受這個值 那么有沒有可以使一個普通類型去接收一個對象呢&#xff1f; 答案是…

聲網自研算法如何重定義AI交互容災標準

在咖啡廳里&#xff0c;當我把手機置于咖啡機與微波爐形成的電磁干擾區時&#xff0c;WiFi丟包率飆升至83%&#xff0c;但AI的回應延遲僅從1.2秒增至1.4秒。這背后是聲網自研的Phoenix抗弱網算法在發揮作用&#xff0c;通過AI驅動的動態FEC&#xff08;前向糾錯&#xff09;機制…

詳解布隆過濾器及其模擬實現

目錄 布隆過濾器 引入 概念 工作原理 模擬實現布隆過濾器 哈希函數集 布隆過濾器基本框架 add函數&#xff08;添加到布隆過濾器中&#xff09; contains函數&#xff08;判斷是否存在該值&#xff09; 完整代碼 布隆過濾器的刪除 布隆過濾器的誤判率 布隆過濾器的…

巧用 VSCode 與 AI 編碼提升 Vue 前端開發效率

在當今快節奏的軟件開發領域&#xff0c;提升開發效率是每個開發者都追求的目標。對于 Vue 前端開發而言&#xff0c;Visual Studio Code&#xff08;VSCode&#xff09;已經成為了眾多開發者的首選編輯器。而隨著人工智能技術的發展&#xff0c;各類 AI 編碼擴展工具如雨后春筍…

5分鐘快速申請一個EDU教育郵箱

感謝CSDN作者 CodeDevMaster 于 2023-10-16 13:22:40 發布作品《5分鐘快速申請一個EDU教育郵箱》 本文內容為作者方法的實踐與復刻&#xff0c;同時 現在是2025/03/17&#xff0c;執行的細節有部分變動&#xff0c;所以完整展示一波。 祝各位好運&#xff0c;同時本案例中展示…

Go string 字符串底層邏輯

在 Go 語言中&#xff0c;string 類型的底層結構是一個結構體&#xff0c;包含兩個字段&#xff1a;一個指向字節數組的指針和該字節數組的長度。以下是其在 Go 源碼中的大致定義&#xff1a;type stringStruct struct {str unsafe.Pointerlen int } str&#xff1a;這是一個指…

【NLP】10. 機器學習模型性能評估指標(含多類別情況), ROC,PRC

機器學習模型性能評估指標&#xff08;含多類別情況&#xff09; 1. 模型評估指標簡介 在機器學習中&#xff0c;模型的性能評估非常重要。常用的模型評估指標有&#xff1a; 準確率&#xff08;Accuracy&#xff09;精度&#xff08;Precision&#xff09;召回率&#xff0…

開源通義萬相本地部署方案,文生視頻、圖生視頻、視頻生成大模型,支持消費級顯卡!

開源通義萬相本地部署方案&#xff0c;文生視頻、圖生視頻、視頻生成大模型&#xff0c;支持消費級顯卡&#xff01; 萬相2.1開源 近日&#xff0c;大模型萬相2.1&#xff08;Wan&#xff09;重磅開源&#xff0c;此次開源采用Apache2.0協議&#xff0c;14B和1.3B兩個參數規格…

機器學習與深度學習中模型訓練時常用的四種正則化技術L1,L2,L21,ElasticNet

L1正則化和L2正則化是機器學習中常用的兩種正則化方法&#xff0c;用于防止模型過擬合。它們的區別主要體現在數學形式、作用機制和應用效果上。以下是詳細對比&#xff1a; 1. 數學定義 L1正則化&#xff08;也叫Lasso正則化&#xff09;&#xff1a; 在損失函數中加入權重參…

qt+opengl 播放yuv視頻

一、實現效果 二、pro文件 Qt widgets opengl 三、主要代碼 #include "glwidget.h"GLWidget::GLWidget(QWidget *parent) : QOpenGLWidget(parent) {connect(&m_timer, &QTimer::timeout, this,[&](){this->update();});m_timer.start(1000/33); }v…

Android開源庫——RxJava和RxAndroid

RxJava和RxAndroid是什么&#xff1f; RxJava是基于JVM的響應式擴展&#xff0c;用于編寫異步代碼 RxAndroid是關于Android的RxJava綁定 RxJava和RxAndroid使用 依賴 implementation io.reactivex.rxjava3:rxjava:3.1.0 implementation io.reactivex.rxjava3:rxandroid:3.…

并發基礎—三大問題:可見性、原子性、有序性

文章目錄 可見性原子性有序性&#xff08;指令重排&#xff09;經典的指令重排案例&#xff1a;單例模式的雙重檢查鎖volatile和synchronize都可以保證有序性并發壓測工具Jcstress證明指令重排會在多線程下出現問題&#xff08;了解&#xff09;CPU緩存分為三個級別&#xff1a…

PyTorch 入門學習

目錄 PyTorch 定義 核心作用 應用場景 Pytorch 基本語法 1. 張量的創建 2. 張量的類型轉換 3. 張量數值計算 4. 張量運算函數 5. 張量索引操作 6. 張量形狀操作 7. 張量拼接操作 8. 自動微分模塊 9. 案例-線性回歸案例 PyTorch 定義 PyTorch 是一個基于 Python 深…