这篇文章主要为大家详细介绍了Vue渲染过程浅析,具有一定的参考价值,可以用来参考一下。
感兴趣的小伙伴,下面一起跟随四海网的小编两巴掌来看看吧!
Vue 推荐在绝大多数情况下使用 template 来创建你的 HTML。但是模板毕竟是模板,不是真实的dom节点。从模板到真实dom节点还需要经过一些步骤
在我们使用Vue的组件化进行开发应用的时候, 如果仔细的查看我们要引入的组件, 例子如下
代码如下:
// App.vue
<template>
<div>
hello word
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
在我们的主入口main.js
代码如下:
import Vue from 'vue'
import App from './App'
console.log(App)
new Vue({
render: h => h(App)
}).$mount('#app')
【图片暂缺】
我们能够看到在我们引入的App这个模块,里面是一个对象,对象里面存在一个方法叫做render。在说render函数之前,我们可以想一想,每一次加载一个组件,然后对模板进行解析,解析完后,生成Dom,挂载到页面上。这样会导致效率很低效。而使用Vue-cli进行组件化开发,在我们引入组件的后,其实会有一个解析器(vue-loader
)对此模板进行了解析,生成了render函数。当然,如果没有通过解析器解析为render函数,也没有关系,在组件第一次挂载的时候,Vue会自己进行解析。源码请参考: https://github.com/vuejs/vue/blob/dev/src/platforms/web/entry-runtime-with-compiler.js
这样,能保证组件每次调用的都是render函数,使用render函数生成VNode。
我们把Vue的实例挂载到#app
, 会调用实例里面的render方法,生成虚拟DOM。来看看什么是虚拟节点,把例子修改一下。
代码如下:
new Vue({
render: h => {
let root = h(App)
console.log('root:', root)
return root
}
}).$mount('#app')
【图片暂缺】
上面生成的VNode就是虚拟节点,虚拟节点里面有一个属性elm
, 这个属性指向真实的DOM节点。因为VNode指向了真实的DOM节点,那么虚拟节点经过对比后,生成的DOM节点就可以直接进行替换。
这样有什么好处呢?
一个组件对象,如果内部的data
发生变化,触发了render函数,重新生成了VNode节点。那么就可以直接找到所对应的节点,然后直接替换。那么这个过程只会在本组件内发生,不会影响其他的组件。于是组件与组件是隔离的。
例子如下:
代码如下:
// main.js
const root = new Vue({
data: {
state: true
},
mounted() {
setTimeout(() => {
console.log(this)
this.state = false
}, 1000)
},
render: function(h) {
const { state } = this // state 变化重新触发render
let root = h(App)
console.log('root:', root)
return root
}
}).$mount('#app')
代码如下:
// App.vue
<script>
export default {
render: (h) => {
let app = h('h1', ['hello world'])
console.log('app:', app)
return app
}
}
</script>
【图片暂缺】
我们可以看到,当main.js
中重新触发render函数的时候,render方法里面有引用App.vue这个子组件。但是并没有触发App.vue组件的的render函数。
在一个组件内,什么情况会触发render?
。
数据劫持是Vue的一大特色,原理官方已经讲的很多了深入响应式原理。在我们给组件的data的属性进行的赋值的时候(set),此属性如果在组件内部初次渲染过程被引用(data的属性被访问,也就是数据劫持的get
), 包括生命周期方法或者render方法。于是会触发组件的update(beforeUpdate -> render -> updated)。
注: 为了防止data被多次set从而触发多次update, Vue把update存放到异步队列中。这样就能保证多次data的set只会触发一次update。
当props会触发组件的重新渲染是怎么发生的呢?
把父组件的data通过props传递给子组件的时候,子组件在初次渲染的时候生命周期或者render方法,有调用data相关的props的属性, 这样子组件也被添加到父组件的data的相关属性依赖中,这样父组件的data在set的时候,就相当于触发自身和子组件的update。
例子如下:
代码如下:
// main.vue
import Vue from 'vue'
import App from './App'
const root = new Vue({
data: {
state: false
},
mounted() {
setTimeout(() => {
this.state = true
}, 1000)
},
render: function(h) {
const { state } = this // state 变化重新触发render
let root = h(App, { props: { status: state } })
console.log('root:', root)
return root
}
}).$mount('#app')
window.root = root
代码如下:
// App.vue
<script>
export default {
props: {
status: Boolean
},
render: function (h){
const { status } = this
let app = h('h1', ['hello world'])
console.log('app:', app)
return app
}
}
</script>
截图如下:
【图片暂缺】
在main.js
中 state 状态发生了变化,由false
=> true
, 触发了自身与子组件的render方法。
上面的内容是本人的一些使用心得,由于水平有限, 内容有些错误或者表达不当。多欢迎大神来指导!!!
这是由于浏览器的渲染机制导致的,浏览器是从头到尾 如果你的js引用在底部,那么浏览器会先加载dom此时,你用于渲染的{{}}识别符,因为还没读到该识别符对应的js文件,所以会被解析为字符串而显示在页面中,我们可以用过自定义属性v-cloak解决,
实例对象对应标签中加入 v-cloak:
代码如下:
<div id="wrap" v-cloak>
然后在css中给定义属性选择器
代码如下:
[v-cloak]{
display:none
}
vue实例创建完成后会把v-cloak去掉,在没创建实例对象时,该标签内的内容都会被隐藏
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持四海网。
本文来自:http://www.q1010.com/184/6805-0.html
注:关于Vue渲染过程浅析的内容就先介绍到这里,更多相关文章的可以留意四海网的其他信息。
关键词:vue.js
四海网收集整理一些常用的php代码,JS代码,数据库mysql等技术文章。