浅析Vue 中的 render 函数

render函数是什么

  简单的说,在vue中我们使用模板HTML语法组建页面的,使用render函数我们可以用js语言来构建DOM

  因为vue是虚拟DOM,所以在拿到template模板时也要转译成VNode的函数,而用render函数构建DOM,vue就免去了转译的过程。

  当使用render函数描述虚拟DOM时,vue提供一个函数,这个函数是就构建虚拟DOM所需要的工具。官网上给他起了个名字叫createElement。还有约定的简写叫h,

  vm中有一个方法_c,也是这个函数的别名

  先看官网对 createElement的介绍

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

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

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

就是说createElement(params1,params2,params3)接受三个参数,每个参数的类型官方介绍已经说明

好了,开始今天的正文。

本文 GitHub https://github.com/qq44924588... 上已经收录,更多往期高赞文章的分类,也整理了很多我的文档,和教程资料。欢迎Star和完善,大家面试可以参照考点复习,希望我们一起有点东西。

我们知道 Vue 模板是非常强大的,基本可以完成我们日常开发的所有任务。但是,有一些用例,如基于输入或插槽值创建动态组件方式, render 函数会比模板完成的更好也更出色。

用过 React 开发的人对 render 函数应该非常熟悉,因为React组件通过 JSX和 render 函数来构建的。 尽管Vue render 函数也可以用JSX编写,但在这里我们使用原生 JS方式,因为这样,我们可以更轻松地了解Vue组件系统的一些基础。

值得注意的是,Vue 的模板实际上在编译时也是会先解析成 render 函数表示方式。 模板只是在 render 函数之上提供了一个方便且熟悉的语法糖。 尽管 render 函数更强大,但 render 函数可读性很差,相对用的也比较少了。

创建组件

带有 render 函数的组件没有 template 标记或属性。 相反,该组件定义了一个了名为 render 的函数,该函数接收一个 reateElement(renderElement: String | Component, definition: Object, children: String | Array) 参数(由于某种原因,通常别名为 h ,归咎于JSX)并返回使用该函数创建的元素,其他一切保持不变,来看看事例:

export default {
 data() {
  return {
   isRed: true
  }
 },

 /*
  * <template>
  *  <div :class="{'is-red': isRed}">
  *   <p>这是一个 render 事例</p>
  *  </div>
  * </template>
  */
 // render 中的渲染结果与上面等价
 render(h) {
  return h('div', {
   'class': {
    'is-red': this.isRed
   }
  }, [
   h('p', '这是一个 render 事例')
  ])
 }
}

render 函数中如何表示指令

Vue 模板具有各种便捷功能,以便向模板添加基本逻辑和绑定功能,如 v-if 、 v-for 、 v-moel 指令等。 在 render 函数中是无法使用这些指令的。 取而代之的是以纯 JS 来实现,对于大多数指令而言,这也是比较简单的。

v-if

v-if 用纯 JS 实现很简单,只需围绕 createElement 调用使用 if(expr) 语句即可。

v-for

v-for 可以使用 for-of , Array.map , Array.filter 等的JS方法中的任何一种来实现。我们可以通过非常有趣的方式将它们组合在一起,以实现过滤或状态切片,而无需计算属性。

例如,有以下 Vue 的模板代码

<template>
 <ul>
  <li v-for="pea of pod">

  </li>
 </ul>
</template>

可以用下面的 render 函数来实现上面的效果:

render(h) {
 return h('ul', this.pod.map(pea => h('li', pea.name)));
}

v-model

我们知道, v-model 只是 bind 属性与 value 的语法糖,并在触发 input 事件时设置数据属性。但是,在 render 函数没有这样的简写,我们需要自己实现。

假设,在 Vue 中,我们有如下的结构:

<template>
 <input v-model='myBoundProperty'/>
</template>

上面代码等价于:

<template>
 <input :value="myBoundProperty" @input="myBoundProperty = $event.target.value"/>
</template>

在 render 函数中可以用下面方式来实现上面的代码:

render(h) {
 return h('input', {
  domProps: {
   value: this.myBoundProperty
  },
  on: {
   input: e => {
    this.myBoundProperty = e.target.value
   }
  }
 })
}

v-bind

attribute 和 property 这两种类型的绑定被放在元素定义中,如 arttrs 、 props 和 domProps ( value 和 innerHTML 之类的东西)。

render(h) {
 return h('div', {
  attrs: {
   // <div :id="myCustomId">
   id: this.myCustomId
  },

  props: {
   // <div :someProp="someonePutSomethingHere">
   someProp: this.someonePutSomethingHere
  },

  domProps: {
    // <div :value="somethingElse">
   value: this.somethingElse
  }
 });
}

