render用法(render及物还是不及物)

根据第一篇文章介绍的响应式原则,如下图所示。在初始化阶段,本质上发生在auto run函数中,然后由render函数生成虚拟DOM,视图根据虚拟DOM生成实际D

根据第一篇文章介绍的响应式原则,如下图所示。

render用法(render及物还是不及物)插图

在初始化阶段,本质上发生在auto run函数中,然后由render函数生成虚拟DOM,视图根据虚拟DOM生成实际DOM。因为渲染函数依赖于页面上的所有数据,而这些数据是有响应的,所以所有数据都是组件渲染函数的依赖项。一旦这些数据被更改,render函数将被再次调用。

在更新阶段,将再次调用render函数,并返回一个新的虚拟Dom。新的虚拟DOM将与旧的进行比较,diff后的最小变化将应用于实际的DOM。

Watcher负责收集依赖关系、清除依赖关系和通知依赖关系。在庞大复杂的构件树结构下,由于采用了精确的依赖跟踪系统,可以避免构件的过度渲染。

实际DOM和虚拟DOM

实际的DOM通过document.createElement('div ')生成一个DOM节点。

document . createelement(' div ')//浏览器原生对象(高开销)"[Object HTMLDivelement]"虚拟DOM通过vm生成一个JS对象。$createElement('div ')。VDOM对象有一个表示div的标签属性,一个包含所有可能特性的数据属性,还可能有一个包含更多虚拟节点的子列表。

Vm。$createElement('div')//纯JS对象(轻量级){tag:' div ',data: {attrs: {},...},children: []}因为虚拟DOM的渲染逻辑与实际DOM解耦,所以有能力在的非浏览器环境下运行,这也是为什么虚拟DOM出现后混合开发开始流行的原因。这是React Native和Weex能够实现的原则。

x和模板

JSX和模板都是声明DOM和状态之间关系的一种方式。在Vue中,默认推荐使用模板,但是JSX也可以用来做更灵活的事情。

JSX更有活力,这对于使用编程语言很有帮助,可以做任何事情。但是,动态使编译优化变得更加复杂和困难。

Template更静态,对表达式的约束更多,但是可以快速重用已有的模板。模板约束意味着可以在编译时进行更多的性能优化,在编译时比JSX更有优势。

示例1:实现示例组件

使用要求如下

& lt示例:tags="['h1 ',' h2 ',' H3 ']" & gt;& lt/example & gt;所需的输出如下

& ltdiv & gt& lth1 & gt0 & lt/h1 & gt;& lth2 & gt1 & lt/H2 & gt;& lth3 & gt2 & lt/H3 & gt;& lt/div & gt;以上需求可以通过render函数完成,官方提供createElement函数生成模板。createElement('div ',{},[...])如下。

//@返回{ vnode } CreateElement(//{ string | object | function }//一个HTML标记字符串、一个组件选项对象或//一个解决上述任何问题的异步函数。必需的参数。Div ',// {Object} //包含与模板相关的属性的数据对象。//可以在模板中使用这些属性。可选参数。{},// {String | Array} //子虚拟节点(VNodes),由“createElement()”构造。//还可以用字符串生成“文本虚拟节点”。可选参数。['先写点字',createElement('h1 ',' a headline '),CreateElement (mycomponent,{props: {some prop:' foobar'}}]]知道用法后,可以在render中返回createElement生成的虚拟节点。外层是一个div,内层是三个主播标题h1 h2 h3,所以内层需要遍历,可以用两个CreateElements来完成。

通常使用H作为createElement的别名,这是Vue的惯例,也是JSX的要求。

实施如下

& lt!-quote-->:& lt;脚本src= "../node _ modules/vue/dist/vue . js " & gt;& lt/script & gt;& lt!-定义模板->;& ltdiv id = " app " & gt& lt示例:tags="['h1 ',' h2 ',' H3 ']" & gt;& lt/example & gt;& lt/div & gt;& lt脚本& gt//定义示例组件vue.component ('example ',{props: ['tags'],render(h){//第二个参数是包含模板相关属性的数据对象,可选参数//VNodes参数可以传入字符串或数字。//由createElement生成,可选参数返回h ('div ',this.tags.map ((tag,I)= >;H (tag,I))} })//实例化new vue({ El:' # app ' })</script & gt;示例2:实现动态

要求如下

