如何理解Vue的render函数
第一个参数(必须) - {String | Object | Function}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render</title>
<script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
<div id="app">
<elem></elem>
</div>
<script>
Vue.component('elem', {
render: function(createElement) {
return createElement('div');//一个HTML标签字符
/*return createElement({
template: '<div></div>'//组件选项对象
});*/
/*var func = function() {
return {template: '<div></div>'}
};
return createElement(func());//一个返回HTML标签字符或组件选项对象的函数*/
}
});
new Vue({
el: '#app'
});
</script>
</body>
</html>
第二个参数(可选) - {Object}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render</title>
<script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
<div id="app">
<elem></elem>
</div>
<script>
Vue.component('elem', {
render: function(createElement) {
var self = this;
return createElement('div', {//一个包含模板相关属性的数据对象
'class': {
foo: true,
bar: false
},
style: {
color: 'red',
fontSize: '14px'
},
attrs: {
id: 'foo'
},
domProps: {
innerHTML: 'baz'
}
});
}
});
new Vue({
el: '#app'
});
</script>
</body>
</html>
第三个参数(可选) - {String | Array}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render</title>
<script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
<div id="app">
<elem></elem>
</div>
<script>
Vue.component('elem', {
render: function(createElement) {
var self = this;
// return createElement('div', '文本');//使用字符串生成文本节点
return createElement('div', [//由createElement函数构建而成的数组
createElement('h1', '主标'),//createElement函数返回VNode对象
createElement('h2', '副标')
]);
}
});
new Vue({
el: '#app'
});
</script>
</body>
</html>
两种组件写法对比
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render</title>
<script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
<div id="app">
<ele></ele>
</div>
<script>
/*Vue.component('ele', {
template: '<div id="elem" :class="{show: show}" @click="handleClick">文本</div>',
data: function() {
return {
show: true
}
},
methods: {
handleClick: function() {
console.log('clicked!');
}
}
});*/
Vue.component('ele', {
render: function(createElement) {
return createElement('div', {
'class': {
show: this.show
},
attrs: {
id: 'elem'
},
on: {
click: this.handleClick
}
}, '文本');
},
data: function() {
return {
show: true
}
},
methods: {
handleClick: function() {
console.log('clicked!');
}
}
});
new Vue({
el: '#app'
});
</script>
</body>
</html>
this.$slots用法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render</title>
<script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
<div id="app">
<blog-post>
<h1 slot="header"><span>About Me</span></h1>
<p>Here's some page content</p>
<p slot="footer">Copyright 2016 Evan You</p>
<p>If I have some content down here</p>
</blog-post>
</div>
<script>
Vue.component('blog-post', {
render: function(createElement) {
var header = this.$slots.header,//返回由VNode组成的数组
body = this.$slots.default,
footer = this.$slots.footer;
return createElement('div', [
createElement('header', header),
createElement('main', body),
createElement('footer', footer)
])
}
});
new Vue({
el: '#app'
});
</script>
</body>
</html>
使用props传递数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render</title>
<script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
<div id="app">
<ele :show="show"></ele>
<ele :show="!show"></ele>
</div>
<script>
Vue.component('ele', {
render: function(createElement) {
if (this.show) {
return createElement('p', 'true');
} else {
return createElement('p', 'false');
}
},
props: {
show: {
type: Boolean,
default: false
}
}
});
new Vue({
el: '#app',
data: {
show: false
}
});
</script>
</body>
</html>
VNodes必须唯一
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render</title>
<script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
<!-- VNode必须唯一 -->
<div id="app">
<ele></ele>
</div>
<script>
var child = {
render: function(createElement) {
return createElement('p', 'text');
}
};
/*Vue.component('ele', {
render: function(createElement) {
var childNode = createElement(child);
return createElement('div', [
childNode, childNode//VNodes必须唯一,渲染失败
]);
}
});*/
Vue.component('ele', {
render: function(createElement) {
return createElement('div',
Array.apply(null, {
length: 2
}).map(function() {
return createElement(child)//正确写法
})
);
}
});
new Vue({
el: '#app'
})
</script>
</body>
</html>
v-model指令
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render</title>
<script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
<div id="app">
<el-input :name="name" @input="val=>name=val"></el-input>
<div>你的名字是{{name}}</div>
</div>
<script>
Vue.component('el-input', {
render: function(createElement) {
var self = this;
return createElement('input', {
domProps: {
value: self.name
},
on: {
input: function(event) {
self.$emit('input', event.target.value);
}
}
})
},
props: {
name: String
}
});
new Vue({
el: '#app',
data: {
name: 'hdl'
}
});
</script>
</body>
</html>
作用域插槽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render</title>
<script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
<div id="app">
<ele>
<template scope="props">
<span>{{props.text}}</span>
</template>
</ele>
</div>
<script>
Vue.component('ele', {
render: function(createElement) {
// 相当于<div><slot :text="msg"></slot></div>
return createElement('div', [
this.$scopedSlots.default({
text: this.msg
})
]);
},
data: function() {
return {
msg: '来自子组件'
}
}
});
new Vue({
el: '#app'
});
</script>
</body>
</html>
向子组件中传递作用域插槽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render</title>
<script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
<div id="app">
<ele></ele>
</div>
<script>
Vue.component('ele', {
render: function(createElement) {
return createElement('div', [
createElement('child', {
scopedSlots: {
default: function(props) {
return [
createElement('span', '来自父组件'),
createElement('span', props.text)
];
}
}
})
]);
}
});
Vue.component('child', {
render: function(createElement) {
return createElement('b', this.$scopedSlots.default({text: '我是组件'}));
}
});
new Vue({
el: '#app'
});
</script>
</body>
</html>
函数化组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render</title>
<script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
<div id="app">
<smart-item :data="data"></smart-item>
<button @click="change('img')">切换为图片为组件</button>
<button @click="change('video')">切换为视频为组件</button>
<button @click="change('text')">切换为文本组件</button>
</div>
<script>
// 图片组件选项
var ImgItem = {
props: ['data'],
render: function(createElement) {
return createElement('div', [
createElement('p', '图片组件'),
createElement('img', {
attrs: {
src: this.data.url
}
})
]);
}
}
// 视频组件
var VideoItem = {
props: ['data'],
render: function(createElement) {
return createElement('div', [
createElement('p', '视频组件'),
createElement('video', {
attrs: {
src: this.data.url,
controls: 'controls',
autoplay: 'autoplay'
}
})
]);
}
};
/*纯文本组件*/
var TextItem = {
props: ['data'],
render: function(createElement) {
return createElement('div', [
createElement('p', '纯文本组件'),
createElement('p', this.data.text)
]);
}
}; Vue.component('smart-item', {
functional: true,
render: function(createElement, context) {
function getComponent() {
var data = context.props.data;
if (data.type === 'img') return ImgItem;
if (data.type === 'video') return VideoItem;
return TextItem;
}
return createElement(
getComponent(),
{
props: {
data: context.props.data
}
},
context.children
)
},
props: {
data: {
type: Object,
required: true
}
}
});
new Vue({
el: '#app',
data() {
return {
data: {}
}
},
methods: {
change: function(type) {
if (type === 'img') {
this.data = {
type: 'img',
url: 'https://raw.githubusercontent.com/iview/iview/master/assets/logo.png'
}
} else if (type === 'video') {
this.data = {
type: 'video',
url: 'http://vjs.zencdn.net/v/oceans.mp4'
}
} else if (type === 'text') {
this.data = {
type: 'text',
content: '这是一段纯文本'
}
}
}
},
created: function() {
this.change('img');
}
});
</script>
</body>
</html>
如何理解Vue的render函数的更多相关文章
- 终于搞懂了vue 的 render 函数(一) -_-|||
终于搞懂了vue 的 render 函数(一) -_-|||:https://blog.csdn.net/sansan_7957/article/details/83014838 render: h ...
- vue之Render函数
(1)什么是Render函数 先来看一个场景,在博客网中,一般有一级标题.二级标题.三级标题...,为了方便分享url,它们都做成了锚点,点击后,会将内容加载网址后面,以#分隔. 例如‘特性’是一个& ...
- vue 之 render 函数不能渲染非全局自定义函数-方案
import customCom from 'xxx.vue' render: (h) => { return h(customCom) }
- 大白话Vue源码系列(03):生成render函数
阅读目录 优化 AST 生成 render 函数 小结 本来以为 Vue 的编译器模块比较好欺负,结果发现并没有那么简单.每一种语法指令都要考虑到,处理起来相当复杂.上篇已经生成了 AST,本篇依然对 ...
- 大白话Vue源码系列(04):生成render函数
阅读目录 优化 AST 生成 render 函数 小结 本来以为 Vue 的编译器模块比较好欺负,结果发现并没有那么简单.每一种语法指令都要考虑到,处理起来相当复杂.上篇已经生成了 AST,本篇依然对 ...
- Vue学习笔记进阶篇——Render函数
基础 Vue 推荐在绝大多数情况下使用 template 来创建你的 HTML.然而在一些场景中,你真的需要 JavaScript 的完全编程的能力,这就是 render 函数,它比 template ...
- vue render函数
基础 vue推荐在绝大多数情况下使用template来创建你的html.然而在一些场景中,你真的需要javascript的完全编程能力.这就是render函数.它比template更接近编译器 < ...
- [转]iview render函数常用总结(vue render函数)
原文地址:https://blog.csdn.net/weixin_43206949/article/details/89385550 iview 的render函数就是vue的render函数ivi ...
- 你是如何理解Vue的响应式系统的
1.响应式系统简述: 任何一个 Vue Component 都有一个与之对应的 Watcher 实例. Vue 的 data 上的属性会被添加 getter 和 setter 属性. 当 Vue Co ...
随机推荐
- java中的final关键字的用法
一. 什么是final关键字? final在Java中是一个保留的关键字,可以声明成员变量.方法.类以及本地变量.一旦你将引用声明作final,你将不能改变这个引用了,编译器会检查代码,如果你试图将变 ...
- leetcode-160周赛-5240-串联字符串的最大长度
题目描述: 自己的提交:O(2**n∗n∗m),m 为字符串长度 class Solution: def maxLength(self, arr: List[str]) -> int: from ...
- 关于axios中post请求提交后变成get的问题
这个问题归结于自己的不细心,如下图. 头疼了好久,才发现是自己多写了一个s,在此记录一下.
- 一维条码Code 128 类型的 A、B、C及Auto的区别
CODE 128条码是1981年由COMPUTER IDENTICS公司开发的.对128个字符进行标准化的多级别编码.其条码的字符与其表示的数据呈1对1的关系,特点是通过起始字符.代码集字符.转换字符 ...
- common配置文件
<dependencies> <dependency> <groupId>com.github.pagehelper</groupId> <art ...
- cartographer和ROS的坐标系关系
参考定义见:backpack_3d.lua Local map frame是一次slam过程中的原点.但是现在cartographer支持Incremental mapping.global m ...
- [7.18NOIP模拟测试5]星际旅行 题解
题面(加密) 考场上靠打表yy出的规律进而想到的正解233333 可以把一条双向边拆成两条单向边,这样的话每个点度数都为偶数,符合欧拉图的定义. 那么题目可以转化为:去掉两条边,使图中存在一条欧拉路. ...
- dubbo入门学习(一)-----分布式基础理论、架构发展以及rpc、dubbo核心概念
一.分布式基础理论 1.什么是分布式系统? <分布式系统原理与范型>定义: “分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统” 分布式系统(distributed ...
- 14、testng.xml 设置用例执行顺序
目录如下: TestGroup.java 代码如下: package com.testng.cn; import org.testng.annotations.*; import static org ...
- 第48章 MDK的编译过程及文件类型全解
Frm: http://www.cnblogs.com/firege/p/5806134.html 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教 ...