资讯专栏INFORMATION COLUMN

Vue render深入窥探之谜

Amos / 2611人阅读

摘要:仅对于组件,用于监听原生事件,而不是组件内部使用触发的事件。注意,你无法对中的赋值,因为已经自动为你进行了同步。

简介

在使用Vue进行开发的时候,大多数情况下都是使用template进行开发,使用template简单、方便、快捷,可是有时候需要特殊的场景使用template就不是很适合。因此为了很好使用render函数,我决定深入窥探一下。各位看官如果觉得下面写的有不正确之处还望看官指出,你们与我的互动就是写作的最大动力。

场景

官网描述的场景当我们开始写一个通过 level prop 动态生成 heading 标签的组件,你可能很快想到这样实现:

Vue.component("anchored-heading", {
  template: "#anchored-heading-template",
  props: {
    level: {
      type: Number,
      required: true
    }
  }
})

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

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

Vue.component("anchored-heading", {
  render: function (createElement) {
    return createElement(
      "h" + this.level,   // tag name 标签名称
      this.$slots.default // 子组件中的阵列
    )
  },
  props: {
    level: {
      type: Number,
      required: true
    }
  }
})

简单清晰很多!简单来说,这样代码精简很多,但是需要非常熟悉 Vue 的实例属性。在这个例子中,你需要知道当你不使用 slot 属性向组件中传递内容时,比如 anchored-heading 中的 Hello world!,这些子元素被存储在组件实例中的 $slots.default中。

createElement参数介绍

接下来你需要熟悉的是如何在 createElement 函数中生成模板。这里是 createElement 接受的参数:

createElement(
  // {String | Object | Function}
  // 一个 HTML 标签字符串,组件选项对象,或者
  // 解析上述任何一种的一个 async 异步函数,必要参数。
  "div",

  // {Object}
  // 一个包含模板相关属性的数据对象
  // 这样,您可以在 template 中使用这些属性。可选参数。
  {
    // (详情见下一节)
  },

  // {String | Array}
  // 子节点 (VNodes),由 `createElement()` 构建而成,
  // 或使用字符串来生成“文本节点”。可选参数。
  [
    "先写一些文字",
    createElement("h1", "一则头条"),
    createElement(MyComponent, {
      props: {
        someProp: "foobar"
      }
    })
  ]
)
深入 data 对象

有一件事要注意:正如在模板语法中,v-bind:class 和 v-bind:style ,会被特别对待一样,在 VNode 数据对象中,下列属性名是级别最高的字段。该对象也允许你绑定普通的 HTML 特性,就像 DOM 属性一样,比如 innerHTML (这会取代 v-html 指令)。

{
  // 和`v-bind:class`一样的 API
  "class": {
    foo: true,
    bar: false
  },
  // 和`v-bind:style`一样的 API
  style: {
    color: "red",
    fontSize: "14px"
  },
  // 正常的 HTML 特性
  attrs: {
    id: "foo"
  },
  // 组件 props
  props: {
    myProp: "bar"
  },
  // DOM 属性
  domProps: {
    innerHTML: "baz"
  },
  // 事件监听器基于 `on`
  // 所以不再支持如 `v-on:keyup.enter` 修饰器
  // 需要手动匹配 keyCode。
  on: {
    click: this.clickHandler
  },
  // 仅对于组件,用于监听原生事件,而不是组件内部使用
  // `vm.$emit` 触发的事件。
  nativeOn: {
    click: this.nativeClickHandler
  },
  // 自定义指令。注意,你无法对 `binding` 中的 `oldValue`
  // 赋值,因为 Vue 已经自动为你进行了同步。
  directives: [
    {
      name: "my-custom-directive",
      value: "2",
      expression: "1 + 1",
      arg: "foo",
      modifiers: {
        bar: true
      }
    }
  ],
  // Scoped slots in the form of
  // { name: props => VNode | Array }
  scopedSlots: {
    default: props => createElement("span", props.text)
  },
  // 如果组件是其他组件的子组件,需为插槽指定名称
  slot: "name-of-slot",
  // 其他特殊顶层属性
  key: "myKey",
  ref: "myRef"
}
条件渲染

既然熟读以上api接下来咱们就来点实战。
之前这样写

//HTML
我被你发现啦!!!
//js //组件形式 Vue.component("vv-isshow", { props:["show"], template:"
我被你发现啦2!!!
", }); var vm = new Vue({ el: "#app", data: { isShow:true } });

render这样写

//HTML
我被你发现啦3!!!
//js //组件形式 Vue.component("vv-isshow", { props:{ show:{ type: Boolean, default: true } }, render:function(h){ if(this.show ) return h("div",this.$slots.default); }, }); var vm = new Vue({ el: "#app", data: { isShow:true } });
列表渲染

之前是这样写的,而且v-for 时template内必须被一个标签包裹

