更新時(shí)間:2021-09-02 10:33:08 來源:動(dòng)力節(jié)點(diǎn) 瀏覽3876次
ant-design-vue開源了一段時(shí)間后,收到了一些反饋,尤其是Form組件上線后,很多用戶對(duì)JSX的使用感到迷惑和不習(xí)慣,為此專門介紹下Vue JSX的使用姿勢(shì)及注意事項(xiàng)。
Form組件的自動(dòng)收集校驗(yàn)功能需要在JSX下使用,當(dāng)然如果不需要自動(dòng)收集校驗(yàn),你依然可以使用template
Vue推薦在絕大多數(shù)情況下使用template來創(chuàng)建你的HTML。然而在一些場(chǎng)景中,你真的需要 JavaScript 的完全編程的能力,就需要使用 render 函數(shù),它比 template 更接近編譯器。但是復(fù)雜的render函數(shù)書寫異常痛苦,好在官方提供了一個(gè) Babel 插件,可以將更接近于模板語法的JSX轉(zhuǎn)譯成JavaScript。
使用過React的同學(xué)對(duì)JSX肯定不陌生,但是Vue的JSX寫法和React的還是有一些區(qū)別。
React中父子之間傳遞的所有數(shù)據(jù)都是屬性,即所有數(shù)據(jù)均掛載在`props`下(style, className, children, value, onChange等等)。
Vue則不然,僅僅屬性就有三種:組件屬性props,普通html屬性attrs,Dom屬性domProps。
接下來我們通過一個(gè)示例來詳細(xì)解釋他們的區(qū)別:本文代碼可在codesandbox查看運(yùn)行
const ButtonCounter = {
name: "button-counter",
props: ["count"],
methods: {
onClick() {
this.$emit("change", this.count + 1);
}
},
render() {
return (
<button onClick={this.onClick}>You clicked me {this.count} times.</button>
);
}
};
export default {
name: "button-counter-container",
data() {
return {
count: 0
};
},
methods: {
onChange(val) {
this.count = val;
}
},
render() {
const { count, onChange } = this;
return (
<div>
<ButtonCounter
style={{ marginTop: "10px" }}
count={count}
type="button"
onChange={onChange}
/>
<ButtonCounter
style={{ marginTop: "10px" }}
count={count}
type="button"
domPropsInnerHTML={`hello ${this.count}.`}
onChange={onChange}
/>
</div>
);
}
};
組件屬性props:指組件聲明的屬性,即上述示例中聲明的props: ['count']。
普通html屬性attrs: 指組件未聲明的屬性,即上述示例中的type="button",該屬性默認(rèn)會(huì)直接掛載到組件根節(jié)點(diǎn)的上,如果不需要掛載到根節(jié)點(diǎn),可聲明 inheritAttrs: false。
Dom屬性domProps:指的Dom屬性,如上述示例中的innerHTML,它會(huì)覆蓋組件內(nèi)部的children, 這類屬性我們一般很少使用到。
同樣事件屬性也分了兩種:on nativeOn
答:正則則則...... ?,babel-plugin-transform-vue-jsx插件會(huì)通過正則匹配的方式在編譯階段將書寫在組件上屬性進(jìn)行“分類”。
onXXX的均被認(rèn)為是事件,nativeOnXXX是原生事件,domPropsXXX是Dom屬性,
class,staticClass,style,key,ref,refInFor,slot,scopedSlots這些被認(rèn)為是頂級(jí)屬性,至于我們屬性聲明的props,以及html屬性attrs,不需要加前綴,插件會(huì)將其統(tǒng)一分類到attrs屬性下,然后在運(yùn)行階段根據(jù)是否在props聲明來決定屬性歸屬(即屬于props還是attrs)。
第一、屬性分類是編譯階段進(jìn)行的分類,那么對(duì)于動(dòng)態(tài)屬性如何劃分分類?
在React中所有屬性都是頂級(jí)屬性,直接使用{...props}就可以了,但是在Vue中,你需要明確該屬性所屬的分類,如一個(gè)動(dòng)態(tài)屬性value和事件change,你可以使用如下方式(延展屬性)傳遞:
const dynamicProps = {
props: {},
on: {},
}
if(haValue) dynamicProps.props.value = value
if(hasChange) dynamicProps.on.change = onChange
<Dynamic {...dynamicProps} />
當(dāng)然你可以混合著使用:
<Dynamic {...dynamicProps} style="color: red"/>
先別高興太早,如果你沒有深入使用過Vue JSX,不建議你使用混合方式,因?yàn)閂ue會(huì)對(duì)其進(jìn)行屬性合并,至于合并的規(guī)則官方也并沒有詳細(xì)的文檔,文檔中有一處示例,我在這再舉一個(gè)例子:
const dynamicProps2 = { on: { change: onChange2 } };
<Dynamic
{...{ on: { change: onChange1 } }}
{...dynamicProps2}
onChange={onChange3}
/>
上例中的onChange1、onChange2、onChange3都會(huì)觸發(fā),而你想要的可能僅僅是onChange3。其它屬性的合并規(guī)則我就不一一列舉了,總之,我不建議你使用混合方式,除非你及你的團(tuán)隊(duì)其他小伙伴對(duì)其規(guī)則了解的足夠透徹。
注:理想情況你不應(yīng)該需要?jiǎng)討B(tài)屬性,在業(yè)務(wù)開發(fā)中也比較少的使用動(dòng)態(tài)屬性,但如果你嘗試開發(fā)一些通用性比較強(qiáng)的組件,就很難逃過動(dòng)態(tài)屬性的使用。
第二、如果聲明的屬性就是onXXX怎么處理?
首先我不建議你這么做,但如果真的需要,你必須明確該屬性的分類,如下所示:
<div>
<Dynamic value="獲取到value,然而并不能獲取到onXXX" onXXX="?" />
<Dynamic {...{ props: { onXXX: "獲取到onXXX,但不建議使用" } }} />
</div>
第三、函數(shù)式組件的props如何處理?
注意:在 2.3.0 之前的版本中,如果一個(gè)函數(shù)式組件想要接受 props,則 props 選項(xiàng)是必須的。在 2.3.0 或以上的版本中,你可以省略 props 選項(xiàng),所有組件上的屬性都會(huì)被自動(dòng)解析為 props。
props和attrs之間存在著很微妙的關(guān)系,在普通組件中,只要明確聲明的屬性會(huì)被劃分到props分類中,剩下的均在attrs中。而對(duì)于函數(shù)式組件,只要省略了props選項(xiàng),傳參時(shí)不管是否明確分類,最終context.props獲取到的都是全部屬性,如果你需要獲取明確的分類情況,可以在context.data下查看。
總之,在函數(shù)式組件中,推薦省略props選項(xiàng)。
第四、指令是否還可用?
很不幸的告訴你,大多數(shù)指令并不能在JSX中使用,對(duì)于原生指令,只有v-show是支持的。
大部分指令在JSX中可以使用表達(dá)式來替代,如:條件運(yùn)算符(?:)替代v-if、array.map替代v-for
對(duì)于自定義的指令,可以使用如下方式使用:
const directives = [
{ name: 'my-dir', value: 123, modifiers: { abc: true } }
]
return <div {...{ directives }}/>
以上就是動(dòng)力節(jié)點(diǎn)小編介紹的"在Vue中使用JSX的正確姿勢(shì)",希望對(duì)大家有幫助,想了解更多可查看編程入門教程。動(dòng)力節(jié)點(diǎn)在線學(xué)習(xí)教程,針對(duì)沒有任何Java基礎(chǔ)的讀者學(xué)習(xí),讓你從入門到精通,主要介紹了一些Java基礎(chǔ)的核心知識(shí),讓同學(xué)們更好更方便的學(xué)習(xí)和了解Java編程,感興趣的同學(xué)可以關(guān)注一下。
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問老師會(huì)電話與您溝通安排學(xué)習(xí)