render函数简而言之就是用js的方式来创建html 类似jQuery里面的创建一个字符串 然后append到dom上(我的理解)
Vue 通过建立一个虚拟 DOM 对真实 DOM 发生的变化保持追踪。请仔细看这行代码
return createElement('h1', this.blogTitle)
createElement 到底会返回什么呢?其实不是一个实际的 DOM 元素。它更准确的名字可能是 createNodeDescription,因为它所包含的信息会告诉 Vue 页面上需要渲染什么样的节点,及其子节点。我们把这样的节点描述为“虚拟节点 (Virtual Node)”,也常简写它为“VNode”。“虚拟 DOM”是我们对由 Vue 组件树建立起来的整个 VNode 树的称呼。
createElement
创建虚拟dom的参数
// @returns {VNode}
createElement(
// {String | Object | Function}
// 一个 HTML 标签字符串,组件选项对象,或者
// 解析上述任何一种的一个 async 异步函数。必需参数。
'div',
// {Object}
// 一个包含模板相关属性的数据对象
// 你可以在 template 中使用这些特性。可选参数。
{
'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
}
},
// {String | Array}
// 子虚拟节点 (VNodes),由 `createElement()` 构建而成,
// 也可以使用字符串来生成“文本虚拟节点”。可选参数。
[
'先写一些文字',
createElement('h1', '一则头条'),
createElement(MyComponent, {
props: {
someProp: 'foobar'
}
})
]
)
官网例子:
var getChildrenTextContent = function (children) {
return children.map(function (node) {
return node.children
? getChildrenTextContent(node.children)
: node.text
}).join('')
}
Vue.component('anchored-heading', {
render: function (createElement) {
// 创建 kebab-case 风格的ID
var headingId = getChildrenTextContent(this.$slots.default)
.toLowerCase()
.replace(/\W+/g, '-')
.replace(/(^\-|\-$)/g, '')
return createElement(
'h' + this.level,
[
createElement('a', {
attrs: {
name: headingId,
href: '#' + headingId
}
}, this.$slots.default) //使用了插槽接收内容,也可以使用作用域插槽
]
)
},
props: {
level: {
type: Number,
required: true
}
}
})
调用这个新创建的组件的使用:
<anchored-heading :level="2">Hello world!</anchored-heading>
渲染出来的组件如果用template来实现应该为:
<h2>
<a name="hello-world" href="#hello-world">
Hello world!
</a>
</h2>
VNodes 必须唯一
组件树中的所有 VNodes 必须是唯一的。这意味着,下面的 render function 是无效的:
render: function (createElement) {
var myParagraphVNode = createElement('p', 'hi')
return createElement('div', [
// 错误-重复的 VNodes
myParagraphVNode, myParagraphVNode
])
}
如果你真的需要重复很多次的元素/组件,你可以使用工厂函数来实现。例如,下面这个例子 render 函数完美有效地渲染了 20 个相同的段落:
render: function (createElement) {
return createElement('div',
Array.apply(null, { length: 20 }).map(function () {
return createElement('p', 'hi')
})
)
}
只要在原生的 JavaScript 中可以轻松完成的操作,Vue 的 render 函数就不会提供专有的替代方法。比如,在 template 中使用的 v-if 和 v-for
<ul v-if="items.length">
<li v-for="item in items">{{ item.name }}</li>
</ul>
<p v-else>No items found.</p>
会使用render这样写:
props: ['items'],
render: function (createElement) {
if (this.items.length) {
return createElement('ul', this.items.map(function (item) {
return createElement('li', item.name)
}))
} else {
return createElement('p', 'No items found.')
}
}
render不支持v-model 需要自己实现该逻辑
createElement这样写起来超级不方便有木有 所以在项目中使用jsx语法会特别方便
jsx语法大致是会将<开头的解析成html,将{}解析成js具体可百度
模板:
<ul v-if="items.length">
<li v-for="item in items">{{ item.name }}</li>
</ul>
<p v-else>No items found.</p>
会使用jsx格式的render这样写:
render: function (h) {
if (this.items.length) {
return <ul>
this.items.map((item)=>{
return <li>{item.name}</li>
})
</ul>
} else {
return <p>No items found.</p>
}
}
之前第一次接触vue项目的时候就是跟着别人做,直接把参考项目的格式复制过来也不知道意思。
image.png
这是当时做的项目的其中一个表格中的某个数据要做成a标签形式的 可以点击的那种。
OK啦!!!
网友评论