“Vue从入门到实战:render函数”的版本间的差异

来自CloudWiki
跳转至: 导航搜索
(创建页面,内容为“Vue推荐在大多数情况下使用模板来构建HTML, 然后在一些场景中,你可能需要Javascript的编程能力,这时可以使用render函数,它…”)
 
第1行: 第1行:
 +
==背景==
 
Vue推荐在大多数情况下使用模板来构建HTML,
 
Vue推荐在大多数情况下使用模板来构建HTML,
  
 
然后在一些场景中,你可能需要Javascript的编程能力,这时可以使用render函数,它比模板更接近编译器。
 
然后在一些场景中,你可能需要Javascript的编程能力,这时可以使用render函数,它比模板更接近编译器。
  
 +
[[文件:vue21022001.png|600px]]
  
 +
假设我们要生成一些带锚点的标题:
 +
 +
<nowiki><h1>
 +
  <a name="hello-world" href="#hello-world">
 +
    Hello world!
 +
  </a>
 +
</h1></nowiki>
 +
 +
对于上面的 HTML,你决定这样定义组件接口:
 +
 +
<nowiki><anchored-heading :level="1">Hello world!</anchored-heading></nowiki>
 +
 +
当开始写一个只能通过 level prop 动态生成标题 (heading) 的组件时,你可能很快想到这样实现:
 +
 +
<nowiki><script type="text/x-template" id="anchored-heading-template">
 +
  <h1 v-if="level === 1">
 +
    <slot></slot>
 +
  </h1>
 +
  <h2 v-else-if="level === 2">
 +
    <slot></slot>
 +
  </h2>
 +
  <h3 v-else-if="level === 3">
 +
    <slot></slot>
 +
  </h3>
 +
  <h4 v-else-if="level === 4">
 +
    <slot></slot>
 +
  </h4>
 +
  <h5 v-else-if="level === 5">
 +
    <slot></slot>
 +
  </h5>
 +
  <h6 v-else-if="level === 6">
 +
    <slot></slot>
 +
  </h6>
 +
</script>
 +
 +
Vue.component('anchored-heading', {
 +
  template: '#anchored-heading-template',
 +
  props: {
 +
    level: {
 +
      type: Number,
 +
      required: true
 +
    }
 +
  }
 +
})</nowiki>
 +
 +
虽然模板在大多数组件中都非常好用,但在本例中不太合适,模板代码冗长,且<slot>元素在每一级标题元素中都重复书写了。
 +
 +
==render函数的引入==
 +
下面改用render函数重复上面的示例,代码精简了很多
 +
 +
render函数 又称渲染函数,字符串模板的代替方案,允许你发挥 JavaScript 最大的编程能力。该渲染函数接收一个 createElement 方法作为第一个参数用来创建 VNode。
  
 
  <nowiki>
 
  <nowiki>
第16行: 第69行:
 
 
 
<div id="app">
 
<div id="app">
<anchored-heading :level="1">
+
 
 +
<anchored-heading :level="3">
 
<a name="hello-world" href="#hello-world">
 
<a name="hello-world" href="#hello-world">
 
     Hello world!
 
     Hello world!
 
   </a>
 
   </a>
 
</anchored-heading>
 
</anchored-heading>
 +
 +
 
</div>
 
</div>
 
<script type = "text/javascript">
 
<script type = "text/javascript">
第43行: 第99行:
 
</body>
 
</body>
 
</html></nowiki>
 
</html></nowiki>
 +
 +
注:$slots用于以编程方式访问由插槽分发的内容,每个命名的插槽都有其相应的属性。default属性包含了所有未包含在命名插槽中的节点或v-slot:default的内容。
 +
 +
====render函数的解释==
 +
===createElement函数===
 +
该函数用于返回描述节点信息及其子节点子信息的一个对象,即虚拟节点(简称为VNode)
 +
 +
一般带有三个参数:
 +
*第一个参数是要创建的元素节点的名字(字符串形式)或者组件选项(对象形式);
 +
*第二个参数是元素的属性集合(包括普通属性、prop、事件属性、自定义指令等),以对象形式给出
 +
*第三个参数是子节点的信息,以数组形式给出,如果该元素只有文本子节点,那么直接以字符串形式给出即可,如果还有子元素,则继续调用createElement函数。

2021年2月20日 (六) 02:46的版本

背景

Vue推荐在大多数情况下使用模板来构建HTML,

然后在一些场景中,你可能需要Javascript的编程能力,这时可以使用render函数,它比模板更接近编译器。

Vue21022001.png

假设我们要生成一些带锚点的标题:

<h1>
  <a name="hello-world" href="#hello-world">
    Hello world!
  </a>
</h1>

对于上面的 HTML,你决定这样定义组件接口:

<anchored-heading :level="1">Hello world!</anchored-heading>

当开始写一个只能通过 level prop 动态生成标题 (heading) 的组件时,你可能很快想到这样实现:

<script type="text/x-template" id="anchored-heading-template">
  <h1 v-if="level === 1">
    <slot></slot>
  </h1>
  <h2 v-else-if="level === 2">
    <slot></slot>
  </h2>
  <h3 v-else-if="level === 3">
    <slot></slot>
  </h3>
  <h4 v-else-if="level === 4">
    <slot></slot>
  </h4>
  <h5 v-else-if="level === 5">
    <slot></slot>
  </h5>
  <h6 v-else-if="level === 6">
    <slot></slot>
  </h6>
</script>

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

虽然模板在大多数组件中都非常好用,但在本例中不太合适,模板代码冗长,且<slot>元素在每一级标题元素中都重复书写了。

render函数的引入

下面改用render函数重复上面的示例,代码精简了很多

render函数 又称渲染函数,字符串模板的代替方案,允许你发挥 JavaScript 最大的编程能力。该渲染函数接收一个 createElement 方法作为第一个参数用来创建 VNode。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script src="vue.js"></script>
	</head>
	<body>
		
		<div id="app">

			<anchored-heading :level="3">
				<a name="hello-world" href="#hello-world">
    			Hello world!
  			</a>
			</anchored-heading>


		</div>
		<script type = "text/javascript">
			Vue.component('anchored-heading', {
			  render: function (createElement) {
			    return createElement(
			      'h' + this.level,   // 标签名称
			      this.$slots.default // 子节点数组
			    )
			  },
			  props: {
			    level: {
			      type: Number,
			      required: true
			    }
			  }
			})
			new Vue({
			  el: '#app'
			})
		</script>
	</body>
</html>

注:$slots用于以编程方式访问由插槽分发的内容,每个命名的插槽都有其相应的属性。default属性包含了所有未包含在命名插槽中的节点或v-slot:default的内容。

==render函数的解释

createElement函数

该函数用于返回描述节点信息及其子节点子信息的一个对象,即虚拟节点(简称为VNode)

一般带有三个参数:

  • 第一个参数是要创建的元素节点的名字(字符串形式)或者组件选项(对象形式);
  • 第二个参数是元素的属性集合(包括普通属性、prop、事件属性、自定义指令等),以对象形式给出
  • 第三个参数是子节点的信息,以数组形式给出,如果该元素只有文本子节点,那么直接以字符串形式给出即可,如果还有子元素,则继续调用createElement函数。