欧美成人精品手机在线观看_69视频国产_动漫精品第一页_日韩中文字幕网 - 日本欧美一区二区

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

Vue有20樣寫法,你知道么?

admin
2024年10月18日 20:47 本文熱度 400

引入

打開 Vue3 的官方文檔,它首先會告訴你,Vue 的組件可以按兩種不同的風格書寫:選項式 API 和組合式 API。文檔為我們提供一系列兩種風格的代碼參考,供我們按照偏好進行選擇。

實際上,Vue3 組件可不止兩種寫法,而是多達十幾種!然而,不管是什么寫法,它們都是基于同一個底層系統實現的,概念之間也是彼此相通的,只是使用的接口不同。在實際開發中,我們也不會同時使用到那么多種寫法,但是這并不意味著我們不需要去了解這些寫法!

如果你仔細閱讀 Vue3 的文檔,會發現一些示例或者 api 看起來模棱兩可,不知道這些 api 到底有什么用,或者閱讀 Vue 的源碼時,總是能發現一些對于我們來說意圖不明的邏輯,那么,你可能先要了解一些 Vue 的寫法。先了解一個東西怎么用,再去分析它是怎么實現的。

看完本文章,你會收獲到:

  1. vue 的渲染原理。
  2. 什么是 defineComponent、h、creatVnode。
  3. 渲染函數和 jsx 的區別。
  4. 馬上能夠上手 jsx。
  5. 輕松閱讀 vue 文檔的所有示例和 api。
  6. 輕松看懂不同的 vue 組件寫法。
  7. 不管新手老手,都會對 Vue 有所新的認識。
  8. 等等...

本文章遵從循序漸進的寫作順序,從易到難,輕松上手!

setup 語法糖

setup 語法糖應該是最常用的寫法了。在 Vue3 中,我們想封裝一個組件,最習慣的做法還是新建一個 Vue 文件,并將組件代碼寫在文件中。具體是:頁面結構寫在 template 中,頁面邏輯寫在 script 中,頁面樣式寫在 style 中。

總之,我們將與該組件相關的代碼都寫在一起、放在一個文件中單獨維護,在需要該組件的地方引入使用。

這里我們使用了 setup 語法糖,直接在 script 中書寫我們的 setup 內部的邏輯。

<template>
  <div>{{ name }}</div>
</template>

<script setup lang="ts">
import { ref } from "vue";
const name = ref("天氣好");
</script>

<style scoped></style>

在 App. vue 中引入并使用:

// App.vue
<template>
  <User />
</template>

<script setup lang="ts">
import User from "./User.vue";
</script>

<style scoped></style>

注:后續寫法盡管形式不同,但它們最終的目的都是導出一個組件,所以對于組件使用方來說(這里是 App. vue),怎么使用這個組件的代碼都是不變的,所以將不再重復此代碼。

Vue2 選項式寫法

Vue2 經典寫法

這種寫法也是比較經典的。和 setup 語法糖寫法類似。我們需要新建一個 vue 文件來存儲我們的組件代碼,然后在需要使用該組件的地方對其進行引入。區別在于,我們需要在 script 中導出一個 Vue 實例。

這里我們導出的其實是一個普通對象,該對象包含 data、methods 等屬性。這個對象的屬性都是可選的,即 option,翻譯回來即“選項”。

<template>
  <div>{{ name }}</div>
</template>

<script lang="ts">
export default {
  data() => {
    return {
      name"天氣好",
    };
  },
};
</script>

<style></style>

defineComponent 輔助函數

盡管我們在 script 語言塊中導出的默認對象會被 vue 編譯器當成 vue 實例,但不管怎么看,它依舊只是一個 plain object。在定義組件實例方面,vue 提供了一個名為 defineComponent 輔助接口。

<template>
  <div>{{ name }}</div>
</template>

<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
  data() => {
    return {
      name"天氣好",
    };
  },
});
</script>

<style></style>

盡管這個接口也不能改變我們導出的是一個普通對象的事實,但是它可以為我們的實例提供強大的類型推導。我們可以把它看成是一個返回 vue 實例的工廠函數,讓我們的代碼看起來更加規范。

Vue3 選項式寫法

在 Vue3 中,官方引入了新的選項 setup,這是 Vue3 選項式寫法和 Vue2 寫法的主要區別。setup 選項的意義在于它允許我們在選項式的寫法中引用和使用組合式的 api,比如 onMounted、ref、reactive 等。但對于我們來說,它對于我們有益的地方還是基于它封裝起來的 setup 語法糖用起來很方便。

<template>
  <div>{{ name }}</div>
</template>

<script lang="ts">
export default {
  setup() {
    return {
      name"天氣好",
    };
  },
};
</script>

<style></style>

