初始化vue源码对照_vue20源码

hacker|
111

文章目录:

vue问题。。。。。。。

Vue.js 本质就是包含各种逻辑的function,初始化Vue的过程就是实例化的过程。

var vm = new Vue({})

console.log(Vue) 之后控制台输出的是 ƒ hn(e){this._init(e)},可以看出,vue对象的本质就是一个function。

vue DOM中定义的const elm = vnode.elm = oldnode.elm看不懂,求解

Vue版本: 2.3.2

virtual-dom(后文简称vdom)的概念大规模的推广还是得益于react出现,virtual-dom也是react这个框架的非常重要的特性之一。相比于频繁的手动去操作dom而带来性能问题,vdom很好的将dom做了一层映射关系,进而将在我们本需要直接进行dom的一系列操作,映射到了操作vdom,而vdom上定义了关于真实dom的一些关键的信息,vdom完全是用js去实现,和宿主浏览器没有任何联系,此外得益于js的执行速度,将原本需要在真实dom进行的创建节点,删除节点,添加节点等一系列复杂的dom操作全部放到vdom中进行,这样就通过操作vdom来提高直接操作的dom的效率和性能。

Vue在2.0版本也引入了vdom。其vdom算法是基于snabbdom算法所做的修改。

在Vue的整个应用生命周期当中,每次需要更新视图的时候便会使用vdom。那么在Vue当中,vdom是如何和Vue这个框架融合在一起工作的呢?以及大家常常提到的vdom的diff算法又是怎样的呢?接下来就通过这篇文章简单的向大家介绍下Vue当中的vdom是如何去工作的。

首先,我们还是来看下Vue生命周期当中初始化的最后阶段:将vm实例挂载到dom上,源码在src/core/instance/init.js

Vue.prototype._init = function () { ...

vm.$mount(vm.$options.el)

...

}

实际上是调用了src/core/instance/lifecycle.js中的mountComponent方法,

mountComponent函数的定义是:

export function mountComponent ( vm: Component, el: ?Element,

hydrating?: boolean

): Component { // vm.$el为真实的node

vm.$el = el // 如果vm上没有挂载render函数

if (!vm.$options.render) { // 空节点

vm.$options.render = createEmptyVNode

} // 钩子函数

callHook(vm, 'beforeMount') let updateComponent /* istanbul ignore if */

if (process.env.NODE_ENV !== 'production' config.performance mark) { ...

} else { // updateComponent为监听函数, new Watcher(vm, updateComponent, noop)

updateComponent = () = { // Vue.prototype._render 渲染函数

// vm._render() 返回一个VNode

// 更新dom

// vm._render()调用render函数,会返回一个VNode,在生成VNode的过程中,会动态计算getter,同时推入到dep里面

vm._update(vm._render(), hydrating)

}

} // 新建一个_watcher对象

// vm实例上挂载的_watcher主要是为了更新DOM

// vm/expression/cb

vm._watcher = new Watcher(vm, updateComponent, noop)

hydrating = false

// manually mounted instance, call mounted on self

// mounted is called for render-created child components in its inserted hook

if (vm.$vnode == null) { vm._isMounted = true

callHook(vm, 'mounted')

} return vm

}

注意上面的代码中定义了一个updateComponent函数,这个函数执行的时候内部会调用vm._update(vm._render(), hyddrating)方法,其中vm._render方法会返回一个新的vnode,(关于vm_render是如何生成vnode的建议大家看看vue的关于compile阶段的代码),然后传入vm._update方法后,就用这个新的vnode和老的vnode进行diff,最后完成dom的更新工作。那么updateComponent都是在什么时候去进行调用呢?

vm._watcher = new Watcher(vm, updateComponent, noop)

vue是怎么将数据绑定到组件的原理

vue将数据绑定到组件的原理如下:

1、当实例化一个Vue构造函数,会执行 Vue 的 init 方法,在 init 方法中主要执行三部分内容,一是初始化环境变量,而是处理 Vue 组件数据,三是解析挂载组件。以上三部分内容构成了 Vue 的整个执行过程。

2、Vue 实现了一个 观察者-消费者(订阅者) 模式来实现数据驱动视图。通过设定对象属性的 setter/getter 方法来监听数据的变化,而每个属性的 setter 方法就是一个观察者, 当属性变化将会向订阅者发送消息,从而驱动视图更新。

3、Vue 的订阅者 watcher 实现在 /src/watchr.js 。构建一个 watcher 最重要的是 expOrFn 和 cb 两个参数,cb 是订阅者收到消息后需要执行的回调,一般来说这个回调都是视图指令的更新方法,从而达到视图的更新,但是这也不是必须的,订阅回调也可以是一个和任何无关的纯函数。一个订阅者最重要的是要知道自己订阅了什么,watcher 分析 expOrFn 的 getter 方法,从而间接获得订阅的对象属性。

4、Vue 双向数据绑定实现