实现一个 Foo 组件渲染 <div>foo</div> ,实现一个 Bar 组件渲染 <div>bar</div> 。实现一个 <example> 组件,根据属性 ok 动态渲染 Foo 组件或者 Bar 组件。如果属性 ok 是 true ,那么最终的渲染应该是 <div>foo</div> 。实现一个按钮控制属性 ok ,通过这个属性让 <example> 在 Foo 或者 Bar 之间切换。

根据上述要求,调用

实施如下

& lt!-quote-->:& lt;脚本src= "../node _ modules/vue/dist/vue . js " & gt;& lt/script & gt;& lt!-定义模板->;& ltdiv id = " app " & gt& lt!-绑定属性ok-->:& lt;示例:ok = " ok " & gt& lt/example & gt;& lt!-绑定点击事件->:& lt;button @click="ok =!ok " & gt切换& lt/button & gt;& lt/div & gt;& lt脚本& gt//定义foo const foo = { render(h){ return h(' div ',' foo ')} }//定义Bar const Bar = { render(h){ return h(' div ',Bar')}} //定义示例组件//动态切换vue.com组件(' example ',{props: ['ok'],render (h) {return h (this.ok?o:bar)} })//实例化newvue ({El:' # app ',data:{ OK:true } })</script & gt;示例3:实现组件

要求如下

实现一个 withAvatarURL 函数,要求传入一个带有 url 属性的组件,返回一个接收 username 属性的高阶组件,这个高阶组件主要负责获取相应的头像URL。在API返回之前,高阶组件将占位符URL http://via.placeholder.com/200x200 传递给内部组件。

例子如下

constsmart avatar = with avatar URL(avatar)//使用此方法& lt/smart-avatar & gt;//替换以下方式& lt/avatar & gt;AvatarURL函数返回一个对象,接收username属性,并获取所创建的生命周期中的头像URL。Avatar对象接收src属性,src的内容从withAvatarURL获取,然后显示在。实例化时,传入新定义的组件名SmartAvatar。

实施如下

<!--引用--><script src="../node_modules/vue/dist/vue.js"></script><!--定义template--><div id="app"> <smart-avatar username="vuejs"></smart-avatar></div><script> // 获取头像URL function fetchURL (username, cb) { setTimeout(() => { // 获取头像并回传 cb('https://avatars3.githubusercontent.com/u/6128107?v=4&s=200') }, 500) } // 传递的InnerComponent const Avatar = { props: ['src'], template: `<img :src="src">` } function withAvatarURL (InnerComponent) { return { props: ['username'], inheritAttrs: false, // 2.4 only,组件将不会把未被注册的props呈现为普通的HTML属性 data () { return { url: null } }, created () { // 获取头像URL并回传给this.url fetchURL(this.username, url => { this.url = url }) }, render (h) { return h(InnerComponent, { attrs: this.$attrs, // 2.4 only,获取到没有使用的注册属性 props: { src: this.url || 'http://via.placeholder.com/200x200' } }) } } } const SmartAvatar = withAvatarURL(Avatar) // 实例化,新构造组件名为SmartAvatar或smart-avatar new Vue({ el: '#app', components: { SmartAvatar } })</script>& lt!-quote-->:& lt;脚本src= "../node _ modules/vue/dist/vue . js " & gt;& lt/script & gt;& lt!-定义模板->;& ltdiv id = " app " & gt& ltsmart-avatar username = " vue js " & gt;& lt/smart-avatar & gt;& lt/div & gt;& lt脚本& gt//Get头像URL函数fetch URL (username,CB){ settimeout(()= >;{//获取头像并发送回CB(' https://avatar S3 . githubusercontent . com/u/6128107?v = 4 & ampS=200') },500)} //传递的inner component const avatar = { props:[' src '],template:` ;{ this.url = url }) },render(h){ return h(inner component,{ attrs: this。$attrs,// 2.4 only,获取未使用的注册属性props:{ src:this . URL | | ' http://via.placeholder.com/200x200'}}}} const smart avatar = with Avatar URL(Avatar)//实例化,新建的建筑组件命名为Smart Avatar或Smart-Avatar Newvue ({El:' # app ',components: {Smart Avatar}})

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。

作者:美站资讯,如若转载,请注明出处:https://www.meizw.com/n/221046.html

发表回复

登录后才能评论