使用 defineComponent 時,它能夠提示我們 setup 將會接收到什么參數:

<template>
  <div>{{ name }}</div>
</template>

<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
  setup(prop,context) {
    return {
      name"天氣好",
    };
  },
});
</script>

<style></style>

以上寫法我們都是在 template 上書寫我們的頁面結構,這也是最常見的幾種寫法,下面我們來介紹幾種了解 vue 底層必不可少的寫法,渲染函數。

手寫渲染函數

template 模板語法本質上也可以算是一種語法糖。在 vue 編譯器上,template 中的內容最終會被翻譯為渲染函數,掛載到 vue 實例的 render 屬性上。當需要渲染組件時,vue 就執行一次 render,得到對應的虛擬節點樹,最后再轉變為真實 dom。

Vue 允許我們脫離 template,直接自己書寫渲染函數。位置就在導出實例的 render 選項上:

<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
  data() => ({ name"天氣好" }),
  render() {
    return this.name;
  },
});
</script>

<style></style>

在 template 中,我們使用類似 html 的模板語法來描述我們的視圖,在 render 函數中又如何描述呢?vue 提供了兩個 api:createVnode 和 h。二者沒有區別,h 函數只是 createVnode 的縮寫。有了 render 函數,我們就不需要寫 template 了。

<script lang="ts">
import { defineComponent, h } from "vue";
export default defineComponent({
  data() => ({ name"天氣好" }),
  render() {
    return h("div"this.name);
  },
});
</script>

<style></style>

在上面的示例中,我們使用 h 函數生成了一個 vNode,并 return 出去,作為本組件最終在被使用時渲染出來的效果。

在 template 中我們可以使用 v-if、v-for、slot 等模板語法,在 h 函數中這些概念也是支持的,只是形式不同,這方面官方文檔有具體的示例。總之,template 模板和 render 選項是可以相互替代的。

setup 返回渲染函數

setup 返回 render 方法

一般來說,在選項式語法中,setup 方法返回一個對象,該對象暴露給 template,供 template 使用,具體參考第三個例子(vue3 選項式寫法)。如果我們不使用 template,也就沒有返回對象的必要了。

在 Vue3 中,還有另外一種不使用 template 的寫法,就是在 setup 方法中返回一個 render 方法。

<script lang="ts">
import { defineComponent, h, ref } from "vue";
export default defineComponent({
  setup() {
    const name = ref("天氣好");
    return () => h("div", name.value);
  },
});
</script>

<style></style>

注意:

  1. 在選項式中使用 setup 之后,一般不應該再使用 data、生命周期等在選項式寫法中常用的選項,而應該把主要邏輯都寫在 setup 中,并適當引入組合式的 api。比如,使用 ref,而不是 data 選項。
  2. ref 自動解包是 template 特有的功能,h 函數是沒有這個功能的。在 h 函數中引入 ref,記得理所當然地帶上 .value

defineComponent 傳入setup

就注意中的第一點,我們可以采用下面這種寫法:直接在 defineComponent 中書寫 setup 函數(如果再省一點就是 setup 語法糖的寫法了)。

<script lang="ts">
import { defineComponent, h, ref } from "vue";
export default defineComponent(() => {
  const name = ref("天氣好");
  return () => h("div", name.value);
});
</script>

<style></style>

以上就是渲染函數的寫法,是不是有點感覺了呢,一下子就學會了兩個 api!后面會提到的 Jsx 寫法其實也應該歸為渲染函數寫法的一種(只要不是 template,而是用 JavaScript 表達頁面結構的,都是渲染函數),但是相對于 h 函數,jsx 并不是純粹的 js,所以我將它們分成了兩類。

Vue & Jsx

在render 中使用 jsx

有了前面兩類寫法介紹的鋪墊,接下來引入 jsx 語法就沒有什么難理解的點了。

jsx 在 vue 文件中是這樣寫的。在 render 渲染函數返回值處書寫 jsx 替代 h 函數。書寫純 JavaScript 的 h 函數描述結構還是比較繁冗的,jsx 就是簡化了的h 函數寫法。

<script lang="tsx">
import { defineComponent } from "vue";
export default defineComponent({
  data() {
    return { name"天氣好" };
  },
  render() {
    return (
      <>
        <div>{this.name}</div>
      </>

    );
  },
});
</script>

<style></style>

在 setup 中使用jsx

jsx 和 setup 配合食用更加。在選項式風格中使用 setup,在 setup 中使用組合式 api,并且返回 jsx 書寫的渲染函數。

<script lang="tsx">
import { defineComponent, ref } from "vue";
export default defineComponent({
  setup() {
    const name = ref("天氣好");
    return () => <>{name.value}</>;
  },
});
</script>

<style></style>