需要注意的是,对于 class 和 style 的绑定是直接在定义的根进行处理,而不是作为 attrs , props 或 domProps 处理。

render(h) {
 return h('div', {
  // “类”是JS中的保留关键字,因此必须引用它。
  'class': {
   myClass: true,
   theirClass: false
  },

  style: {
   backgroundColor: 'green'
  }
 });
}

v-on

对事件处理程也是直接添加到元素定义中 on 定义

render(h) {
 return h('div', {
  on: {
   click(e) {
    console.log('I got clickeded!')
   }
  }
 });
}

事件的修饰符可以在处理程序内部实现:

.stop -> e.stopPropagation()
.prevent -> e.preventDefault()
.self -> if (e.target !== e.currentTarget) return

键盘修饰符

.[TARGET_KEY_CODE] -> if (event.keyCode !== TARGET_KEY_CODE) return
.[MODIFIER] -> if (!event.MODIFIERKey) return

特殊属性

Slots 可以通过 this.$slots 作为 createElement() 节点的数组来访问插槽。

作用域插槽存储在 this.$scopedSlots[scope](props:object) 中,作为返回 createElement() 节点数组的函数。

代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug

总结

到此这篇关于浅析Vue 中的 render 函数的文章就介绍到这了,更多相关Vue render 函数内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Vue2.x中的Render函数详解

    Render函数是Vue2.x版本新增的一个函数:使用虚拟dom来渲染节点提升性能,因为它是基于JavaScript计算.通过使用createElement(h)来创建dom节点.createElement是render的核心方法.其Vue编译的时候会把template里面的节点解析成虚拟dom: 什么是虚拟dom? 虚拟dom不同于真正的dom,它是一个JavaScript对象.当状态发生变化的时候虚拟dom会进行一个diff判断/运算:然后判断哪些dom是需要被替换的而不是全部重绘,所以性能

  • vue中render函数的使用详解

    render函数 vue通过 template 来创建你的 HTML.但是,在特殊情况下,这种写死的模式无法满足需求,必须需要js的编程能力.此时,需要用render来创建HTML. render方法的实质就是生成template模板: 通过调用一个方法来生成,而这个方法是通过render方法的参数传递给他的: 通过这三个参数,可以生成一个完整的模板 官网实例 //未使用render函数 Vue.component('anchored-heading', { template: '#anchor

  • Vue中render函数的使用方法

    render函数 vue通过 template 来创建你的 HTML.但是,在特殊情况下,这种写死的模式无法满足需求,必须需要js的编程能力.此时,需要用render来创建HTML. 什么情况下适合使用render函数 在一次封装一套通用按钮组件的工作中,按钮有四个样式(default success error ).首先,你可能会想到如下实现 <div v-if="type === 'success'">success</div> <div v-else

  • vue 中的 render 函数作用详解

    render 函数作用 vue渲染函数文档第一遍看的晕晕乎乎的,再看看写写终于清晰了.建议配合文档阅读,本文也是根据文档加上自己的理解. 注:本文代码都是在单文件组件中编写.代码地址 render 函数作用 render 函数 跟 template 一样都是创建 html 模板的,但是有些场景中用 template 实现起来代码冗长繁琐而且有大量重复,这时候就可以用 render 函数. 官网例子:子组件想要根据父组件传递的 level 值(1-6)来决定渲染标签 h 几.具体代码可以看文档.

  • 详解vue渲染函数render的使用

    1.什么是render函数? vue通过 template 来创建你的 HTML.但是,在特殊情况下,这种写死的模式无法满足需求,必须需要js的编程能力.此时,需要用render来创建HTML. 比如如下我想要实现如下html: <div id="container"> <h1> <a href="#" rel="external nofollow" rel="external nofollow"

  • 浅谈vue的iview列表table render函数设置DOM属性值的方法

    如下所示: { title: '负责人社保照片', key: 'leaderIdNumber', render: (h, params) => { return h('img',{domProps:{ src:params.row.leaderIdNumber }}) } }, 找了好多,终于找到了原因,如果想要让列表返回的是一个img标签,并且设置img的src,这里不能用props,而是要用domProps就ok了. 以上这篇浅谈vue的iview列表table render函数设置DOM属

  • vue iview组件表格 render函数的使用方法详解

    如果要在标签中加入属性,例如img 中src属性   a标签中href属性  此时需要用到 attrs 来加入而不是props { title: '操作', key: 'action', align: 'center', render: function (h, params) { return h('div', [ h('Button', { props: { type: 'primary', size: 'small' }, style: { marginRight: '8px' }, on

  • 浅析Vue 中的 render 函数

    render函数是什么 简单的说,在vue中我们使用模板HTML语法组建页面的,使用render函数我们可以用js语言来构建DOM 因为vue是虚拟DOM,所以在拿到template模板时也要转译成VNode的函数,而用render函数构建DOM,vue就免去了转译的过程. 当使用render函数描述虚拟DOM时,vue提供一个函数,这个函数是就构建虚拟DOM所需要的工具.官网上给他起了个名字叫createElement.还有约定的简写叫h, vm中有一个方法_c,也是这个函数的别名 先看官网对

  • 在vue中通过render函数给子组件设置ref操作

    正常我们的写法是,这样ref不会生效,h是作用在渲染的时候的,而ref是渲染之后才创建的,因此在h函数中使用ref是无效的. render: (h, params) => { return h(expandRow, { ref:'child', props: { row: params.row } }) } 我们常见h函数的用法是: render: (h) => { return h(ele) } => 是es6的用法,相当于 (h) => {} 相当于 function(){},

  • 浅析Vue中Virtual DOM和Diff原理及实现

    目录 0. 写在开头 1. vdom 2. Diff 0. 写在开头 本文将秉承Talk is cheap, show me the code原则,做到文字最精简,一切交由代码说明! 1. vdom vdom即虚拟DOM,将DOM映射为JS对象,结合diff算法更新DOM 以下为DOM <div id="app"> <div class="home">home</div> </div> 映射成VDOM { tag: '

  • 在vue中使用防抖函数组件操作

    初级 1.先写好防抖函数 /** * @desc 防抖函数 * @param {需要防抖的函数} func * @param {延迟时间} wait * @param {是否立即执行} immediate */ export function debounce(func, wait, immediate) { let timeout return function(...args) { let context = this if (timeout) clearTimeout(timeout) i

  • Vue.js之render函数使用详解

    Vue 推荐在绝大多数情况下使用 template 来创建你的 HTML.然而在一些场景中,你真的需要 JavaScript的完全编程的能力,这就是 render 函数,它比 template 更接近编译器. 在 HTML 层, 我们决定这样定义组件接口:通过传入不同的level 1-6 生成h1-h6标签,和使用slot生成内容 <div id="div1"> <child :level="1">Hello world!</child

  • 浅析vue中的组件传值

    目录 一.正向传值 验证写法 props验证 更多验证 二.逆向传值 自定义事件 实现逆向传值 三.同胞传值/兄弟传值 low的方式(了解) 中央事件总线 eventBus 前言: 只要是做项目,组件和组件之间的传值是不可避免的,那么怎样才能完成组件之间的传值呢?我总结了以下几点,若有不足,欢迎补充 一.正向传值 基本写法: props:[“接收变量1”,“接收变量2”.......] 使用: 1,在需要接收数据的子组件中,定义props设置接收变量 <template> <div>

  • vue语法之render函数和jsx的基本使用

    目录 h函数的使用 h函数基本介绍 h函数使用流程 h函数案例练习 jsx的体验 jsx的babel配置 jsx计数器案例 h函数的使用 h函数基本介绍 Vue推荐在绝大数情况下使用模板来创建你的HTML,然后一些特殊的场景,你真的需要JavaScript的完全编程的能力,这个时候你可以使用渲染函数,它比模板更接近编译器: 前面我们讲解过VNode和VDOM的概念: Vue在生成真实的DOM之前,会将我们的节点转换成VNode,而VNode组合在一起形成一颗树结构,就是虚拟DOM (VDOM):

  • vue3中的render函数里定义插槽和使用插槽

    目录 render函数里定义插槽和使用插槽 定义插槽 定义有插槽的组件使用插槽 vue3 render函数小变动 render函数的参数 render函数签名 VNode属性格式 render函数里定义插槽和使用插槽 vue3中this.slots和vue2的区别 vue3:this.slots是一个{ [name: string]: (…args: any[]) => Array | undefined }的对象,每个具名插槽的内容都要通过函数调用.如v-slot:foo插槽分发的内容通过th

  • 在vue中使用回调函数,this调用无效的解决

    let self = this //使用新变量替换this,以免this无效 //updateStudentInfoToServer是一个将本身部分数据异步上传的接口,接收三个参数,其中第一个是数据,第二.三个是函数,第二.三个函数使用function(){}形式书写 updateStudentInfoToServer:function(data, networkOk, networkError){ let postData = this.$qs.stringify({ data:data })

随机推荐