//HTML
//js //组件形式 Vue.component("vv-aside", { props:["list"], methods:{ handelClick(item){ console.log(item); } }, template:"
{{item.txt}}
", //template:"
{{item.txt}}
",错误 }); var vm = new Vue({ el: "#app", data: { list: [{ id: 1, txt: "javaScript", odd: true }, { id: 2, txt: "Vue", odd: false }, { id: 3, txt: "React", odd: true }] } });

render这样写

//HTML
//js //侧边栏 Vue.component("vv-aside", { render: function(h) { var _this = this, ayy = this.list.map((v) => { return h("div", { "class": { odd: v.odd }, attrs: { title: v.txt }, on: { click: function() { return _this.handelClick(v); } } }, v.txt); }); return h("div", ayy); }, props: { list: { type: Array, default: () => { return this.list || []; } } }, methods: { handelClick: function(item) { console.log(item, "item"); } } }); var vm = new Vue({ el: "#app", data: { list: [{ id: 1, txt: "javaScript", odd: true }, { id: 2, txt: "Vue", odd: false }, { id: 3, txt: "React", odd: true }] } });
v-model

之前的写法

//HTML
//js //input Vue.component("vv-models", { props: ["txt"], template: "

看官你输入的是:{{txtcout}}

", computed: { txtcout:{ get(){ return this.txt; }, set(val){ this.$emit("input", val); } } } }); var vm = new Vue({ el: "#app", data: { txt: "", } });

render这样写

//HTML
//js //input Vue.component("vv-models", { props: { txt: { type: String, default: "" } }, render: function(h) { var self=this; return h("div",[h("p","你猜我输入的是啥:"+this.txt),h("input",{ on:{ input(event){ self.$emit("input", event.target.value); } } })] ); }, }); var vm = new Vue({ el: "#app", data: { txt: "", } });
总结

render函数使用的是JavaScript 的完全编程的能力,在性能上是占用绝对的优势,小编只是对它进行剖析。至于实际项目你选择那种方式进行渲染依旧需要根据你的项目以及实际情况而定。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/94195.html

相关文章

  • 2017-08-02 前端日报

    摘要:前端日报精选浮点数精度之谜前端面试必备基本排序算法从贺老微博引出的遍历器加速那些奥秘进阶之深入理解数据双向绑定全栈天中文深入理解笔记用模块封装代码前端架构经验分享周二放送自制知乎专栏译在大型应用中使用的五个技巧掘金开发指南众成 2017-08-02 前端日报 精选 JavaScript 浮点数精度之谜前端面试必备——基本排序算法从贺老微博引出的遍历器(Iterators)加速那些奥秘J...

    Worktile 评论0 收藏0
  • 窥探react事件

    摘要:解决问题为了解决上述问题,先来了解下的事件,事件是合成事件,为原生事件的一个子集,仅仅是进行了一个跨浏览器的封装。参考本文部分参考自事件初探 写在前面 本文源于本人在学习react过程中遇到的一个问题;本文内容为本人的一些的理解,如有不对的地方,还请大家指出来。本文是讲react的事件,不是介绍其api,而是猜想一下react合成事件的实现方式 遇到的问题 class EventTes...

    刘厚水 评论0 收藏0
  • 窥探React - 源码分析

    摘要:所谓知其然还要知其所以然本文将分析的部分源码包括组件初始渲染的过程和组件更新的过程在这之前假设读者已经对有一定了解知道区别了解生命周期事务批量更新大致概念等如何分析源码代码架构预览首先我们找到在上的地址把版本的源码下来观察它的整体架构这 所谓知其然还要知其所以然. 本文将分析 React 15-stable的部分源码, 包括组件初始渲染的过程和组件更新的过程.在这之前, 假设读者已经:...

    instein 评论0 收藏0
  • 深入理解js

    摘要:详解十大常用设计模式力荐深度好文深入理解大设计模式收集各种疑难杂症的问题集锦关于,工作和学习过程中遇到过许多问题,也解答过许多别人的问题。介绍了的内存管理。 延迟加载 (Lazyload) 三种实现方式 延迟加载也称为惰性加载,即在长网页中延迟加载图像。用户滚动到它们之前,视口外的图像不会加载。本文详细介绍了三种延迟加载的实现方式。 详解 Javascript十大常用设计模式 力荐~ ...

    caikeal 评论0 收藏0
  • 深入Vue.js从源码开始(三)

    摘要:数据驱动一个核心思想是数据驱动。发生了什么从入口代码开始分析,我们先来分析背后发生了哪些事情。函数最后判断为根节点的时候设置为,表示这个实例已经挂载了,同时执行钩子函数。这里注意表示实例的父虚拟,所以它为则表示当前是根的实例。 数据驱动 Vue.js 一个核心思想是数据驱动。所谓数据驱动,是指视图是由数据驱动生成的,我们对视图的修改,不会直接操作 DOM,而是通过修改数据。它相比我们传...

    lentrue 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<