快来学vue吧

vue源码解析(一)

前段时间用vue3开发了几个项目,由于vue3有蛮多新特性的所以还是有必要去学习一下vue3的源码,在此之前呢,先来复习一遍vue2的源码吧。下面我会分为几部分来解剥vue的底层代码。

1. 源码构建

Vue的源码是基于Rollup构建的,它的配置信息全部都放在了scripts

"scripts": {
    "dev": "rollup -w -c scripts/config.js --environment TARGET:web-full-dev",
     ······
    "build": "node scripts/build.js",
    "build:ssr": "npm run build -- web-runtime-cjs,web-server-renderer",
    "build:weex": "npm run build -- weex",
     ······
  }
复制代码

执行build后就回去找构建入口文件 scripts/build.js

let builds = require('./config').getAllBuilds()

// filter builds via command line arg
if (process.argv[2]) { // 这里是判断构建是否有其他项
  const filters = process.argv[2].split(',')
  builds = builds.filter(b => {
    return filters.some(f => b.output.file.indexOf(f) > -1 || b._name.indexOf(f) > -1)
  })
} else {
  // filter out weex builds by default
  builds = builds.filter(b => {
    return b.output.file.indexOf('weex') === -1
  })
}

build(builds)
复制代码

在build.js里我们发现他取到了config.js里的builds,并且做了一层筛选,用于构建出不同的代码块。我们接着跟着逻辑走,builds里会通过函数resolve去找到对应的入口文件,它们都会被构建成dest里的出口文件

const builds = {
  // Runtime only (CommonJS). Used by bundlers e.g. Webpack & Browserify
  'web-runtime-cjs-dev': {
    entry: resolve('web/entry-runtime.js'),
    dest: resolve('dist/vue.runtime.common.dev.js'),
    format: 'cjs',
    env: 'development',
    banner
  },
  ········
}
复制代码

也就是说,执行命令构建打包后,entry会通过resolve函数会根据内容找到对应的代码块,并输出给dest。 最终会在 dist 目录下生成对应的js文件。

构建总结

通过上面的部分学习我们了解到了vue底层构建打包,也知道了不同作用和功能的 Vue.js 它们对应的入口以及最终编译生成的 JS 文件。

初始化

根据上文我们可得知vue的代码是在src/core/index.js中的,根据它我们找到了存放vue地方src/core/instance/index.js

import { initMixin } from './init'
import { stateMixin } from './state'
import { renderMixin } from './render'
import { eventsMixin } from './events'
import { lifecycleMixin } from './lifecycle'
import { warn } from '../util/index'

function Vue (options) {
  if (process.env.NODE_ENV !== 'production' &&
    !(this instanceof Vue)
  ) {
    warn('Vue is a constructor and should be called with the `new` keyword')
  }
  this._init(options)
}

initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)

export default Vue
复制代码

原来vue实际上就是一个用 Function实现的类,所以我们每次都需要new Vue来实例化,里面还有很多带xxxMixin的函数,并用了vue当参数,这里是在vueprototype上挂载一些方法。

initGlobalAPI

initGlobalAPI在vue初始化时挂载了我们常用的一些方法 如nextTick,vue的全局API都可以在这里找到

export function initGlobalAPI (Vue: GlobalAPI) {
  // config
  const configDef = {}
  configDef.get = () => config
  if (process.env.NODE_ENV !== 'production') {
    configDef.set = () => {
      warn(
        'Do not replace the Vue.config object, set individual fields instead.'
      )
    }
  }
  Object.defineProperty(Vue, 'config', configDef)

  // exposed util methods.
  // NOTE: these are not considered part of the public API - avoid relying on
  // them unless you are aware of the risk.
  Vue.util = {
    warn,
    extend,
    mergeOptions,
    defineReactive
  }

  Vue.set = set
  Vue.delete = del
  Vue.nextTick = nextTick

  Vue.options = Object.create(null)
  ASSET_TYPES.forEach(type => {
    Vue.options[type + 's'] = Object.create(null)
  })

  // this is used to identify the "base" constructor to extend all plain-object
  // components with in Weex's multi-instance scenarios.
  Vue.options._base = Vue

  extend(Vue.options.components, builtInComponents)

  initUse(Vue)
  initMixin(Vue)
  initExtend(Vue)
  initAssetRegisters(Vue)
}
复制代码

初始化总结

到这里vue初始化基本就结束了,相信看完了大家对vue都有一些基本的认知了,文中还有很多东西我们会放到后面慢慢学习。

尾言

这是我第一次在掘金发文章,因为之前在知乎专心回答过一些问题,我发现写一些文章不仅能知道自己对知识的掌握能力还可以巩固知识以及发现新的知识点。所以我就写下了这一篇文章,第一次发文写的也许不是很友好,后续会慢慢迭代的。这篇文章参考了 vue技术揭秘。写的很好,感兴趣可以去看一看,我写文章的目的呢就是用来巩固知识点的。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享