Vue.js-渲染函数 & JSX
发布日期:2021-08-22 19:57:27 浏览次数:51 分类:技术文章

本文共 3291 字,大约阅读时间需要 10 分钟。

hot3.png

Vue推荐在绝大多数情况下使用template来创建你的Html,然而在一些场景中,你真的需要JavaScript的完全编程的能力,这就是、render函数,它比template更接近编译器

使用template例子

    
hello

在这种场景中使用template并不是最好的选择:首先代码冗长,为了在不同级别的标题中插入锚点元素,我们需要重复的使用<slot></slot>

虽然模板在大多数组件中都非常好用,但是在这里它就不是那么简洁了,那么我们来尝试使用render函数重写上面的例子

    
HELO

这样代码简单清晰多了,在这个例子中,你需要知道当你不使用slot属性向组件中传递内容时,如上面的"hello world",这些子元素被存储在组件实例的$slots.default

结点、树、以及虚拟DOM

    
Helloworld!

woqu

what

组件树中所有VNodes必须是唯一的,这意味着,下面的render function是无效的

render: function (createElement) {
  var myParagraphVNode = createElement('p', 'hi')
  return createElement('div', [
    // 错误-重复的VNodes
    myParagraphVNode, myParagraphVNode
  ])
}

如果你真的需要重复很多次的元素/组件,你可以使用工厂函数来实现。例如:下面这个例子render函数

完美的渲染了10个重复的段落  其中{length: 10}理解为Array like,即类数组对象(包含length属性)。

    

使用JavaScript代替模板功能,由于使用原生的JavaScript来实现某些东西很简单,Vue的render函数没有提供专用的API,比如,template中的v-if和v-for

    

也可以

    

render函数中没有与v-model相应的API,你必须自己来实现相应的逻辑

    
{
{data}}

你可以从this.$slots获取VNodes列表中的静态内容

    

hello slot

spantext
渲染成

hello slot

spantext

还可以从this.$scopedSlots中获得能用作函数的作用域插槽,这个函数返回VNodes:

    
渲染为
this is the textlily

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

    

渲染成

来自父组件
我是组件

函数化组件

之前创建的锚点标题组件比较简单,没有管理或者监听任何传递给他的信息,也没有生命周期方法,它只是一个接收参数的函数
在这个例子中,我们标记组件为functional,这意味它是无状态(没有data),无实例(没有this上下文),一个函数化组件就像这样
Vue.component('my-component', {
  functional: true,
  // 为了弥补缺少的实例
  // 提供第二个参数作为上下文
  render: function (createElement, context) {
    // ...
  },
  // Props 可选
  props: {
    // ...
  }
})

注意:在2.3.0之前的版本中,如果一个函数式组件想要接受props,则props选项是必须的。在2.3.0或者以上的版本中,你可以省略props选项,所有组件上的属性都会被自动解析为props

组件需要的一切都是通过上下文传递,包括:
props:提供props的对象
children:VNode子节点的数组
slot:slots对象
data:传递给组件的data对象
parent:对父组件的引用
listeners:(2.3.0+)一个包含了组件上所注册的v-on诊听器的对象。这只是一个指向data.on的别名
injections:(2.3.0+)如果使用了inject选项,则该对象包含了应该被注入的属性

在添加functional:true之后,锚点标题组件的render函数之间简单更新增加context参数,this.$slots.default更新为context.children,之后this.level更新为context.props.level

因为函数化组件只是一个函数,所以渲染开销也低很多。然而,对持久化实例的缺乏也意味着函数化组件不会出现在Vue devtools的组件树里,在作为包装组件时它们也同样非常有用,比如,当你需要做这些时
程序化地在多个组件中选择一个,再将children,props,data传递给子组件之前操作它们
下面是一个依赖传入props的值的smart-list组件例子,它能代表更多具体的组件

    
最后渲染成
  • test

 

slots()和children对比

你可能想知道为什么同时需要slots()和children。slots().default不是和children类似吗
在一些场景中,是这样,但是如果是函数式组件和下面这样的children呢
<my-functional-component>
  <p slot="foo">
    first
  </p>
  <p>second</p>
</my-functional-component>
对于这个组件,children会给你两个段落标签,而slots().default只会传递第二个匿名段落标签,slots().foo会传递第一个具名段落标签。同时拥有children和slots()
因此你可以选择让组件通过、slot()系统分发或者简单的通过children接收,让其它组件去处理

转载于:https://my.oschina.net/u/2612473/blog/1530028

转载地址:https://blog.csdn.net/weixin_33755554/article/details/92336349 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:linux下搭建svn仓库,window下访问
下一篇:“闪购”神话的牛皮吹出了泡沫

发表评论

最新留言

做的很好,不错不错
[***.243.131.199]2024年04月05日 17时53分51秒