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
传递一个带参的方法给子组件。