$attrs:当前组件的属性,通俗的讲也就是在组件标签定义的一系列属性,如input的value,placeholder等,但是不包括在当前组件里面定义的props属性
$listeners:当前组件监听的事件,通俗的讲也就是在使用组件的时候在标签中定义的事件,如@input,以及一些自定义事件@tempFn等
$props:当前组件从父组件那里接收的参数,通俗的讲和$attr差不多,但是只包括在当前组件中定义了的props属性。Vue 实例代理了对其 props 对象 property 的访问。
$data:Vue 实例观察的数据对象。Vue 实例代理了对其 data 对象 property 的访问。
$scopedSlots:用来访问作用域插槽。对于包括 默认 slot
在内的每一个插槽,该对象都包含一个返回相应 VNode 的函数。
通俗的讲:$attr + $props = 在使用组件时定义得所有属性,不包含事件。
那么在当前组件中使用v-bind="$attrs",v-bind="$props",v-on="$listeners"也就是把之前父组件那里给它的属性再全部传到它的子组件。
由于 render 函数中没有 v-bind、v-on 等内置指令,因此我们将如何使用呢?
render () {
const props = {
...this.$attrs,
...this.$props,
}
const on = {
this.$listeners,
}
return (
Object.keys(this.slots).map(name => ({this.$slots[name]}))
)
}
这里使用了展开运算符,更多详情,请查看:vue 中,如何使用 JSX 语法。
用来访问作用域插槽。对于包括 默认 slot
在内的每一个插槽,该对象都包含一个返回相应 VNode 的函数。vm.$scopedSlots
在使用渲染函数开发一个组件时特别有用。
render () {
return (
)
}
注意:从 2.6.0 开始,这个 property 有两个变化:
1.作用域插槽函数现在保证返回一个 VNode 数组,除非在返回值无效的情况下返回 undefined。
2.所有的 $slots 现在都会作为函数暴露在 $scopedSlots 中。如果你在使用渲染函数,不论当前插槽是否带有作用域,我们都推荐始终通过 $scopedSlots 访问它们。这不仅仅使得在未来添加作用域变得简单,也可以让你最终轻松迁移到所用插槽都是函数的 Vue3。
listName: [
{ label: '运单号', value: 'taskNo' },
{ label: '状态',
value: 'status',
scopedSlots: {
default: (scope) => {
return (
{util.getFormatValue(scope.row.status, putGoodsData.status) || '-'}
)
},
}
},
],
render (h) {
return
{this.listName.map(item => {
return
}
)}
}
handleOperation () {
return {
scopedSlots: {
default: (scope) => {
return (
{ scope.row.status === 0 && this.handleDelete(scope.row)}>删除 }
)
},
},
}
},
补充:this.$slots
用来访问被插槽分发的内容。每个具名插槽有其相应的 property (例如:v-slot:foo
中的内容将会在 vm.$slots.foo
中被找到)。default
property 包括了所有没有被包含在具名插槽中的节点,或 v-slot:default
的内容。
请注意插槽不是响应性的。如果你需要一个组件可以在被传入的数据发生变化时重渲染,我们建议改变策略,依赖诸如 props
或 data
等响应性实例选项。
注意:v-slot:foo
在 2.6 以上的版本才支持。对于之前的版本,你可以使用废弃了的语法。
在使用渲染函数书写一个组件时,访问 vm.$slots
最有帮助。更多详情,请查看 vue 官网之 vm.$slots。
除了通过 this.$slots 访问静态插槽的内容,每个插槽都是一个 VNode 数组,也可以通过 this.$scopedSlots 访问作用域插槽,每个作用域插槽都是一个返回若干 VNode 的函数:
// $slots
render: function (createElement) {
// ` `
return createElement('div', this.$slots.default)
}
// $scopedSlots
props: ['message'],
render: function (createElement) {
// ` `
return createElement('div', [
this.$scopedSlots.default({
text: this.message
})
])
}
如果要用渲染函数向子组件中传递作用域插槽,可以利用 VNode 数据对象中的 scopedSlots 字段:
render: function (createElement) {
// `{{ props.text }} `
return createElement('div', [
createElement('child', {
// 在数据对象中传递 `scopedSlots`
// 格式为 { name: props => VNode | Array }
scopedSlots: {
default: function (props) {
return createElement('span', props.text)
}
}
})
])
}