在 render 函数中,Vue 实例属性:$attrs、$props、$listeners 和 $scopedSlots的使用

一、$attrs、$props、$listeners 

$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 中使用

由于 render 函数中没有 v-bind、v-on 等内置指令,因此我们将如何使用呢?

render () {
  const props = {
    ...this.$attrs,
    ...this.$props,
  }
  const on = {
    this.$listeners,
  }
  return (
    <a-table
      {...{ props, scopedSlots: { ...this.$scopedSlots } }}
      {...{ on }}
    >
      Object.keys(this.slots).map(name => (<template slot={name}>{this.$slots[name]}</template>))
    </a-table>
  )
}

这里使用了展开运算符,更多详情,请查看:vue 中,如何使用 JSX 语法

三、$scopedSlots

用来访问作用域插槽。对于包括 默认 slot 在内的每一个插槽,该对象都包含一个返回相应 VNode 的函数。vm.$scopedSlots 在使用渲染函数开发一个组件时特别有用。

render () {
  return (
    <a-table
      onChange={this.loadData}
      {...{ scopedSlots: ...this.$scopedSlots }}
    />
  )
}

注意:从 2.6.0 开始,这个 property 有两个变化:

1.作用域插槽函数现在保证返回一个 VNode 数组,除非在返回值无效的情况下返回 undefined。

2.所有的 $slots 现在都会作为函数暴露在 $scopedSlots 中。如果你在使用渲染函数,不论当前插槽是否带有作用域,我们都推荐始终通过 $scopedSlots 访问它们。这不仅仅使得在未来添加作用域变得简单,也可以让你最终轻松迁移到所用插槽都是函数的 Vue3。

listName: [
  { label: '运单号', value: 'taskNo' },
  { label: '状态',
    value: 'status',
    scopedSlots: {
      default: (scope) => {
        return (
          <span>{util.getFormatValue(scope.row.status, putGoodsData.status) || '-'}</span>
        )
      },
    }
  },
],

render (h) {
  return <el-table
    data={this.tableData}
    border>
    {this.listName.map(item => {
      return <el-table-column
        key={item.value}
        prop={item.value}
        label={item.label}
        scopedSlots={item.scopedSlots}
      >
      </el-table-column>
    }
    )}
    <el-table-column
      fixed="right"
      label="操作"
      scopedSlots={this.handleOperation().scopedSlots}>
    </el-table-column>
  </el-table>
}

handleOperation () {
  return {
    scopedSlots: {
      default: (scope) => {
        return (
          <div>
            { scope.row.status === 0 && <el-button type="text" size="small" onClick={_ => this.handleDelete(scope.row)}>删除</el-button>}
          </div>
        )
      },
    },
  }
},

补充: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) {
  // `<div><slot></slot></div>`
  return createElement('div', this.$slots.default)
}
// $scopedSlots
props: ['message'],
render: function (createElement) {
  // `<div><slot :text="message"></slot></div>`
  return createElement('div', [
    this.$scopedSlots.default({
      text: this.message
    })
  ])
}

如果要用渲染函数向子组件中传递作用域插槽,可以利用 VNode 数据对象中的 scopedSlots 字段:

render: function (createElement) {
  // `<div><child v-slot="props"><span>{{ props.text }}</span></child></div>`
  return createElement('div', [
    createElement('child', {
      // 在数据对象中传递 `scopedSlots`
      // 格式为 { name: props => VNode | Array<VNode> }
      scopedSlots: {
        default: function (props) {
          return createElement('span', props.text)
        }
      }
    })
  ])
}

 

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue ,当你使用某些组件时,组件可能会使用 `$attrs` 属性来传递一些额外的属性到组件内部。 在 `$attrs` ,存储了组件外部传入的、但是组件内部没有声明的所有属性。这些属性可以通过 `$attrs` 访问并使用。 在 `$attrs` ,还有一个特殊的属性 `$listeners`,用于存储组件外部传入的、但是组件内部没有声明的事件监听器。这些事件监听器可以通过 `$listeners` 访问并使用。 当你在使用 `el-table` 组件时,`$attrs` 属性可以用于传递一些额外的表格属性到组件内部。例如,你可以通过 `$attrs` 给表格添加 `border`、`size`、`stripe` 等属性,如下所示: ```html <el-table :data="tableData" :attrs="{ border: true, size: 'medium', stripe: true }" > <!-- 表格列定义 --> </el-table> ``` 在上面的代码,我们通过 `:attrs` 给表格添加了 `border`、`size`、`stripe` 等属性。这些属性会被传递到 `el-table` 组件内部,并应用到表格上。在 `el-table` 组件内部,你可以通过 `$attrs` 访问这些属性,如下所示: ```js export default { name: 'MyTable', props: { // ... }, render(h) { return h( 'el-table', { attrs: this.$attrs, // 将外部传入的属性应用到表格上 on: this.$listeners // 将外部传入的事件监听器绑定到表格上 }, this.$slots.default // 表格列定义 ) } } ``` 在上面的代码,我们将 `$attrs` 属性应用到了 `el-table` 组件上。这样,所有在外部传入的、但是组件内部没有声明的属性都会被应用到表格上。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值