Vue中從template到j(luò)sx語(yǔ)法教程示例
從 template 到 jsx
大多數(shù) Vue 開(kāi)發(fā)者都習(xí)慣使用 template 模板語(yǔ)法,因?yàn)?nbsp;template 模板語(yǔ)法 具有如下優(yōu)點(diǎn):
熟悉的類(lèi) HTML 結(jié)構(gòu)
- 模板語(yǔ)法可以像 HTML 一樣進(jìn)行布局和設(shè)計(jì),上手快、學(xué)習(xí)成本比低
更簡(jiǎn)潔的寫(xiě)法
- 例如,可以在模板中使用各種 修飾符 來(lái)達(dá)到簡(jiǎn)化編寫(xiě)代碼的過(guò)程
結(jié)構(gòu)與邏輯分離
- 元素結(jié)構(gòu)和邏輯并沒(méi)有雜糅在一起,因此結(jié)構(gòu)上更簡(jiǎn)潔明了
提供更好的性能
- Vue3 中對(duì)模板語(yǔ)法在 編譯階段 進(jìn)行的各種優(yōu)化,使得其性能更好
但即便如此,在某些場(chǎng)景下還是不得不在 Vue 中使用 jsx 語(yǔ)法 實(shí)現(xiàn)需求, 例如開(kāi)發(fā) 內(nèi)部組件庫(kù) 選擇的編寫(xiě)形式就是 jsx 語(yǔ)法 等。
而對(duì)于習(xí)慣使用 template 模板語(yǔ)法 的開(kāi)發(fā)者并不是輕易的就能轉(zhuǎn)換到相應(yīng) jsx 語(yǔ)法,因此本文就列舉一些 template 模板語(yǔ)法 中對(duì)應(yīng)的 jsx 語(yǔ)法 應(yīng)該怎么寫(xiě)。
插值表達(dá)式(文本插值)
template 語(yǔ)法
最基本的數(shù)據(jù)綁定形式就是 文本插值,它使用的是 Mustache 語(yǔ)法 (即 {{}} ),雙大括號(hào) 中的內(nèi)容最終 會(huì)將數(shù)據(jù)解釋為純文本。
<span>Message: {{ msg }}</span>jsx 語(yǔ)法
而 JSX 中使用 文本插值 就從 雙大括號(hào) {{ }} 變成 單大括號(hào) {}
<span>Message: { msg }</span>原始 HTML
template 語(yǔ)法
雙大括號(hào) 會(huì)將數(shù)據(jù)解釋為純文本,而不是 HTML,因此若想在模板中 插入 HTML,我們需要使用 v-html 指令:
// html 字符內(nèi)容
rawHtml = '<span>hello!</span>'
// 最終變成純文本
<p>Using text interpolation: {{ rawHtml }}</p>
// 最終渲染為 html 結(jié)構(gòu)
<div>Using v-html directive: <p v-html="rawHtml"></p></div>jsx 語(yǔ)法
而在 jsx 語(yǔ)法 中就更直接了,我們直接通過(guò) 變量 的形式來(lái)寫(xiě) html 結(jié)構(gòu) 配合上 文本插值 {} 即可:
// 最終變成純文本
cosnt rawHtml = '<span>hello!</span>'
<p>Using text interpolation: { rawHtml }</p>
// 最終渲染為 html 結(jié)構(gòu)
cosnt rawHtml = <span>hello!</span>
<div>Using v-html directive: { rawHtml }</div>條件渲染
template 語(yǔ)法
在模板語(yǔ)法中和 條件渲染 相關(guān)的可以直接使用指令 v-if / v-show 來(lái)實(shí)現(xiàn):
<p v-show="isShow">hello world!</p> <p v-show="!isShow">hello bros!</p> <p v-if="isShow">hello world!</p> <p v-else>hello bros!</p>
jsx 語(yǔ)法
而在 jsx 語(yǔ)法 中我們就不能使用 指令形式 了,取而代之的是 JavaScript 中的 if-else、&&、||、三元表達(dá)式 等形式:
if-else
const content = (isShow) => {
if(isShow){
return <h1>hello world!</h1>
}else{
return <div>hello bros!</div>
}
}&&
{ isShow && <div>hello world!</div> }
{ !isShow && <div>hello bros!</div> }||
const content1 = <h1>hello world!</h1>
const content2 = <h1>hello world!</h1>
<div>{ content1 || content2 } </div>三元表達(dá)式
const content1 = <h1>hello world!</h1>
const content2 = <h1>hello world!</h1>
<div>{ isShow ? content1 : content2 } </div>列表渲染
tempalte 語(yǔ)法
在 template 模板 中可以通過(guò) v-for 指令 來(lái)快速實(shí)現(xiàn)列表渲染:
<ul>
<li v-for="item in list" :key="item.key">{{ item.text }}</li>
</ul>jsx 語(yǔ)法
在 jsx 語(yǔ)法 中通常是使用 Array.prototype.map() 方法來(lái)實(shí)現(xiàn)列表渲染,原因就在于這個(gè)遍歷數(shù)組的方法返回值也是數(shù)組:
<ul>
{
list.map((item) => (
<li key={item.key}>{ item.text }</li>
))
}
</ul>style 外部樣式
template 語(yǔ)法
在 .vue 文件 中可以通過(guò) <style> 標(biāo)簽來(lái) 編寫(xiě)樣式 或 導(dǎo)入外部樣式,還可以直接通過(guò)設(shè)置 scope 實(shí)現(xiàn)局部樣式:
<script setup lang="ts">
import { ref } from "vue";
import ChcekBox from "./components/CheckBox";
const checkResult = ref(false);
</script>
<template>
<ChcekBox v-model="checkResult">選項(xiàng)</ChcekBox>
</template>
<style scope>
@import './index.less';
</style>jsx 語(yǔ)法
而在一個(gè) .jsx / .tsx 文件中由于不存在 <style> 元素,因此無(wú)法通過(guò)其來(lái)編寫(xiě)或?qū)霕邮?,或者通過(guò) scope 實(shí)現(xiàn)局部樣式,可通過(guò)如下方式導(dǎo)入:
直接 import 導(dǎo)入
import { defineComponent, ref } from 'vue'
import './index.less'
export default defineComponent({})通過(guò) CSS Module 導(dǎo)入
import { defineComponent, ref } from 'vue'
import styleModule from './index.module.less'
export default defineComponent({
setup() {
return () => (
<label class={styleModule.abs}>hello world!</label>
)
})事件綁定
tempalte 語(yǔ)法
在模板語(yǔ)法中綁定事件可以使用 v-on(簡(jiǎn)寫(xiě) @) 來(lái)實(shí)現(xiàn),并且可以在模板中 直接傳遞參數(shù) 給目標(biāo)事件,也可以配合使用 事件修飾符,支持內(nèi)聯(lián)事件等等。
綁定處理函數(shù)
<!-- 方法處理函數(shù) --> <button v-on:click="doThis"></button> <!-- 縮寫(xiě) --> <button @click="doThis"></button>
使用修飾符
<!-- 鏈?zhǔn)秸{(diào)用修飾符 -->
<button @click.stop.prevent="doThis"></button>傳遞參數(shù)
<!-- 傳參 --> <button @click="doThis($event, params)"></button>
內(nèi)聯(lián)事件
<!-- 傳參 --> <button @click="count++"></button>
jsx 語(yǔ)法
上述寫(xiě)法在 jsx 語(yǔ)法 中的對(duì)應(yīng)寫(xiě)法具體如下:
綁定處理函數(shù)
需要使用 on + [eventName] 的形式來(lái)綁定事件,可使用 或 不使用 駝峰形式,但當(dāng)使用 typescript 時(shí)建議使駝峰形式,否則會(huì)有提示:
<!-- 駝峰 -->
<button onClick={doThis}></button>
<!-- 非駝峰 -->
<button onclick={doThis}></button>使用修飾符
在 jsx 語(yǔ)法 中不能直接使用 .stop 形式的事件修飾符,需要通過(guò) withModifiers 函數(shù)來(lái)實(shí)現(xiàn),其支持 事件和按鍵修飾符:
<!-- withModifiers -->
<button onClick={withModifiers(doThis, ['prevent'])}></button>傳遞參數(shù)
在 jsx 語(yǔ)法 中不能像在模板中使用 handleAction($event, params) 的方式來(lái)實(shí)現(xiàn)傳參,因?yàn)檫@種寫(xiě)法在 jsx 中屬于調(diào)用,因此相當(dāng)于把函數(shù)返回值作為事件綁定到目標(biāo)元素上,大多數(shù)情況下會(huì)拋出異常(即返回值不一定為函數(shù)):
使用 bind 實(shí)現(xiàn)傳參
const bindEvent = doThis.bind(tarrget)
<!-- 傳參 -->
<button onClick={bindEvent}></button>使用 箭頭函數(shù) 實(shí)現(xiàn)傳參
<!-- 傳參 -->
<button onClick={ (parms) => bindEvent(parms)}></button>內(nèi)聯(lián)事件
在 jsx 語(yǔ)法 并不支持內(nèi)聯(lián)事件的寫(xiě)法,因此可以使用箭頭函數(shù)來(lái)包裹:
<!-- 方式一 -->
<button onClick={ () => count++ }></button>
<!-- 方式一 -->
const addCount = () => count++
<button onClick={ addCount }></button>雙向綁定 v-model
template 語(yǔ)法
v-model 可以在組件上使用以實(shí)現(xiàn) 雙向綁定:
- 在 原生表單元素 上使用
v-model會(huì)被編譯為value 屬性和input 事件 - 在 組件 上使用
v-model會(huì)被編譯為modelValue 屬性和update:modelValue 事件 - 支持自定義
v-model綁定的屬性名和事件名
// 常見(jiàn)表單 <input v-model="searchText" /> // 自定義組件 <CustomInput v-model="searchText" /> // 自定義 v-model 名 <MyComponent v-model:title="bookTitle" />
jsx 語(yǔ)法
正常綁定
<CustomInput v-model={searchText} />自定義名稱(chēng)
jsx 語(yǔ)法 中不存在類(lèi)似 v-model:title 的命名形式,因此我們給 v-model 一個(gè)數(shù)組,如 [title, 'titleAlias']:
- 數(shù)組的第一個(gè)參數(shù)就是要綁定的 值
數(shù)組的第二個(gè)參數(shù)就是要綁定的 自定義名稱(chēng)
<Custom v-model={[title, 'titleAlias']} />slot 插槽
template 語(yǔ)法
在模板語(yǔ)法中可以 <slot> 元素來(lái)定義 插槽出口,用于標(biāo)示父元素提供的 插槽內(nèi)容 的渲染位置:
默認(rèn)插槽
<button class="fancy-btn"> <slot></slot> <!-- 插槽出口 --> </button>
具名插槽
<button class="fancy-btn"> <slot name="content"></slot> <!-- 插槽出口 --> </button>
動(dòng)態(tài)插槽
<div>
<!-- 動(dòng)態(tài)插槽 -->
<template v-slot:[dynamicSlotName]> ... </template>
<!-- 縮寫(xiě)為 -->
<template #[dynamicSlotName]> ... </template> </base-layout>
</div>作用域插槽
<!-- MyComponent 模板 -->
<div>
<slot :text="greetingMessage" :count="1"></slot>
</div>
<!-- 父組件模板 -->
<MyComponent v-slot="slotProps">
{{ slotProps.text }} {{ slotProps.count }}
</MyComponent>jsx 語(yǔ)法
由于 jsx 語(yǔ)法 中不存在 <slot> 元素,因此只能通過(guò)如下方式來(lái)渲染插槽內(nèi)容:
從 SetupContext 中獲取
defineComponent({
setup(props, { slots }) {
return <div>
{ slots.default && slots.default() }
{ slots.nameSlot && slots.nameSlot() }
</div>
}
})使用 useSlot() 方法
import { defineComponent, renderSlots } from 'vue'
defineComponent({
setup(props, context) {
const slots = useSlots();
return <div>
{ renderSlot(slots, 'default') }
</div>
}
})使用 renderSlot() 方法
import { defineComponent, renderSlot } from 'vue'
defineComponent({
setup(props, { slots }) {
return <div>
{ renderSlot(slots, 'default') }
</div>
}
})使用 Scoped Slots 作用域插槽
<!-- MyComponent 模板 -->
defineComponent({
setup(props, { slots }) {
const slotParams = { name: 'hello' };
return <div>
{ slots.default && slots.default(slotParams) }
</div>
}
})
<!-- 父組件模板 -->
defineComponent({
setup(props, { slots }) {
return <div>
<MyComponent v-slot="slotProps">
{{ slotProps.name }}
</MyComponent>
</div>
}
})以上就是Vue中從template到j(luò)sx語(yǔ)法指北的詳細(xì)內(nèi)容,更多關(guān)于Vue template jsx語(yǔ)法的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue項(xiàng)目打包開(kāi)啟gzip壓縮具體使用方法
這篇文章主要為大家介紹了vue項(xiàng)目打包開(kāi)啟gzip壓縮具體使用方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07
vue后端傳文件流轉(zhuǎn)化成blob對(duì)象,前端點(diǎn)擊下載返回undefined問(wèn)題
這篇文章主要介紹了vue后端傳文件流轉(zhuǎn)化成blob對(duì)象,前端點(diǎn)擊下載返回undefined問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12
在Vue項(xiàng)目中使用d3.js的實(shí)例代碼
這篇文章主要介紹了在Vue項(xiàng)目中使用d3.js的實(shí)例代碼,非常不錯(cuò),具有參考借鑒價(jià)值價(jià)值,需要的朋友可以參考下2018-05-05
vue.js中proxyTable 轉(zhuǎn)發(fā)請(qǐng)求的實(shí)現(xiàn)方法
今天小編就為大家分享一篇vue.js中proxyTable 轉(zhuǎn)發(fā)請(qǐng)求的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09
vue中計(jì)算屬性和方法的區(qū)別及說(shuō)明
這篇文章主要介紹了vue中計(jì)算屬性和方法的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09
vue使用swiper實(shí)現(xiàn)中間大兩邊小的輪播圖效果
這篇文章主要介紹了vue使用swiper實(shí)現(xiàn)中間大兩邊小的輪播圖效果,本文分步驟通過(guò)實(shí)例代碼講解的非常詳細(xì),需要的朋友可以參考下2019-11-11
微前端qiankun主應(yīng)用與子應(yīng)用之間的跳轉(zhuǎn)示例
這篇文章主要為大家介紹了微前端qiankun主應(yīng)用與子應(yīng)用之間的跳轉(zhuǎn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08

