iview Table 單元格數據是一個下拉選擇框vue
起初直接 render 了一個通過二次封裝的 iview Dropdown 組件,在接入後臺數據後發現-等待請求返回數據形成必定時間延緩而不能正常 render 這個組件,因此又考慮採用 template 的寫法,結果就出現參數 undefined 的問題:bash
(最後發現直接在 Table 上綁定 vif ,等數據請求完後再渲染整個 Table 也行)iview
render jsx 寫法:ide
template 寫法:測試
進行 template 寫法測試過程當中發現,父組件方法 handleChangeCharac
不能正常獲取到下拉列表的 name
值,但在子組件 handleCommand
中是能獲取到的,就產生疑問:爲何 render 中沒有出現這個 undefined
問題呢?ui
因而回到封裝組件 xz-dropdown
裏面看邏輯,簡單點說 Dropdown
提供了一個 @on-click
方法返回當前點擊下拉列表的 name 值,我用 handleDropDown
接受這個 name
並傳給了一個類型爲 Function
的 prop : handleCommand
this
// xz-dropdown.vue
spa
再次理清了一下流程, xz-dropdown
中觸發 handleDropDown
方法並傳 name
給 handleCommand
,並同時調用 父組件的 handleChangeCharac
方法 , 這時 handleCommand
才能接收 name
, 以上調用封裝組件的寫法是有問題的,父組件中應改寫成3d
父組件調用:code
<template slot-scope="{ row }" slot="roleName">
<xz-dropdown
:title="row.roles[0].roleName"
class="charac-type-btn"
:transferDom="true"
:handleCommad="handleChangeCharac" // 更改
:commands="characCommands"
></xz-dropdown>
</template>
複製代碼
結果:
此時父組件中是能接收到 name
, 可是我還必須獲取到 當前的行數據row
, 若是直接在上面基礎上寫 :handleCommand="handleChangeCharac(row)"
這時是會覆蓋 name
結構仍是隻能操做一個對象而不是兩個。
進而應該審視一下 xz-dropdown
中的邏輯代碼,看是否可以改善以上的問題,父子組件通訊中經常使用的方式除了 prop
外,還有$emit
,因而開始邏輯修改:(採用$emit)
xz-dropdown.vue:
// template
<Dropdown
trigger="click"
@on-click="handleOnClick" // 更改
:transfer="transferDom"
@on-clickoutside="handleClickOutside"
>
// js
methods: {
}
複製代碼
父組件:
<template slot-scope="{ row }" slot="roleName">
<xz-dropdown
:title="row.roles[0].roleName"
class="charac-type-btn"
:transferDom="true"
@handle-on-click="handleChangeCharac($event, row)" // 更改
:commands="characCommands"
></xz-dropdown>
</template>
複製代碼
點擊目標後(順序是先觸發xz-dropdown 中的 handleOnClick
接着觸發父組件的 handleChangcharac
name
和
row
致使出現問題的緣由:子組件中經過自定義方法傳一個參給類型爲function
的prop
,此處纔是調用該方法的地方,若是須要增長參數個數,也應該在此處增長。這種狀況下父組件觸發是可以獲取到該參數(這種方式有點相似於子組件$emit
出一個參數給父組件),卻混淆了$emit
和prop
的使用結果,
若是要堅持用prop
的方式並達到需求,就須要更改邏輯爲:
xz-dropdown.vue:
// template
<Dropdown
trigger="click"
@on-click="handleDropDown($event, item)"
:transfer="transferDom"
@on-clickoutside="handleClickOutside"
>
// js
props: {
item: { // 添加
type: Object
},
handleCommand: {
type: Function
}
},
methods: {
handleDropDown(name, item) { // 添加
this.handleCommand(name, item)
}
}
複製代碼
父組件:
<template slot-scope="{ row }" slot="roleName">
<xz-dropdown
:title="row.roles[0].roleName"
class="charac-type-btn"
:transferDom="true"
:item="row" // 添加
:handleCommad="handleChangeCharac($event, row)"
:commands="characCommands"
></xz-dropdown>
</template>
複製代碼
爲何 render的寫法可以避免出現這種問題呢? 其實就是這裏起了做用
handleCommand
的一個方法裏面得到了
name
, 再將
name
傳給了
handleChangeCharac
的同時,
handleChangeCharac
也得到了第二個參數
row
, 這偏偏是
render
寫法的好處
它等價於:
handkeCommand={this.funtionA}
functionA(name) {
this.handleChangeCharac(name)
}
複製代碼
而普通的template
寫法是不能同時得到上文的row
使用vue
過程當中常常出現父子組件數據傳遞的現象,而prop
和$emit
又是實現這種需求較爲經常使用的方法,這次使用prop
達到了必定的$emit
效果,但也出現了弊端,混淆了對prop
和$emit
的理解,是不能經過prop
傳遞一個帶參的方法給子組件。