defineComponent 簡寫

這個其實就是前面介紹過的 「defineComponent 傳入 setup」 函數寫法:這里的區別只是使用 jsx 替代了 h 函數。

<script lang="tsx">
import { defineComponent, ref } from "vue";
export default defineComponent(() => {
  const name = ref("天氣好");
  return () => (
    <>
      <div>{name.value}</div>
    </>

  );
});
</script>

<style></style>

自行導出 vNode 對象

我們也可以自己將 render 函數執行一遍,然后將得到的 jsx Element 導出,和上一個示例「defineComponent 簡寫」是十分相似。但是這段代碼的缺點非常致命,它不支持接收外部傳遞來的屬性參數。

<script lang="tsx">
import { ref } from "vue";
export default (() => {
  const name = ref("天氣好");
  return () => (
    <>
      <div>{name.value}</div>
    </>

  );
})();
</script>

<style></style>

不要使用這種寫法。這里會提到這樣寫,只是因為和后面的「函數式組件(其二)」 寫法有關聯。本寫法與其它寫法都不同,其它寫法導出的都是 JavaScript 對象或者 jsx 對象,而這里我們則是自己執行了一遍渲染函數并得到了虛擬節點,直接將虛擬節點導出去。既然都已經把虛擬節點創建出來了,那自然無法接收 props。

defineComponent 的第二個參數

如果 defineComponent 的第一個參數是 setup 函數,那么它的第二個參數則可以為組件的定義添加需要的選項,但一般除了補充 props 選項,不會再需要其它選項了(組合式 api 和 setup 的入參可以完全替代其它選項)。

<script lang="tsx">
import { defineComponent } from "vue";
export default defineComponent(
  (props) => {
    return () => (
      <>
        <div>{props.userName}</div>
      </>

    );
  },
  {
    props: { userNameString },
  }
);
</script>

<style></style>

直接在 vue 中使用 jsx

這里 jsx 不再只作為返回值,而是直接被某處使用。它可以是被直接導出,或者用在 template 上。

直接導出 jsx 對象

直接將 jsx 對象導出使用。比前面的寫法更簡潔,做法就是把 setup 里面的內容提到外面。這里需要注意的是我們導出的是一段直接的 jsx 對象(jsx Element),而不是渲染函數。

<script lang="tsx">
import { ref } from "vue";
const name = ref("天氣好");
const User = <>{name.value}</>;
export default User;
</script>

<style scoped></style>

直接用在 template 上

這種寫法可以幫助你在自身的組件內復用一些顆粒度更小的組件,它和 setup 語法糖的寫法非常接近,只是 User 變量可以作為標簽直接使用。

<template>
  <User />
</template>

<script setup lang="tsx">
import { ref } from "vue";
const name = ref("天氣好");
const User = <>{name.value}</>;
</script>

<style></style>

函數式組件(其一)

你還可以將 User 寫成函數式組件,在本頁面內使用。但它不會將連字符屬性轉換為小駝峰寫法。這和「直接用在 template 上」的內容都是一樣的,它們都是為了方便在組件本身復用一些常用的組件。

<template>
  <User :user-name="name" />
</template>

<script setup lang="tsx">
import { ref } from "vue";
const name = ref("天氣好");
const User = (props: { "user-name": string }) => {
  return <>{props["user-name"]}</>;
};
</script>

<style></style>

如果你經常使用 tailwind,你可能就會知道什么情況下會出現小顆粒度的可復用標簽,比如,一個加了一大堆類名的 div 標簽。

獨立的 Jsx 文件

以上介紹的所有寫法,都是在 .vue 文件中書寫的,而且也離不開 <script>。接下來的寫法可以讓我們脫離 Vue 的語法塊框架,書寫更像 jsx 的 jsx。

jsx 定義組件

我們需要新建一個 jsx/tsx 文件,然后只要保證導出的仍然是一個組件就可以了。有了前面的鋪墊,我們不難發現,這不就是去掉 script 標簽的選項式寫法嗎?確實!這是因為我故意在前面安排了選項式寫法的例子,所以過渡到這里完全沒有壓力!

// User.tsx
import { ref } from 'vue'
export default {
  setup() {
    const name = ref('天氣好')
    return () => <><div>{name.value}</div></>
  }
}

我還是推薦套上 defineComponent:

// User.tsx
import { ref, defineComponent } from 'vue'
export default defineComponent({
  setup() {
    const name = ref('天氣好')
    return () => (<><div>{name.value}</div></>)
  }
});

同樣地,前面對于 defineComponent 不同方式的使用這里也都可以的。比如導出普通對象并在 render 或者 setup 中使用 jsx 等等。從 vue 到 jsx,區別只是省下了 script 語法塊。

vue2 選項式寫法+jsx。

