精华内容
下载资源
问答
  • vue 渲染流程
    2021-08-15 12:42:47

    vue 渲染流程

    注意:以下代码都是关键代码,由本人手写并经过测试 ~ 并非直接down的源码。

    使用方式

    既然我们已经使用很多次vue了,那vue的使用方式大家一定不陌生。

    假设我们在html中引入了打包好的vue.js文件,代码如下:在这个new Vue的构造函数中,我们传入了一个对象,对象的属性包括了data、el、mounted三个属性。今天只考虑这三个属性如何正确的渲染出来。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>My-Vue</title>
    </head>
    <body>
        <div id="app" class="app">hello<span class='12312'>{{a.name}}</span>{{b}}</div>
    
        <script src="/dist/umd/vue.js"></script>   
        <script> 
        let vm = new Vue({
            el:'#app',
            data(){return{a:{name:'张三'},b:[[1],0]}},
            // template:"hello<span class='12312'>{{name}}</span>",
            mounted(){
    			console.log('mounted')
    		}
        })
        console.log('1234444444',vm.$el.innerHTML )
        setTimeout(()=>{
            vm.a.name = '李四';
            vm.b.push(5)
            vm.b[0].push(2)
        },1200)
        </script>
    </body>
    </html>
    

    从我们调用vue的方式来看,能得到一个关键的信息,也就是这个暴露出来的Vue,它是一个函数。否则不能用new来调用。

    那这个vue函数是怎么样的呢?

    且听我细细道来~

    Vue 函数及原型方法

    vue是一个函数当然也是对象,对象是有原型的,原型上有很多方法,当我们new一个实例的时候,这个实例就能够获取构造函数原型上的方法。这时候就像子类可以继承父类的方法一样,就可以使用vue原型上的方法。这与js原型链的机制息息相关~

    在vue暴露出去之前,他会往他的原型上挂载很多方法,以供在需要的时候直接使用。那他都会挂在哪些方法呢?

    比如说我们的初始化init方法、返回vdom的render方法,进行渲染的mount方法以及update更新DOM的方法等等。这里只列举了下文可能会涉及的一些方法。

    事实上,在VUE的源码中,不同用途的函数会进行分门别类的挂载。

    如下,与初始化相关的函数,由initMixin()来完成挂载。与生命周期相关的函数由lifecycleMixin来完成挂载,等等~

    这些mixin函数的根本操作就是 Vue.prototype.XXX = function (){ // *****},也就是往Vue上挂载很多方法。

    当我们把Vue函数暴露出去的时候,他的原型已经有了我们需要的全部方法。

    // 定义Vue函数
    function Vue(options) {
        // 初始化操作
        this._init(options);
    }
    debugger
    // 给Vue原型上添加方法
    initMixin(Vue)
    renderMixin(Vue)
    lifecycleMixin(Vue)
    // 等等其他功能的函数
    

    渲染流程1、 调用init() 初始化

    这个时候,我们new Vue() 执行 this._init(),这里的_init 其实就是在initMixin中进行挂载的。

    initMixin函数的关键代码如下。

     function initMixin(Vue){
        // 初始化方式
        Vue.prototype._init = function (options){
            const vm = this
            vm.$options = mergeOptions(vm.constructor.$options || {},options)
            vm._self = vm
            initLifecycle(vm)
            initEvents(vm)
            initRender(vm)
            callHook(vm, 'beforeCreate')
            initInjections(vm) // resolve injections before data/props
            initState(vm)
            initProvide(vm) // resolve provide after data/props
            callHook(vm, 'created')
            
            // 如果用户传入了el属性,需要将页面渲染出来
            vm.$options.el && vm.$mount(vm.$options.el)
        }
    }
    

    构造函数,也就是new的时候调用_init,就是这里挂载到vue上的_init。

    init做的三件事:(这里只简单介绍哈~)

    1、合并options ,vue的原型继承策略并不能很好的满足我们,因为在很多情况下,我们不是当前对象找不到就使用继承属性。而是有策略在的,举一个例子,vue的生命周期事件,当前对象和原型链上都有,但是不是当前对象有就不去取原项链的方法了,他是要依次执行两个方法。所以这一步确保每一个options 都正确且合理。

    2、各模块的初始化 。这里同样包括很多初始化,比如生命周期、渲染、数据等等初始化。我们今天很多不会涉及到。这里比较重要的一点就是数据的初始化。也就是 initState(),这一块我们会将data数据创建成响应式数据。这样我们在修改了数据之后,就可以看到dom自动更新啦。详细可以看:Vue的响应式原理

    3、调用mount函数渲染。

    渲染流程2 调用$mount() 挂载

    $mount的函数在不同的打包方式下是不一样的。这里我们已编译版本的为例进行介绍。(编译版本就是我们写的时候要写template 运行时版本就是写render函数的那一种)。

     Vue.prototype.$mount = function (el){
            const vm = this;
            const {render,template} = this.$options;
            let myRender  = render;
            if(!render){
                let myTemplate = template;
                if(!template){
                    const dom = document.querySelector(el)
                    vm.$options.$el = dom;
                    if(dom){
                        myTemplate = dom.outerHTML
                    }
                }
                // template 转 render
                myRender = compileToFunction(myTemplate)
                this.$options.render = myRender;
            }
            
            // 渲染当前的组件
            mountComponent(vm,el)
      }
    
    function mountComponent (
        vm,
        el
      ) {
        vm.$el = el;
        if (!vm.$options.render) {
          vm.$options.render = createEmptyVNode;
        }
        // 拿到render函数之后,进行beforemount
        callHook(vm, 'beforeMount');
        // HACK: 平台相关 
        var updateComponent;
        updateComponent = function () {
            // vm._render() 返回虚拟dom
            // vm._update() 虚拟dom生成真实的dom
            console.log('-------更新------')
            vm._update(vm._render());
        };
        
        // 渲染watcher   
        new Watcher(vm, updateComponent, ()=>{}, null, true /* isRenderWatcher */);
      
        // NOTE: 组件更新原理
        // watcher 用来渲染的 
        // updateComponent  创建真实的dom
        if (vm.$vnode == null) {
          vm._isMounted = true;
          callHook(vm, 'mounted');
        }
        return vm
    }
      
    

    挂载dom的核心逻辑就是:
    1、有render函数吗 ? 如果有直接使用 , 如果没有,找到template通过 vue 模板编译 转成 render函数。这个render函数会在下边执行_render的时候执行并返回dom对应的vdom;
    2、有了render函数 ,调用组件渲染 。这个函数呢,会new一个watcher ,在new的当下执行 updateComponent 调用update更新一次dom,往后当data发生改变时继续执行update更新dom,这样就做到了响应式。所以当我们在后边改vm的数据的时候,就会更新dom.张三变成李四。

    后续

    这只是Vue的核心渲染流程。至于他是怎么响应式的,是怎么编译的,又是怎么进行的组件的渲染的,dom的更新策略是什么 等等
    这些东西且听我下次讲解~

    更多相关内容
  • 二、Vue 页面渲染过程

    2020-12-21 13:31:23
    我也是刚刚接触,所以就会有这样的困惑,所以这篇就简单的理解一下项目页面渲染的过程。渲染过程我们上篇文章说main.js 是无用的,是废代码,只是起到支撑框架的。但是其实我们应该有感觉,把他删...

    前言

    上篇博文我们依葫芦画瓢已经将hello world 展现在界面上啦,但是是不是感觉新虚虚的,总觉得这么多文件,项目怎么就启动起来了呢?怎么访问到8080 端口就能进入到我们的首页呢。整个的流程是怎么样的呢?

    我也是刚刚接触,所以就会有这样的困惑,所以这篇就简单的理解一下项目页面渲染的过程。

    渲染过程

    我们上篇文章说main.js 是无用的,是废代码,只是起到支撑框架的。但是其实我们应该有感觉,把他删除了整个项目就跑步起来了。其实main.js 算是项目的入口了。我们就从这个文件看起。

    import Vue from 'vue'

    import App from './App'

    import router from './router'

    Vue.config.productionTip = false

    new Vue({

    el: '#app',

    router,

    components: { App },

    template: ''

    })

    可以看到代码非常的少,就导入了vue.js、我们的APP.vue 以及index.js

    第一次做动图,操作像是老年人,大家见谅。上图可以大概的看到引入的三个文件是什么了。

    Vue.config.productionTip = false 我们这里暂时不管,知道是一个配置信息就可以了,感兴趣的可以百度一下就知道什么意思了。

    new Vue({

    el: '#app',

    router,

    components: { App },

    template: ''

    })

    上面这些,如果完全没有vue 语法知识的话,确实不知道什么意思,但是我们看官网教程,起步的时候都是在当个html 文件中使用vue 的。在js 中就会用到这个。

    可以看到,其实都是差不多的,所以这里的作用就是实例化一个Vue。当然我们项目中,这里是为整个项目实例化了一个Vue ,el 指定的元素,这里就是我们index.html 中的div啦。

    router 就指定路由,也就是我们在index.js 配置的路由信息。

    components 指定的组件信息。项目有一个父组件就是APP.vue。我们自己写的所有组件都是在这个父组件之下的。

    怎么说呢,也就是说所有的界面,最外层的div 就是APP.vue 定义的。div 中其他的div 才是我们自己写的。看下面这个应该就会有所感觉吧。

    所以这里我们就可以解答上篇文章,为什么我们只是写了一个hello world 。但是为什么界面上呈现的会有图标,还有样式。因为在APP.vue 中设置了这些动洗。我们APP.vue 中的这些内容注释掉就可以看到效果。

    我们将APP.vue logo和样式去掉,再来看看内容

    export default {

    name: 'App'

    }

    是不是发现和我们在组件中自己写的Hello.vue 格式完全一样,哈哈没错,vue文件就是这样的格式。可以看到template 渲染的是id 为app 的盒子(div)。这里应该是覆盖了index.html中的d 也为app 的盒子。

    所有的 router-view 中的内容,都会被自动替换。

    script 中的代码则是脚本代码。

    至此,整个过程就出来了:项目启动首先会读取main.js 。实例化一个vue,然后渲染APP.vue 文件内容,我们自己写的vue 组件则是通过路由转接到父组件下的。

    番外

    我们项目的流程就讲到这里把,算是对上篇的补充,让我们对项目启动,界面渲染算是有一个大概的了解啦,我们接下来就按照官网上讲一下vue 的一些语法和特性,但是与官网上不同的是,官网上都是一个个的html,而我们就在这个项目的基础的上。将会是一个个的vue 文件。

    后续加油♡

    欢迎大家关注个人公众号 "程序员爱酸奶"

    分享各种学习资料,包含java,linux,大数据等。资料包含视频文档以及源码,同时分享本人及投递的优质技术博文。

    如果大家喜欢记得关注和分享哟❤

    展开全文
  • html:组件渲染的基本过程main.js:import Vue from "vue";import Home from "./home.vue";new Vue({el: "#app",template: "",components: { Home }});home.vue{{text}}export default {name: "home",data() {return...

    html:

    组件渲染的基本过程

    main.js:

    import Vue from "vue";

    import Home from "./home.vue";

    new Vue({

    el: "#app",

    template: "",

    components: { Home }

    });

    home.vue

    {{text}}

    export default {

    name: "home",

    data() {

    return {

    text: '测试'

    };

    },

    mounted() {

    },

    methods: {

    }

    };

    1.项目运行编译时,home.vue中的template会被vue-loader编译成render函数,并添加到组件选项对象里。组件通过components引用该组件选项,创建组件(Vue实例),渲染页面(组件被多次引用时,引用的是相同的组件选项,解释data为什么要是函数)。main.js根组件template转化成render函数是由vue插件中的编译器实现的。

    // 编译器生成的render函数:

    var render = function() {

    var _vm = this

    var _h = _vm.$createElement

    var _c = _vm._self._c || _h

    return _c(

    "div",

    { staticClass: "home" },

    [

    _c("a",

    [_vm._v(_vm._s(_vm.text))]

    )

    ]

    )

    }

    // 编译后的组件选项对象:

    {

    beforeCreate: []

    beforeDestroy: []

    data: function() {}

    methods: {}

    mounted: function() {}

    name: "home"

    render: function() {}

    staticRenderFns: []

    __file: "src/page/home/index.vue"

    _compiled: true

    }

    2.组件渲染页面时会先调用render函数,render函数返回组件内标签节点(VNode实例)。每个标签(包括文本和组件标签等)会创建一个节点,先创建子标签的节点,再父节点创建时将它添加父节点的children数组中,形成与标签结构相同的树形结构。

    // 虚拟节点构造函数

    var VNode = function VNode (

    tag,

    data,

    children,

    text,

    elm,

    context,

    componentOptions,

    asyncFactory

    ) {

    this.tag = tag;// 标签名

    this.data = data;// 节点数据(原生事件信息),包括节点的钩子函数(包含标签上数据的钩子函数,例如:指令)

    this.children = children;// 当节点是原生标签节点,保存它的子节点

    this.text = text;// 为文本节点或者注释节点时的文本内容

    this.elm = elm;// 节点对应的DOM,组件节点则对应的是该组件内原生根标签DOM

    this.ns = undefined;

    this.context = context;// 节点对应标签所在的组件(组件内包含该标签)

    this.fnContext = undefined;

    this.fnOptions = undefined;

    this.fnScopeId = undefined;

    this.key = data && data.key;// key值

    this.componentOptions = componentOptions;// 缓存组件标签信息:包括组件名称,组件选项、标签上的props、标签上的事件、以及组件标签内的子节点。

    this.componentInstance = undefined;// 组件标签节点对应的组件(Vue实例)

    this.parent = undefined;// 当节点是组件内根标签节点,保存它的组件标签节点

    this.raw = false;

    this.isStatic = false;

    this.isRootInsert = true;

    this.isComment = false;

    this.isCloned = false;

    this.isOnce = false;

    this.asyncFactory = asyncFactory;

    this.asyncMeta = undefined;

    this.isAsyncPlaceholder = false;

    };

    // 调用render函数,生成组件模板对应的节点

    Vue.prototype._render = function () {

    var vm = this;

    var ref = vm.$options;

    var render = ref.render;

    var _parentVnode = ref._parentVnode;

    ...

    vm.$vnode = _parentVnode;

    // render self

    var vnode;

    ...

    currentRenderingInstance = vm;

    vnode = render.call(vm._renderProxy, vm.$createElement);//返回组件模板形成节点(组件内根标签节点)

    ...

    currentRenderingInstance = null;

    ...

    vnode.parent = _parentVnode;// 设置组件根标签节点的parent为当前组件节点。

    return vnode

    };

    // 根据标签创建节点

    function _createElement (

    context,

    tag,

    data,

    children,

    normalizationType

    ) {

    if (isDef(data) && isDef((data).__ob__)) {

    ...

    return createEmptyVNode()

    }

    ...

    if (!tag) {

    return createEmptyVNode()

    }

    ...

    if (typeof tag === 'string') {

    vnode = new VNode(

    config.parsePlatformTagName(tag), data, children,

    undefined, undefined, context

    );

    } else if ((!data || !data.pre) && isDef(Ctor = resolveAsset(context.$options, 'components', tag))) {/* 从组件实例option的components中寻找该标签对应的组件选项 */

    vnode = createComponent(Ctor, data, context, children, tag);// 组件标签节点

    } else {

    vnode = new VNode(

    tag, data, children,

    undefined, undefined, context

    );

    }

    } else {

    vnode = createComponent(tag, data, context, children);// 标签节点

    }

    if (Array.isArray(vnode)) {

    return vnode

    } else if (isDef(vnode)) {

    if (isDef(ns)) { applyNS(vnode, ns); }

    if (isDef(data)) { registerDeepBindings(data); }

    return vnode

    } else {

    return createEmptyVNode()

    }

    }

    3.如果标签是组件标签,通过components获取的组件选项,并使用extend方法生成组件的构造函数,将构造函数和组件选项保存在组件标签节点上。

    4.render函数生成组件内标签节点,并设置根节点的parent指向组件节点。将节点作为新节点,传入到patch方法中,组件页面初始更新时,不存在旧节点,直接根据新节点创建DOM。

    // 组件页面更新

    Vue.prototype._update = function (vnode, hydrating) {

    var vm = this;

    var prevEl = vm.$el;

    var prevVnode = vm._vnode;

    var restoreActiveInstance = setActiveInstance(vm);

    vm._vnode = vnode;

    ...

    if (!prevVnode) {// 组件初次渲染

    // initial render

    vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false /* removeOnly */);// 将组件内根标签DOM赋值给实例的$el属性

    } else {

    // updates

    vm.$el = vm.__patch__(prevVnode, vnode);// 将组件内根标签DOM赋值给实例的$el属性

    }

    restoreActiveInstance();

    ...

    };

    5.在patch方法中,根据节点创建DOM,并在节点上保存它的DOM引用,再根据节点的children值,创建子节点的DOM,再添加到父节点的DOM中,完成组件的渲染。

    // 根据节点类型(原生标签或者组件标签),创建组件或者DOM

    function createElm (

    vnode,

    insertedVnodeQueue,

    parentElm,

    refElm,

    nested,

    ownerArray,

    index

    ) {

    ...

    vnode.isRootInsert = !nested; // for transition enter check

    if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) {// 如果vnode是组件节点,创建组件

    return

    }

    var data = vnode.data;

    var children = vnode.children;

    var tag = vnode.tag;

    if (isDef(tag)) {

    ...

    vnode.elm = vnode.ns // 创建DOM

    ? nodeOps.createElementNS(vnode.ns, tag)

    : nodeOps.createElement(tag, vnode);

    setScope(vnode);// 添加DOM属性,构造css作用域

    {

    createChildren(vnode, children, insertedVnodeQueue);// 创建子节点的DOM

    if (isDef(data)) {

    invokeCreateHooks(vnode, insertedVnodeQueue);

    }

    insert(parentElm, vnode.elm, refElm);// 添加父节点的DOM中

    }

    ...

    } else if (isTrue(vnode.isComment)) {// 注释节点

    vnode.elm = nodeOps.createComment(vnode.text);

    insert(parentElm, vnode.elm, refElm);// 添加DOM

    } else {// 文本节点

    vnode.elm = nodeOps.createTextNode(vnode.text);

    insert(parentElm, vnode.elm, refElm);// 添加DOM

    }

    }

    6.在根据节点创建DOM的过程中,如果节点包含组件构造器信息(即是组件节点),会先使用构造器创建组件,调用组件render方法,执行以上操作,生成组件内标签对应的节点,再根据节点生成DOM,并将根标签节点的DOM保存在组件上,然后添加到父节点的DOM上,完成组件的渲染。DOM添加到页面的过程是从下往上依次添加,DOM添加到父级DOM中,父级DOM添加到它的父级DOM中,迭代添加,最后将最上级的DOM添加到页面。

    // 生成组件,并将组件内根标签DOM添加到父级DOM中:

    function createComponent (vnode, insertedVnodeQueue, parentElm, refElm) {

    var i = vnode.data;

    if (isDef(i)) {

    var isReactivated = isDef(vnode.componentInstance) && i.keepAlive;

    if (isDef(i = i.hook) && isDef(i = i.init)) {

    i(vnode, false /* hydrating */);// 调用节点钩子函数init,生成组件

    }

    if (isDef(vnode.componentInstance)) {

    initComponent(vnode, insertedVnodeQueue);

    insert(parentElm, vnode.elm, refElm);// 组件内根标签DOM添加到父级DOM中

    if (isTrue(isReactivated)) {

    reactivateComponent(vnode, insertedVnodeQueue, parentElm, refElm);

    }

    return true

    }

    }

    }

    // 在节点钩子函数init创建组件

    function init (vnode, hydrating) {

    ...

    var child = vnode.componentInstance = createComponentInstanceForVnode(// 创建组件

    vnode,

    activeInstance// 父组件

    );

    child.$mount(hydrating ? vnode.elm : undefined, hydrating);//渲染页面

    }

    展开全文
  • Vue渲染过程浅析

    2020-12-21 13:31:04
    从模板到真实dom节点还需要经过一些步骤把模板编译为render函数实例进行挂载, 根据根节点render函数的调用,递归的生成虚拟dom对比虚拟dom,渲染到真实dom组件内部data发生变化,组件和子组件引用data作为props重新...

    Vue 推荐在绝大多数情况下使用 template 来创建你的 HTML。但是模板毕竟是模板,不是真实的dom节点。从模板到真实dom节点还需要经过一些步骤

    把模板编译为render函数

    实例进行挂载, 根据根节点render函数的调用,递归的生成虚拟dom

    对比虚拟dom,渲染到真实dom

    组件内部data发生变化,组件和子组件引用data作为props重新调用render函数,生成虚拟dom, 返回到步骤3

    第一步: 模板到render

    在我们使用Vue的组件化进行开发应用的时候, 如果仔细的查看我们要引入的组件, 例子如下

    // App.vue

    hello word

    export default {

    }

    在我们的主入口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/...

    这样,能保证组件每次调用的都是render函数,使用render函数生成VNode。

    第二步:虚拟节点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

    export default {

    render: (h) => {

    let app = h('h1', ['hello world'])

    console.log('app:', app)

    return app

    }

    }

    我们可以看到,当main.js中重新触发render函数的时候,render方法里面有引用App.vue这个子组件。但是并没有触发App.vue组件的的render函数。

    在一个组件内,什么情况会触发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

    export default {

    props: {

    status: Boolean

    },

    render: function (h){

    const { status } = this

    let app = h('h1', ['hello world'])

    console.log('app:', app)

    return app

    }

    }

    截图如下:

    在main.js中 state状态发生了变化,由false => true, 触发了自身与子组件的render方法。

    补充

    上面的内容是本人的一些使用心得,由于水平有限, 内容有些错误或者表达不当。多欢迎大神来指导

    展开全文
  • Vue中DOM渲染的过程

    2020-12-30 18:30:54
    vue中dom渲染过程1、响应式监听data属性的getter setter2、模板编译模板到render函数再到vnode。模板不是html,有指令、插值、js表达式,能够实现循环、判断。html是标签语言,只有js才能实现循环判断。因此,模板...
  • 今天对这个问题做一个总结一、Vue的初始化我们在使用Vue.js的时候,最基本的一个使用,就是在HTML引入Vue.js的库文件,并写如下一段代码:1.var app = new Vue({2. el: '#app',3. data: {4. message: 'Hello Vue!'5....
  • vue渲染页面原理

    2021-10-18 19:04:29
    vue代码前后各console.log一次渲染的元素会得到: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, ...
  • vue页面渲染过程

    千次阅读 2020-11-11 08:25:51
    本文主要介绍Vue页面渲染过程 首先vue会找到webpack的打包配置文件。在build/webpack.base.conf.js下:在这里,定义了vue的程序入口文件 vue加载时文件的执行顺序 执行index.html文件 执行main.js文件 main....
  • html:组件页面渲染的基本流程main.js:import Vue from "vue";import Home from "./home.vue";new Vue({el: "#app",template: "",components: { Home }});home.vue{{text}}export default {name: "home",data() {...
  • Vue3.0 渲染流程(一)

    2021-01-19 08:31:09
    我们先从一个最简单的例子来分析渲染流程: ​ <html> <head> <style type="text/css"> </style> </head> <body> <div id="app"> <div>hello {{state....
  • 把模板中的Vue指令(v-for、v-model等)都变成了JS逻辑 最终,在with函数传入模板作为参数,返回render函数,render函数最终返回Vnode对象。 <div id="app"> <div> <input type="text" v-model=...
  • vue组件渲染过程

    2022-02-18 11:32:14
    虚拟DOM也就是我们常说的虚拟节点,他是通过JS的Object对象模拟DOM中的节点,然后在通过特定的render方法将其渲染成真实的DOM节点。 为什么要使用虚拟节点? 频繁的DOM操作会导致大量页面元素的重绘和回流,处于...
  • jQuery中可以这样写 ...以上所述是小编给大家介绍的Vue.js在页面加载时执行某个方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对软件开发网网站的支持!
  • 一、前言最近一直在使用vue做项目,闲暇之余查阅了一些关于vue实现原理的资料,一方面对所了解到的知识做个总结,另外一方面希望能对看到此文章的同学有所帮助。本文如有不足之处,还请过往的大佬批评指正。二、vue...
  • render函数的主要功能是生成vnode。在vue渲染过程中总共涉及两大工作:创建vnode...生成vnode大家知道一个复杂的页面会包含大量的DOM节点,为了高效地更新这些DOM节点,vue设计了虚拟DOM的概念。虚拟DOM是对真实DO...
  • 1、初次渲染过程 模板字符串被解析成render函数, 一般这一步在开发环境就已经完成了。 触发响应式,监听data 执行render函数,生成vnode,然后patch(ele,vnode) 执行render函数的时候,回去获取data中的数据...
  • Vue 是一个新兴的前端视图框架,与 React 类似,实现了前端组件化以及 View-ViewModel 绑定,但是同时又支持跟 Angular 很类似的模版语法,虽然有很多类似的地方,但两者也有很多不同,下面简述两者在渲染流程方面...
  • 2.Comment(注释类型) 匹配到Comment类型Vnode 调用processCommentNode函数 如果n1不存在,则执行插入工作 否则直接新的覆盖旧的,因为注释节点并不需要在页面中进行展示,不必做多余的渲染工作 3.Static(静态...
  • Vue 首次渲染的过程

    2021-11-13 17:20:30
    二,Vue 初始化过程 1,首先取出 Vue 的 $mount 进行重写,给 $mount 增加新的功能 // src/platform/web/entry-runtime-with-compiler.js // 保留 Vue实例的 $mount 方法 const mount = Vue.prototype.$mount ...
  • 本文主要是讲述 Vue.js 3.0 中一个组件是如何转变为页面中真实 DOM 节点的。对于任何一个基于 Vue.js 的应用来说,一切的故事都要从应用初始化「根组件(通常会命名为 APP)挂载到 HTML 页面 DOM 节点(根组件容器)...
  • 本文转载自 http://blog.csdn.net/generon/article/details/72482844 ,看过之后觉得,实在太精彩了一、前言Vue.js框架是目前比较火的MVVM框架...前不久Vue.js 2.0正式版已出,在体积优化(相比1.0减少了50%)、性能提...
  • Vue 3.0组件的渲染流程

    2021-08-08 16:59:03
    Vue简单易上手,只需要简单的文档说明就能上手开发。虽然本人也有一直使用Vue 2.0的项目开发经验,以前也只了解一点核心代码逻辑,没有全面阅读过Vue 2.0的源码。Vue 3.0发布后我也有了一些Vue 3.0项目使用经验,...
  • vue 异步渲染

    2021-04-29 22:05:46
    vue 异步渲染 昨天遇到一个事,项目里之前的同事留下了一个定时器,在ajax请求后,接了个定时器,异步调用,保证数据全部接受后再渲染数据,然后被组长看到了,把我们说了一顿,叫我们把前端代码里遇到的所有定时器...
  • 在工作中,有次遇到要把返回的字符串分割成两部分,一部分用另外的样式显示。...不过后面单独为自动添加的标签(span)设定需要的css样式时(直接在vue页面的css区域加的样式),并没有起作用,浏览器检查元素s...
  • # Vue.js 服务器端渲染指南注意本指南需要最低为如下版本的 Vue,以及以下 library 支持: vue & vue-server-renderer 2.3.0+vue-router 2.5.0+vue-loader 12.0.0+ & vue-style-loader 3.0.0+如果先前已经...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 18,420
精华内容 7,368
关键字:

vue渲染页面的流程