聊聊Vue怎么通過JSX動態(tài)渲染組件_第1頁
聊聊Vue怎么通過JSX動態(tài)渲染組件_第2頁
聊聊Vue怎么通過JSX動態(tài)渲染組件_第3頁
聊聊Vue怎么通過JSX動態(tài)渲染組件_第4頁
聊聊Vue怎么通過JSX動態(tài)渲染組件_第5頁
已閱讀5頁,還剩11頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第聊聊Vue怎么通過JSX動態(tài)渲染組件想通過循環(huán)arr,拿到tag渲染對應的組件。

下面我們分析如何寫才是最優(yōu)。

二、進行分析

2.1v-if走天下

我們可以寫一個v-for去循環(huán)arr數(shù)組,然后通過v-if去判斷tag,渲染對應的組件類型。

這樣子寫不是不可以,只不過擴展性不好,每次加一個標簽,模板就要再加一個v-if。

我相信很多人起初都是這樣寫。

但這不是我們優(yōu)雅人該寫的代碼。

2.2動態(tài)渲染組件標簽

我們能不能根據tag的標簽來渲染出真正的標簽。

關鍵是循環(huán)內,怎么根據遍歷的tag去渲染出真正的組件。

van-cellv-for=(cell,cellKey)inarr:key=cellKey

!--動態(tài)渲染--

/van-cell

有請今天的主角JSX上場。

2.3JSX動態(tài)渲染組件

父組件

van-cellv-for=(cell,cellKey)inarr:key=cellKey

!--用jsx動態(tài)渲染--

RendTag:cell=cell/

/van-cell

constarr=[

{tag:van-field},//輸入框

{tag:van-cell},//彈出層

{tag:van-stepper}//步進器

]

子組件RendTag.vue

script