数据与视图的绑定与同步,最终体现在对数据的读写处理过程中,也就是 Object.defineProperty() 定义的数据 set、get 函数中。Vue 中对于的函数为 defineReactive,在精简版实现中,我只保留了一些基本特性:

function defineReactive(obj, key, value) {

   var dep = new Dep()

   Object.defineProperty(obj, key, {

       enumerable: true,

       configurable: true,

       get: function reactiveGetter() {

           if (Dep.target) {

               dep.depend()

           }

           return value

       },

       set: function reactiveSetter(newVal) {

           if (value === newVal) {

               return

           } else {

               value = newVal

               dep.notify()

           }

       }

   })

}

在对数据进行读取时,如果当前有 Watcher(对数据的观察者吧,watcher 会负责将获取的新数据发送给视图),那将该 Watcher 绑定到当前的数据上(dep.depend(),dep 关联当前数据和所有的 watcher 的依赖关系),是一个检查并记录依赖的过程。而在对数据进行赋值时,如果数据发生改变,则通知所有的 watcher(借助 dep.notify())。这样,即便是我们手动改变了数据,框架也能够自动将数据同步到视图。

请简述什么是vue

vue指的是vue.js框架。Vue.js是一款友好的、多用途的且高性能的js框架,一款构建用户界面的渐进式框架,它可以帮你创建可维护性和可测试性更强的代码库。

Vue.js是一款流行的JavaScript前端框架,一个用于创建用户界面的开源JavaScript框架,旨在更好地组织与简化Web开发。Vue所关注的核心是MVC模式中的视图层,同时,它也能方便地获取数据更新,并通过组件内部特定的方法实现视图与模型的交互。

Vue.js是一套构建用户界面的渐进式框架。与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计。Vue 的核心库只关注视图层,并且非常容易学习,非常容易与其它库或已有项目整合。另一方面,Vue 完全有能力驱动采用单文件组件和Vue生态系统支持的库开发的复杂单页应用。

Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

Vue.js 自身不是一个全能框架——它只聚焦于视图层。因此它非常容易学习,非常容易与其它库或已有项目整合。另一方面,在与相关工具和支持库一起使用时 ,Vue.js 也能完美地驱动复杂的单页应用。

Vue.js是前端的主流框架之一,和Angular.js、React.js 一起,并成为前端三大主流框架!

vue中这句话会重新安装,会初始化其他本地Vue项目吗?

一个不错的开头

1 . 首先全局装vue-cli,它是vue的一个脚手架。

cnpm i -g vue-cli1

2 . 然后进入workspace。执行了如下代码,生成vue项目的初始化工作。这里是基于webpack打包。

vue init webpack learnvue1

3 . 引导定制过程中,测试的选项我全部选了否,完了之后,根据提示,进入learnvue。执行 了

cnpm i1

4 . ok,一切顺利。然后,执行

cnpm run dev

12

5 . ok,打开浏览器跑起来了,正常。

然而

6 . 解决scanning files to index

打开常用的webstorm 10.打开这个learnvue。看到了 scanning files to index。意思是正在扫描文件索引。听起来是项目文件读取的问题。怎么可能要扫描这么长时间。没有大文件呀看于是我放弃这次vue init出来的文件。决定删除它。就在我删除文件的时候,window提示我文件目录结构太深,无法删除。这让我想到了什么,那就是scanning files to index也是这个原因。唯一的就是node_modules。解决 scanning files to index的办法就是在这个node_module文件上右键。mark Directory As Excluded。

重新打开项目。ok!

7 . webtorm的两个vue插件都装了。(vue-for-idea和vue.js)

8 . 解决es 6

当我想愉快地尝试vue的时候,发现script里的代码给我标红了,说我语法错误了。于是在language framework里 解决es 6的问题。并且在vue的script里用type=地text/babel地或者type=地text/ecmascipt-6地什么的,还是描红报错。

4条大神的评论

  • avatar
    访客 2022-07-08 上午 09:05:17

    中主要执行三部分内容,一是初始化环境变量,而是处理 Vue 组件数据,三是解析挂载组件。以上三部分内容构成了 Vue 的整个执行过程。2、Vue 实现了一个 观察者-消费者(

  • avatar
    访客 2022-07-08 上午 07:01:00

    Mount') let updateComponent /* istanbul ignore if */if (process.env.NODE_ENV !== 'pro

  • avatar
    访客 2022-07-08 下午 12:36:49

    还是得益于react出现,virtual-dom也是react这个框架的非常重要的特性之一。相比于频繁的手动去操作dom而带来性能问题,vdom很好的将dom做了一层映射关系,进而将在我们本需要直接进行dom的一系列操作,映射到了操作vdom,而vdom

  • avatar
    访客 2022-07-08 上午 06:27:59

    // manually mounted instance, call mounted on self// mounted is called for render-created child components in its inserted hookif (v

发表评论