// User.tsx
import { defineComponent } from 'vue'
export default defineComponent({
  data() => ({ name'天氣好' }),
  render() {
    return <><div>{this.name}</div></>
  }
});

導出普通對象:

// User.tsx
export default {
  data() => ({ name'天氣好' }),
  render() {
    return <><div>{this.name}</div></>
  }
});

函數式組件(其二)

Vue 中支持的最像函數式組件的寫法。

// User.tsx
import { ref } from 'vue'

export default function User(props{
  const name = ref('天氣好')
  return <><div>{name.value}</div></>
}

該例和前面的「自行導出 vNode 對象」非常接近,這也是為什么即使后者存在不能接收參數的缺陷我也會提出來,因為二者都是使用接近函數式組件的寫法來描述組件的,但是在 vue 文件中并沒有辦法直接導出這個函數組件,而是需要自行執行得到vNode。而在 jsx 文件中卻可以將其導出,并且支持接收參數。

如果你需要為其定義 props,也不需要使用 「defineComponent 的第二個參數」為你提供什么 props 選項,而是直接在函數式組件的 props 、emits 屬性上掛載對應的配置。

import { ref } from 'vue'

User.props = {
  userNameString
}

function User(props{
  // const name = ref('天氣好')
  return <><div>{props.userName}</div></>
}

export default User;

相信習慣了 React 的 fc 的小伙伴,看到這里一定感覺倍感親切。然而 Vue 的 Jsx 終究只是 Vue 的 Jsx,它并沒有像 React 一樣存在那么多強大的 Hooks 和內置組件,而是僅僅只是 h 函數的便捷寫法。在語法上也和 React Jsx 存在諸多區別。和 React Jsx 相比,Vue Jsx 其實和自家的 template 更接近。不過 Vue Jsx 寫法的靈活性還是要比 template 模板高,但官方更推薦使用 template。template 更容易上手且提供了更好的性能優化,除非你想完完全全掌控組件的每一個細節,才需要jsx。

小結

盡管本文提到了很多種寫法,但大多數寫法在大多數時候都是不會派上用場的,也應該不被派上用場。之所以列舉那么多寫法,主要的目的還是為了循序漸進引入 jsx 文件寫法和函數式組件寫法。

可以看出,Vue 的寫法本質上是選項式的。Vue3 在 Vue2 的基礎上引入了 setup 選項和 setup 語法糖,結合組合式 api 后,開發者可以將組件的大部分邏輯都維護在 setup 中,而不是 vue2 中割裂了邏輯的 data+created+methods 選項。

在此基礎上,setup 語法糖支持自動導出組件功能,為我們日常開發帶來了很大的便利。

但是除了使用 template 來表達我們的結構,我們也可以自己使用 render 選項并借助 h 函數或者 jsx 的力量來手寫渲染函數。這些都是在 vue 文件中完成的。

既然都不需要 template 了,那么 vue 文件里就只剩下一個 script 了(我們先忽略 style)。在 jsx 文件中,就允許我們直接書寫導出對象(仍是選項式的寫法),忽略script。

最后是 Vue 的 jsx 文件獨有的特性。它允許我們導出一個函數作為組件,我們稱之為函數式組件(fc,function component),這是 vue 文件和以前所有寫法所不具備的,外形與 React 相近。

總的來說就一句話,「Vue 本身仍然是選項式的,但是它現在還額外支持了在 jsx 文件中書寫 fc。」

個人看法

使用哪一種寫法,主要看個人偏好。每種寫法在特定場景下都有它的好處和壞處。選擇哪一種并不重要。但是我還是提幾點個人建議:

  1. 優先選擇 setup 語法糖。
  2. 使用選項式時,推薦套上 defineComponent。
  3. 當需要使用 jsx 時,推薦在 vue 文件中使用選項式 setup+返回 jsx 渲染函數的寫法。

為什么不推薦函數式組件的寫法,因為它需要寫在 jsx 文件里。如果你只是想通過 jsx 為你的組件增強某些功能,直接改造 vue 文件更加方便,并且不需要修改你引入文件的后綴(.vue -> .jsx/.tsx)。最重要的是,如果真的想寫函數式組件,為何不試試 React?

當然以上只是我個人的小小看法。如果覺得有用,不妨動動小手點贊和收藏吧!

看到這里,如果你也想試試在 Vue 中寫 jsx,不妨看看這篇文章,分享了怎么在 Vue 項目中配置 jsx 環境,充分發揮 jsx 的優勢!

傳送門:【Vue3】對el-form進行二次封裝后,我的開發效率提升了3倍 - 掘金

參考

渲染函數 & JSX | Vue.js


該文章在 2024/10/19 12:27:24 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2025 ClickSun All Rights Reserved