开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 12 天,点击查看活动详情
Vue是如何设计UI的
HTML类似的声明式描述UI减少学习成本,增加开发效率
vue中templete模板
- 与html标签一致
- 属性描述,层级都与html一致
<div id ='iddd'><span></span></div> - 动态属性用
v-bind或者:表示 如:<div :id="dynamicId"></div> - 使用
@或者v-on来描述事件
js描述UI
js描述UI更灵活。 eg
const title = {
tag:`h${lever}`
}
用templete描述则需要穷举。
常见的h函数就是用js来描述UI的。
<templete>
<div id={'foo'} class = {'bar'}></div>
</templete>
templete会被编译成为render函数。里面内容编译成对象即虚拟dom
等价于
export default {
render() {
/**
* @param type:string 标签的类型
* @param props:object 所有属性的对象
* @param children:array children的数组
@return object 返回值就是虚拟dom
**/
return h( 'div', { id: 'foo', class: 'bar' }, [ /* children */ ])
}
}
等价于
最终上线两种方式都会编译成为虚拟dom 即
render({
tag:'div',
props: { id: 'foo', class: 'bar' },
children: []
}, container)
细心的同学会发现h函数实际上就是虚拟dom的简写。
那么我们发现虚拟dom前面有render函数。那么render又是什么呢
渲染器与编译器
render函数即渲染器。上面我们看到无论是h函数还是templete模板最终都会编译成文虚拟dom。 而render函数 则是将虚拟dom 渲染成为(document.crenteElement('div'))这种浏览器识别的内容
如何实现render
const vNode = {
tag:'div',
props: { id: 'foo', class: 'bar' },
children: []
}
render(vNode, document.body)
实现render 大致
- 根据tag 来crenteElement, 遍历props 添加到element上面。
- 判断children 如果sttring 则createTextNode 否则遍历children递归循环步骤1,2
组件如何渲染呢
组件实际上也是
tag:'MyComponent'
function组件
const MyComponent = function(){
return {
tag: 'div',
props:{
onClick: () => alert('hellow')
},
children: 'clickMe'
}
}
本质是一个方法返回虚拟dom, 渲染时候只需要调用方法获取虚拟dom循环上面1,2步骤 即
vNode.tag()
类组件
const MyComponent = {
render() {
return {
tag: 'div',
props:{
onClick: () => alert('hellow')
},
children: 'clickMe'
}
}
}
类组件本质是返回一个对象 即
{render: render function }
所以渲染只需要调用对象中的render方法
vNode.tag.render()
最终实现render 实现render 大致 判断vNode.tag
-
如果为字符串
- 根据tag 来crenteElement, 遍历props 添加到element上面。
- 判断children 如果sttring 则createTextNode 否则遍历children递归循环步骤1,2
-
如果为方法
调用方法
const functionNode = vNode.tag() render(functionNode, container) -
如果为object
const functionNode = vNode.tag.render() render(functionNode, container)
总结: 组件本质是一组DOM元素的封装,templete模板会编译成为render渲染函数,h实际是简化获取虚拟dom的。
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 12 天,点击查看活动详情