Vue中的template 里面使用的模版是HTML语法组件的页面,在Vue中都会被编译成render函数,Vue会采用虚拟dom进行页面组件渲染。
render函数基本使用
render不能与template 一起使用,否则无效。
<script>
export default {
name:'render',
render(createElement){
return createElement('h1',{},'hello')
}
}
</script>
在APP.vue中引入Render.vue
<template>
<div id="app">
<Render></Render>
</div>
</template>
<script>
import Render from './components/Render'
export default {
name: 'App',
components: {
Render
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
通过render动态渲染节点 Render.vue 修改为
<script>
export default {
name:'render',
props:{
tag:{
type:String,
required:true,
},
data:{
type:String
}
},
render(createElement){
return createElement(this.tag,{},this.data)
}
}
</script>
App.Vue 中使用 :tag :data 传参
<template>
<div id="app">
<Render :tag="'div'" :data="'Hello World!'" ></Render>
</div>
</template>
createElement 第二个参数可以设置属性
render(createElement){
return createElement(this.tag,{
class:'render-color'
},this.data)
}
<style scoped>
.render-color{
background-color: aqua;
}
</style>
也可以使用 domProps 进行设置
render(createElement){
return createElement(this.tag,{
// class:'render-color',
domProps:{
className:'render-color',
innerHTML:'hahhaha', // 会替换传进来的data的值
}
},this.data)
}
createElement 第三个参数可以传一个数组,从而实现嵌套
render(createElement){
return createElement(this.tag,{
class:'render-color',
},[createElement('p',{},'balabal')])
}
createElement 简易版
- 创建一个createElement
function Element(type,props,children){
this.type = type
this.props = props
this.children = children
}
function createElement(type,props,children){
return new Element(type,props,children)
}
- 实现render 函数
function render(obj){
// 创建节点
let el = document.createElement(obj.type)
for (let key in obj.props){
el.setAttribute(key,obj.props[key])
}
if(Array.isArray(obj.children)){
obj.children.forEach(element => {
// 递归操作,如果当前child不是文本,就继续进行操作,否则创建文本节点
element = element instanceof Element? render(element):document.createTextNode()
el.appendChild(element)
});
}
else if (typeof obj.children === 'string'){ // 如果是字符串当成数组进行递归
el.appendChild(document.createTextNode(obj.children))
}
return el
}
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app"></div>
</body>
<script>
let myDom = createElement('div',{class:'container',style:'color:red'},
[
createElement('p',{class:'item'},'child1'),
createElement('p',{class:'item'},'child2'),
createElement('p',{class:'item'},'child3'),
createElement('input',{class:'item',value:'I am input'},'child4')
])
let myDom2 = createElement('p',{class:'item'},'child23233')
function Element(type,props,children){
this.type = type
this.props = props
this.children = children
}
function createElement(type,props,children){
return new Element(type,props,children)
}
function render(obj){
// 创建节点
let el = document.createElement(obj.type)
for (let key in obj.props){
el.setAttribute(key,obj.props[key])
}
if(Array.isArray(obj.children)){
obj.children.forEach(element => {
// 递归操作,如果当前child不是文本,就继续进行操作,否则创建文本节点
element = element instanceof Element? render(element):document.createTextNode()
el.appendChild(element)
});
}
else if (typeof obj.children === 'string'){ // 如果是字符串当成数组进行递归
el.appendChild(document.createTextNode(obj.children))
}
return el
}
function renderDom(node,target){
node.appendChild(target)
}
let node2 = render(myDom2)
let app = document.getElementById('app')
renderDom(app,render(myDom))
renderDom(app,render(myDom2))
</script>
</html>
<style>
.container{
font-weight: 700;
}
.item{
background-color: darkolivegreen;
}
</style>
网友评论