专栏首页与前端沾边Vue2 运行原理学习(一)初始化
原创

Vue2 运行原理学习(一)初始化

本次主要跟大家分享学习下 vue2 的部分知识。网上大部分知识讲解都是抽离的形式,对应哪个函数直接拿出来讲解,但是对于新手或者不了解内在原理的,逻辑图谱不是很清晰,不成体系。很容易忘记,所以本次系列计划从零还是手写,实现部分功能。

目前大部分公司还是使用的 2 版本,vue3.2 发布后,还不跟 3.0 兼容。求职应聘也主要是 2.0 为主,所以本次主要学习下 vue2 中的一些功能(后面有机会在整理下 vue3 的实现),例如:响应式实现、模板编译解析、依赖收集等功能的实现,尽量保证大家跟着写可以实现自己的版本,尽量把要点写清,有不对的欢迎指正,没懂的欢迎交流。面后会发布到 github,交流学习。

项目初始化

我们选用 rollup 进行项目启动,这里为什么不用 webpack 呢?

rollup 属于库开发用的,打包体积小,专注打包 jswebpack 当然也是可以的,但是它更适于应用类的,项目类的打包,需要处理 imgcssfont 等,而且打包体积也比较大。

  • npm init -y 初始化项目
  • 安装 rollup
    • npm i rollup rollup-plugin-babel @babel/core @babel/preset-env
    • rollup 打包使用的
    • rollup-plugin-babel 处理 rollup 和 babel 的,打包有的语法需要 babel 转义
    • @babel/core 核心模块,处理逻辑
    • @babel/preset-env 高级语法转换低级语法
  • 配置 rollup.config.js

我们运行按照自己配置的形式执行

import babel from 'rollup-plugin-babel'

export default {
  // 入口文件
  input: './src/index.js',
  // 输出配置
  output: {
    // 输出的文件位置
    file: 'dist/vue.js',
    format: 'umd', // 打包规范,通用打包格式,包含 commonjs ,给node用的;amd 基本没用过;global 形式,声明变量到 window 上
    name: 'Vue', // window.Vue
    sourcemap: true
  },
  plugins: [
    babel({
      exclude: 'node_modules/**' // 打包排除第三方包
    })
  ]
}
  • 配置执行命令
'start': 'rollup -cw' // w 监听文件改变, c 使用配置文件

写几行测试代码,执行命令 npm run start,我们测试一下

/// src/index.js
let a = 123

function Vue(options) {
}

console.log(a, Vue)

export default Vue // 一定要导出

我们写个 html 文件,引入打包后的 js

/// example/example.html
....
<script src="../dist/vue.js"></script>
......
console.log(Vue)  // 可以在浏览器中查看

小节:到这里我们的项目就搭建完成了,主要是配置 rollup 打包,能够在 html 我呢间中访问

Vue 初始化

  1. 注册全局函数
// src/index.js

/**
  当我们 new Vue 时,其实就是初始化我们写的选项,data、props 等
*/

function Vue() {
  // 具体的初始化内容
  this._init()
}

export default Vue

这里我们为什么使用的函数,而不是 类?

因为这里方便我们在原型链上拓展,调用直接 this.xxx,如果写成类了,更多的是使用继承,需要维护比不方便;虽然类本质也是函数,但是很少见用了类再写个原型的,不规范;我们平时拓展也是 Vue.prototype.xxx = xxx,在全局都可以使用。

  1. 定义 _init

因为我们使用函数定义,所以调用原型方法都可以使用 this.xx,但是我们不好每个文件都引入 Vue 函数,去在原型挂载。所以这里我们导出初始化函数给 index.js,把 Vue 传进去,方便维护

//// src/init.js
// 这样我们只需要在 src/index.js 中维护 Vue,
export function initMixin(Vue) {
  Vue.prototype._init = function(options) { // new Vue 参数
    console.log(options)
  }
}


//// example.html 文件中测试
const vm = new Vue({
  data: {
    a: 1,
    b: 2
  }
})
  1. 初始化选项

我们在 init 中主要做两件事,一个是初始化数据,datapropsmethods 等,一个是挂载到 el

//// _init 函数

// 使用 vm ,避免都叫 this,多了分不清
const vm = this
// 初始化属性
initState(vm)

if(options.el) {
  // 有 el 执行挂载
  vm.$mount(options.el)
}
//// src/state.js
export function initState(vm) {
  const options = vm.$options
  
  if (options.data) {
    initData(vm)
  }
  
  if (options.computed) {
    initComputed(vm)
  }
  
  if (options.watch) {
    initWatch(vm)
  }
}

function initData(vm) {}
// 后面去实现
function initComputed(vm) {}
function initWatch(vm) {}
//// init.js
Vue.prototype.$mount = function (el) {
  el = document.querySelector(el)
  const vm = this
  vm.$el = el
  // 后面添加模板解析
}

目前得到的 vm 结构

  1. 代理 vm 数据指向 data

我们平时定义数据都是 this.xxx,访问的 data 中的值,实际上使用的代理

function initData(vm) {
  let data = vm.$options.data // 用户传的 data
  
  // 如果传的是 函数,执行 _data 标识内部属性
  data = vm._data = typeof data === 'function' ? data.call(vm) : data
  
  for(let key in data) {
    proxy(vm, '_data', key)
  }
  
  // 下一篇实现数据响应式**
  observe(data)
}

function  proxy(target, key, property) {
  Object.defineProperty(target, property, {
    get() {
      return target[key][property]
    },
    set(v) {
      target[key][property] = v
    }
  })
}

