時間:2023-06-06 23:12:02 | 來源:網(wǎng)站運(yùn)營
時間:2023-06-06 23:12:02 來源:網(wǎng)站運(yùn)營
簡化版的 vue 頁面模板語法:簡化的目的:SomeComponent.tm
<html> <body> <div :title="myTitle" /> </body></html>
SomeComponent.ts
import * as Biz from '@triones/biz-kernel';export class SomeComponent extends Biz.MarkupView { public readonly myProp1: string; public readonly myProp2?: string; public get myTitle() { return '..some title...' + this.myProp1; }}
當(dāng)調(diào)用 SomeComponent 組件的時候,會創(chuàng)建對應(yīng)的 SomeComponent.ts 這個類的實(shí)例。然后渲染頁面的時候,會用 SomeComponent.tm 來渲染。通過 :title 這樣的屬性來綁定“展現(xiàn)”和“邏輯”,渲染的時候 get myTitle() 這個 getter 屬性會被求值。<SomeComponent myProp1="hello" />
這個時候,從 public readonly myProp1: string 上就可以取到傳入的 myProp1 屬性。沒有傳的 myProp2 屬性就是 undefined。SomeComponent.tm
<html> <body> <button @onClick="sayHello">hello</button> </body></html>
SomeComponent.ts
import * as Biz from '@triones/biz-kernel';export class SomeComponent extends Biz.MarkupView { public sayHello() { // ... }}
和 vue 類似的是都是用 : 和 @ 來表達(dá)屬性綁定和事件處理。和 vue 不同的是,在綁定的地方只能寫屬性名字引用對應(yīng)的屬性,不能寫復(fù)雜的表達(dá)式。和微信的 wxml 語法類似,bind:tap 這樣的事件綁定的地方,也是只能寫一個 event handler 的方法名,不能寫表達(dá)式。<template #default> <Header /> <Body /> <Footer /></template<template #Header> ...</template><template #Body> ...</template><template #Footer> ...</template>
這么寫就省得建立 4 個組件了,合并寫到一個組件里。如果沒有寫 <template #default>,那默認(rèn)就是包裹在 <template #default> 里的。從語法上來說,也非常類似微信小程序的 wxml 的寫法。只是微信小程序的 wxml 沒有 <template #default>,而是直接寫在了文件的頂層。<div>hello</div>
和這么寫<template #default> <div>hello</div></template>
是等價的<LineChart width={500} height={300} data={data}> <XAxis dataKey="name"/> <YAxis/> <CartesianGrid stroke="#eee" strokeDasharray="5 5"/></LineChart>
如果是 react 組件,往往會用 React.Children 來遍歷這些子節(jié)點(diǎn),從中提取數(shù)據(jù)做為參數(shù)來使用。也就是給一個組件傳遞 children,有的時候傳的是組件,有的時候傳的是渲染組件的函數(shù),有的時候傳遞過去被當(dāng)成 array/object 使用。這也是 jsx 語法從一開始沒有設(shè)計(jì)好的地方。<LineChart XAxis="{ dataKey: "name" }" YAxis CartesianGrid="{ stroke: "#eee", strokeDasharray="5 5" } />
書寫體驗(yàn)會非常難受,這一行 LineChart 組件的調(diào)用也會非常的長。把這些屬性折行之后寫成 children,就可以更結(jié)構(gòu)化地進(jìn)行書寫。<LineChart :wdith="500" :height="300" :data="data"> <attr #XAxis dataKey="name"/> <attr #YAxis>true</attr> <attr #CartesianGrid stroke="#eee" strokeDasharray="5 5"/></LineChart>
用 #xxx 的方式來表達(dá),我是給組件傳遞了 xxx 屬性。這樣做為數(shù)據(jù)使用的 children,和做為組件使用的 children 就被區(qū)分開了。定義組件
<div class="container"> <header> <slot :render="header" /> </header> <main> <slot :render="children" /> </main> <footer> <slot :render="footer" /> </footer></div>
通過 <slot> 來表達(dá),這個地方可以用戶自定義。使用組件
<BaseLayout> <fragment #header> <h1>Here might be a page title</h1> </fragment> <fragment #children> <p>A paragraph for the main content.</p> <p>And another one.</p> </fragment> <fragment #footer> <p>Here's some contact info</p> </fragment></BaseLayout>
這里用 <fragment> 來表達(dá),傳入的是一個具體的實(shí)例,而不是可以被多次調(diào)用的參數(shù)。如果是 React,那么類型就是 ReactNode。定義組件
<div class="container"> <header> <slot :render="header" title="abc" /> </header> <footer> <slot :render="footer" title="xyz" /> </footer></div>
<slot> 渲染的額時候,額外提供了參數(shù)使用組件
<BaseLayout> <template #header> <h1>Here might be a page title: {{ #header.title }}</h1> </template> <template #footer> <p>Here's some contact info: {{ #footer.title }}</p> </template></BaseLayout>
傳入 template 和 fragment 不同,template 會捕獲參數(shù),從而可以在 template 內(nèi)容里引用。template 比 fragment 更常用,所以有一種簡寫形式:使用組件
<BaseLayout> <h1 #header>Here might be a page title: {{ #header.title }}</h1> <p #footer>Here's some contact info: {{ #footer.title }}</p></BaseLayout>
綜上 #xxx 是一種傳遞各種復(fù)雜屬性的寫法。相比 jsx 的語法,折行書寫更舒服。<import from="@vant/weapp/tag/index" as="VantTag"/><template #default> <view> <VantTag /> </view></template>
這里引用的 @vant/weapp 是外部第三方組件,通過 import 就可以直接被使用。import 后的組件可以當(dāng)作“虛擬節(jié)點(diǎn)”傳遞出去使用。這個是微信小程序特有的概念:<import from="@app/MyComps/MyHeader" /><import from="@app/MyComps/MyFooter" /><template #default> <BaseLayout :header="<MyHeader/>" :footer="<MyFooter/>" /></template>
BaseLayout 要聲明自己接受這么兩個抽象節(jié)點(diǎn),所以要和普通的 slot 區(qū)分開來<div class="container"> <header> <slot :component="header" title="abc" /> </header> <footer> <slot :component="footer" title="xyz" /> </footer></div>
區(qū)別就是 <slot :component ..> 代替了 <slot :render ...>。定義組件
<div class="container"> <main> <slot :render="children" /> </main></div>
使用組件
<BaseLayout> <p>A paragraph for the main content.</p> <p>And another one.</p></BaseLayout>
這個實(shí)際上等價于使用組件
<BaseLayout> <fragment #children> <p>A paragraph for the main content.</p> <p>And another one.</p> </fragment></BaseLayout>
也就是普通寫法下的子組件,其實(shí)是一個 fragment 類型的 slot。<dynamic :visible="vip"> <p>you are vip</p></dynamic>
分支<dynamic :slot="userType"> <fragment #vip><p>you are vip</p></fragment> <fragment #normal><p>you are normal</p></fragment></dynamic>
循環(huán)<template #default> <ul> <dynamic :expand="items" key="id"><MyItem #element></dynamic> </ul></template><template #MyItem> <span>{{ #MyItem.firstName }}</span><span>{{ #MyItem.lastName }}</template>
關(guān)鍵詞:模板,語法,簡化
客戶&案例
營銷資訊
關(guān)于我們
微信公眾號
版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。