constAssemblyRend={

name:assembly-rend,

props:[cell],

data(){

return{

input:,

methods:{

onClick(){

this.$emit(changeTag,this.input);

computed:{

itemVal:{

get(){

returnthis.cell.value

set(v){

this.cell.value=v

render(){

const{cell}=this;//解構

constassembly=cell.tag;//這里就是我們動態(tài)渲染組件的核心

return(

assembly

v-model={this.itemVal}

placeholder={cell.placeholder}

min={cell.min}

this.onClick}

/assembly

exportdefault{

name:RendTag,

props:{

cell:{

type:Object,

default:()={

return{

title:能否輸入,

placeholder:請輸入姓名,

value:name,

tag:van-Switch,

methods:{

changeTag(val){},

render(){

const{cell}=this;//解構

return(

div>

我們利用JSX的render可以寫JavaScript返回組件,來實現(xiàn)我們動態(tài)渲染標簽。

render相當于我們vue中的模板。

于是渲染出的效果如下:根據tag渲染成真正的組件

我們用普通的組件,無法像JSX一樣渲染成我們想要的組件。

這里的v-model用計算屬性的坑,我推薦看一遍:實戰(zhàn)v-model如何綁定多循環(huán)表達式(內含原理)

其實這兩篇是有一定的掛鉤的,只不過我在這里拆開了需求。

主要也是方便朋友們閱讀理解。

三、vue中如何使用JSX

借著該需求,我們惡補一下JSX。

3.1是什么?

JSX是一種Javascript的語法擴展,JSX=Javascript+XML,即在Javascript里面寫XML,因為JSX的這個特性,所以他即具備了Javascript的靈活性,同時又兼具html的語義化和直觀性。

活度強的部分組件可以用JSX來代替(比如以上需求);

整個工程沒有必要都使用JSX。

3.2基本用法

3.2.1函數(shù)式組件

我們在組件中,也可以嵌入ButtonCounter組件。

constButtonCounter={

name:button-counter,

props:[count],

methods:{

onClick(){

this.$emit(changeNum,this.count+1);

render(){

returnbuttonthis.onClick}數(shù)量:{this.count}/button

exportdefault{

name:HelloWorld,

props:{

msg:String

data(){

return{

count:0

methods:{

//改變button按鈕數(shù)量

changeNum(val){

this.count=val;

render(){

const{count}=this;//解構

return(

div>

3.2.2普通屬性、行內樣式、動態(tài)class與style

可以看到,其實和vue的模板寫法基本一致,只不過要注意的是花括號;

在vue的模板是要寫兩對花括號,而在JSX只需要寫一對。

exportdefault{

name:HelloWorld,

props:{

msg:String

data(){

return{

count:0,

text:HelloWorld!,

msgClass:msg-class,

isGreen:true

render(){

const{count,text}=this;//解構

return(

div>

3.2.3常用指令

v-html、v-if、v-for、v-model常用指令在JSX中無法使用,需要使用其他方式來實現(xiàn)。

v-html

在JSX中,如果要設置DOM的innerHTML,需要用到domProps。

組件使用:

HelloWorld

msg=div>

組件代碼:

exportdefault{

name:HelloWorld,

props:{

msg:String

data(){

return{};

methods:{},

render(){

returndivdomPropsInnerHTML={this.msg}/div

};

渲染DOM結果:

v-for

使用map來實現(xiàn):

render(){

constlist=[1,2,3]

return(

div

{list.map(item=button按鈕{item}/button)}

/div

}

v-if

簡單示例:用三元

render(){

constbool=false;

returndiv{boolbutton按鈕1/button:button按鈕2/button}/div

}

復雜示例:直接用JS

render(){

letnum=3

if(num===1){return(button按鈕1/button)}

if(num===2){return(button按鈕2/button)}

if(num===3){return(button按鈕3/button)}

}

v-model

直接使用:inputv-model={this.value}

exportdefault{

name:HelloWorld,

props:{

msg:String

data(){

return{

value:abc

watch:{

value(val){

console.log(this.model內容:+val);

methods:{},

render(){

return(

div

inputv-model={this.value}placeholder=普通文本/

/div

};

3.2.4監(jiān)聽事件、事件修飾符

監(jiān)聽事件

監(jiān)聽事件想到用onChange,onClick等。

需要注意的是,傳參數(shù)不能使用this.handleClick(params)},這樣子會每次render的時候都會自動執(zhí)行一次方法。

應該使用bind,或者箭頭函數(shù)來傳參。

組件示例代碼:

exportdefault{

name:HelloWorld,

props:{

msg:String

data(){

return{};

methods:{

handleClick(val){

alert(val);

render(){

return(

div

buttontype=buttonthis.handleClick.bind(this,11)}

/button

buttontype=button()=this.handleClick(22)}

/button

/div

};

用監(jiān)聽事件來實現(xiàn)v-model:

methods:{

input(e){

this.value=e.target.value;

render(){

return(

div

inputtype=textvalue={this.value}onInput={this.input}/

/div

}

也可以調整為:

input

type=text

value={this.value}

onInput={(e)=(this.vaue=e.target.value)}

/

還可以使用對象的方式去監(jiān)聽事件:解構事件

exportdefault{

name:HelloWorld,

props:{

msg:String

data(){

return{

value:

watch:{

value(val){

console.log(this.model的內容:+val);

methods:{

handleInput(e){

this.value=e.target.value;

handleFocus(e){

console.log(e.target);

render(){

return(

div

inputtype=textvalue={this.value}{...{on:{input:this.handleInput,focus:this.handleFocus}}}/

/div

};

nativeOn僅對于組件,用于監(jiān)聽原生事件,也可以使用對象的方式去監(jiān)聽事件:

{...{nativeOn:{click:this.handleClick}}}

事件修飾符

和指令一樣,除了個別的之外,大部分的事件修飾符都無法在JSX中使用。

.stop:阻止事件冒泡,在JSX中使用event.stopPropagation()來代替

.prevent:阻止默認行為,在JSX中使用event.preventDefault()來代替

.self:只當事件是從偵聽器綁定的元素本身觸發(fā)時才觸發(fā)回調,使用下面的條件判斷進行代替

if(event.target!==event.currentTarget){

return

}

.enter與keyCode:在特定鍵觸發(fā)時才觸發(fā)回調

if(event.keyCode===13){

//執(zhí)行邏輯

}

除了上面這些修飾符之外,尤大大對于.once,.capture,.passive,.capture.once做了優(yōu)化,簡化代碼:

exportdefault{

name:HelloWorld,

props:{

msg:String

methods:{

handleClick(e){

console.log(click事件:+e.target);

handleInput(e){

console.log(input事件:+e.target);

handleMouseDown(e){

console.log(mousedown事件:+e.target);

handleMouseUp(e){

console.log(mouseup事件+e.target);

render(){

return(

{...{

on:{

//相當于:click.capture

!click:this.handleClick,

//相當于:input.once

~input:this.handleInput,

//相當于:mousedown.passive

mousedown:this.handleMouseDown,

//相當于:mouseup.capture.once

~!mouseup:this.handleMouseUp

點擊模塊

/div

};

3.3插槽

3.3.1普通插槽與具名插槽

父傳子。

示例:

HelloWorld

templateslot=default默認內容/template

templateslot=footer

el-buttontype=primary確定/el-button

el-button取消/el-button

/template

/HelloWorld

HelloWorld組件代碼:this.$slots

exportdefault{

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論