为什么组件中 data 需要是函数?

其实如果保证组件使用一次,可以不使用函数。但是如果定义的组件被使用多次,如果 data 是对象的话,引用类型,就会相互影响。如果是函数的话,每次执行返回新的对象,不会冲突

本篇介绍了项目搭建和数据的初始化,我们下一篇去实现 vue2 响应式数据的实现,如何递归,怎么处理数组的。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • vue3与vue2的区别之数据响应

    这里一定要明确一个概念,数据响应式和视图更新是没有关系的!数据响应式是一种机制,一种数据变化的侦测机制。而实现数据响应式这种机制的方法不唯一。 那么,在vue...

    conanma
  • Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(十一)阶段性小结

    Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(十一)阶段性小结 前情回顾 去年写的那一套东西,虽然我也写得非常的认真,...

    FungLeo
  • 零基础学习weex(二)Vue2.0

    首先,先解决上一章出现的坑。官网是提供解决方案的有效途径,既然不能用前端的开发模式在sublime编辑,那就选择回归weex官方教程的怀抱吧。在上一章已经搭建了...

    sweet说好的幸福
  • ❤️[前端学习]大数据全栈工程师之一文快速上手vue3❤️

    下面是学习Vue3的成果,一些案例,能让你能快速了解什么是Vue?Vue2.x和Vue3.x的区别在哪里?:

    ChinaManor
  • 快速使用Vue3最新的15个常用API

    之前我写了一篇博客介绍了Vue3的新特性,简单了解了一下Vue3都有哪些特色,并且在文末带大家稍微体验了一下Vue3中 Compsition API 的简单使用

    若川
  • 2020年,需要了解 Vue3 的哪些知识

    Vue 是目前前沿开发中最热门的框架之一,到2019年每周的下载率翻了一番。2020 年初 Vue3的发布还会增加它的受欢迎程度。

    前端小智@大迁世界
  • 12 手写配置启动一个 vue2 项目

    2019年10月5日,vue 团队发布了 Vue3.0 预览版源码,预计到 2020 年第一季度将发布 3.0 正式版。3.0 包涵了许多激动人心的新特性。

    程序员LIYI
  • 石桥码农:Vue3 与 Vue2 在响应机制的实现上有什么差别?

    vue 开发者可能都遇到过这样一个问题:如果模板中数据绑定的是一个数组,我们在 js 代码里面,直接以索引方式改变数组元素的值,有时候视图并不会按照我们的期许更...

    程序员LIYI
  • 迷你版Vue--学习如何造一个Vue轮子

    其实Vue1和Vue2最大的区别就是Vue2多了一个虚拟DOM,其他的区别都是很小的。所以理解了Vue1的源码,就相当于理解了Vue2,中间差了一个虚拟DOM的...

    谭光志
  • Spring学习(一)bean的初始化过程

    (1)通过@ComponentScan扫描com.ywl.leetcode下面所有的类。

    虞大大
  • Vue2+VueRouter2+webpack+Axios 构建项目实战(七)重构API文件为使用axios

    Vue2+VueRouter2+webpack+Axios 构建项目实战(七)重构API文件为使用axios 2017年8月补充 2016年,我写了一系列的 V...

    FungLeo
  • 码云推荐 | J2EE 快速开发平台 renren-security-boot

    renren-security-boot 是一款基于代码生成器的 J2EE 快速开发平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展;使用 Spring...

    码云Gitee
  • Vue3.0 新特性以及使用变更总结(实际工作用到的)

    Vue3.0 在去年9月正式发布了,也有许多小伙伴都热情的拥抱Vue3.0。去年年底我们新项目使用Vue3.0来开发,这篇文章就是在使用后的一个总结, 包含Vu...

    @超人
  • 探索 vuex 2.0 以及使用 vuejs 2.0 + vuex 2.0 构建记事本应用

    前言 首先说明这并不是一个教程贴,而记事本应用是网上早有的案例,对于学习 vuex 非常有帮助。我的目的是探索 vuex 2.0 ,然后使用 vuejs 2.0...

    叙帝利
  • 适合初学者练手的vue小项目(附github源码)

    vue慢慢的成为了前端最受欢迎的框架之一,在很多项目之中开发都能用得到,如今也已经发展到3.0了,可能是因为这个框架可以提高工作效率,因此受到大家的追捧,在之前...

    王小婷
  • 带你体验Vue2和Vue3开发组件的区别(一)

    现在的vue版本已经可以满足我们大部分开发场景,虽然Vue3正式版发布不久,可能存在某些问题,但是提前学习了解总归是有好处的。可能有些已经开始抓狂了,学不动了。

    青年码农
  • jquery dataTable 的学习之初始化插件(一)

    最近用到了一个比较实用的jquery插件--jquery dataTable,这是一个高度灵活的工具,依据的基础逐步增强,这将增加先进的互动控制,支持任何HTM...

    OECOM
  • 前端MVC Vue2学习总结(二)——Vue的实例、生命周期与Vue脚手架(vue-cli)

    一、Vue的实例 1.1、创建一个 Vue 的实例 每个 Vue 应用都是通过 Vue 函数创建一个新的 Vue 实例开始的: var vm = new Vue...

    张果
  • vue2.x老项目typescript改造过程经验总结

    对于vue-cli项目来说,从新跑一遍 vue create xxx-project ,选择Manually select features ,重新选择上typ...

    周陆军

扫码关注云+社区

领取腾讯云代金券