Vue.js设计与实现之Vue.js3设计思路
时间:2023-03-12 08:04:17
科技观察
1.写在前面的这篇文章将基于全局的视角来理解Vue.js3的设计思路、工作机制和一些重要的独立组件,了解它们之间的关系它们是如何相互独立的,又是如何相互合作的。了解描述UI的两种形式:模板字符串和虚拟DOM,Vue.js框架的两个重要组件:编译器和渲染器。2.声明式描述UI通过前面的介绍,我们知道Vue.js3是一个声明式UI框架。作者如何参与声明式UI框架的设计,编写前端页面涉及哪些内容?DOM元素属性和事件元素的层次结构上面的内容是原生包含的,在设计框架的时候如何让它们响应式,Vue.js3中的解决方案是:用同样的方式描述DOM元素和属性,层次结构等作为原生html标签onechuan
使用:或v-bind描述动态绑定属性,使用@或v-on描述事件
onechuan 这样用户就可以实现声明式描述UI,而无需手动编写任何命令式代码。当然,除了用模板来描述UI,还可以用JS对象来描述:constelement={//label元素tag:"div",//label属性props:{onClick:handleClick},//子节点children:[{tag:"span"}]}对应的template模板为:
使用js数据有什么异同objectdescriptionandtemplatetemplate?//h标签的限制constlevel=3;constelement={tag:`h${level}`,//h3tag}我们看到js对象结构代码简洁明了,但是使用模板需要穷举枚举:
我们在Vue.js组件中手写渲染函数,使用虚拟DOM来描述UI。h函数的返回值是一个对象,开发人员可以使用虚拟DOM轻松描述UI。import{h}from"vue";exportdefault{render(){returnh("div",{onClick:handleClick})//VirtualDOM}}对应的JS对象描述UI为如下代码段:exportdefault{render(){return{tag:"div",props:{onClick:handleClick}}}}组件的渲染函数renderer的作用:Vue.js根据组件的render函数的返回值生成虚拟DOM,以及然后将组件的内容渲染到页面。3.认识渲染器我们可以使用JS数据对象来描述虚拟DOM,那么虚拟DOM是如何通过渲染函数转换为真实DOM并渲染到页面的呢?在前面的代码片段中,JS数据对象用于描述虚拟DOM:constvnode={tag:"div",props:{onclick:()=>console.log("hellopingping")},children:"pleaseclickme"}我们需要编写渲染函数renderer来将虚拟DOM渲染成真实DOM,接收两个参数:vnode虚拟DOM对象和容器真实DOM元素挂载点,容器用于挂载渲染的真实DOM元素渲染功能。functionrenderer(vnode,container){//使用vnode的标签作为标签名渲染DOM元素constel=document.createElement(vnode.tag)//遍历vnode的props作为DOM元素的属性和事件for(constkeyinvnode.props){if(/^on/.test(key)){//如果key以on开头,说明是事件el.addEventListener(key.substring(2).toLowerCase(),//事件名会onClick-->clickvnode.props[key]//事件处理函数)}}//处理childrenif(typeofvnode.children==="string"){//如果是字符串,直接作为text的element子节点el.appendChild(document.createTextNode(vnode.children))}elseif(Array.isArray(vnode.children)){//递归调用renderer函数渲染子节点,以当前元素el作为挂载点vnode。children.forEach(child=>renderer(child,el))}//添加元素到挂载点container.appendChild(el)}call:renderer(vnode,document.body)点击按钮后:rendererIdea的实现:创建元素,为元素添加属性和事件,递归遍历children创建节点。4.组件的本质。DOM元素对应的虚拟DOM对象。constMyComponent=function(){return{tag:"div",props:{onClick:()=>console.log("helloworld")},children:"clickme"}}通过虚拟中的tag属性DOMobject可以用来存储组件功能,并将其渲染为标签类型,同时还需要renderer功能。当然此时的渲染函数需要根据要渲染的标签类型来决定,是普通标签元素还是组件元素。constvnode={tag:MyComponent}renderer(vnode,document.body)functionrenderer(vnode,container){//判断是标签元素还是组件if(typeofvnode.tag==="string"){//如果是String,直接作为元素的标签元素mountElement(vnode,container)}else{mountComponent(vnode,container)}}//renderelementfunctionmountElement(vnode,container){//使用vnode。tag作为创建DOM元素的标签名constel=document.createElement(vnode.tag)//遍历vnode的props作为DOM元素的属性和事件for(constkeyinvnode.props){if(/^on/.test(key)){//ifThekey以on开头,表示它是一个事件el.addEventListener(key.substring(2).toLowerCase(),//事件名称会是onClick-->clickvnode.props[key]//事件处理函数)}}//处理childrenif(typeofvnode.children==="string"){//如果是字符串,直接作为元素el的文本子节点。appendChild(document.createTextNode(vnode.children))}elseif(Array.isArray(vnode.children)){//递归调用renderer函数渲染子节点,以当前元素el为挂载点vnode.children.forEach(child=>renderer(child,el))}//添加元素到挂载点container.appendChild(el)}//渲染组件函数mountComponent(vnode,container){//调用组件函数,获取组件要渲染的内容-虚拟DOMconstsubtree=vnode.tag()//递归调用renderer渲染子树renderer(subtree,container)}5.模板的工作原理其实手写virtual可以使用DOM或模板形式对UI的声明式描述,在Vue.js框架的设计中始终支持两种形式。我们知道JS对象描述的是虚拟DOM的形式,而虚拟DOM是通过渲染器转换成真实DOM的,那么模板是如何渲染到它的呢?页面呢?hellopingping
模板字符串渲染到页面,依赖模板字符串渲染到页面,依赖Vue.js框架的一个重要功能--编译器compiler,它的作用是将模板字符串编译成其功能对应的渲染函数:render(){returnh("div",{onClick:handleClick},"hellopingping")}对于这个,我们知道你是否使用模板无论是字符串还是手写渲染函数,通过渲染函数将虚拟DOM转化为真实DOM,最终将所描述的内容渲染到页面上。只是使用模板字符串需要额外的编译过程,需要编译器将模板字符串编译成渲染函数。6、编译器和渲染器是一个有机的整体。在Vue.js框架设计中,组件的实现依赖于渲染器和编译器,渲染器和编译器是重要的部分,既相互独立又相互依赖。7.写在本文后面,我们了解到Vue.js框架是声明式描述UI的,描述UI有两种形式:模板字符串和手写虚拟DOM形式。虚拟DOM表单比模板字符串更准确。灵活,但模板字符串比虚拟DOM表单更直观。Vue.js框架的设计中有两个重要的组件:编译器和渲染器。编译器将模板字符串编译成渲染函数,渲染器将虚拟DOM创建成真实DOM,最终完成页面。使成为。