>웹 프론트엔드 >JS 튜토리얼 >Vue 소스 코드 아키텍처 해석(상세)

Vue 소스 코드 아키텍처 해석(상세)

不言
不言앞으로
2019-01-24 10:03:053300검색

이 기사의 내용은 Vue 소스 코드 아키텍처의 해석(상세)에 관한 것입니다. 필요한 친구들이 참고할 수 있기를 바랍니다.

Download

Github으로 이동하여 다운로드 Vue#🎜🎜 #

npm install 
npm run dev
Run it

rollup + flow

vue는 롤업 패키징, 플로우 표준 데이터 유형을 사용합니다#🎜 🎜#

rollup은 먼저 webpack을 사용하여 적용할 수 있습니다. 시간이 제한되어 있으므로 이를 위해 롤업 문서를 읽을 필요는 없습니다. 🎜🎜#

package.json 열기

스크립트 구성 살펴보기

 "dev": "rollup -w -c scripts/config.js --environment TARGET:web-full-dev",
  "dev:cjs": "rollup -w -c scripts/config.js --environment TARGET:web-runtime-cjs-dev",

scripts/config.jsOpen

에 따르면 다른 TARGET은 다른 구성을 선택합니다


동시에 process.env.NODE_ENV 환경은 여기에서 구성됩니다

TARGET에는 js에 대한 CommonJS, ES 모듈, UMD가 있습니다. 소개 유형#🎜 🎜#weex도 있고, ssr

'web-runtime-cjs-dev': {
    entry: resolve('web/entry-runtime.js'),
    dest: resolve('dist/vue.runtime.common.dev.js'),
    format: 'cjs',
    env: 'development',
    banner
  }
alias 경로는 alias.js 아래에 설정됩니다

먼저 src/platforms를 소개합니다

있습니다 web 및 weex 입구

웹 파일 아래에는 js 도입 유형, 서버 패키징 입구에 대한 CommonJS, ES 모듈, UMD가 있습니다

웹/입력-런타임 열기 .js#🎜 🎜#소개

import Vue from './runtime/index'

export default Vue

Open ./runtime/index
import Vue from 'core/index'

Vue.prototype.$mount = function (
  el?: string | Element,
  hydrating?: boolean
): Component {
  el = el && inBrowser ? query(el) : undefined
  return mountComponent(this, el, hydrating)
}
export default Vue

vue 프로토타입에 마운트 방법 추가

devtools 처리, devtools 설치 알림 없음 #🎜 🎜#

이 프롬프트 개발 환경 프롬프트를 제공했습니다

You are running Vue in development mode.
Make sure to turn on production mode when deploying for production.
See more tips at https://vuejs.org/guide/deployment.html

platforms 디렉토리 폴더 설명이 완료되었습니다

core 디렉토리

Open core/ 인스턴스 /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
가장 먼저 실행할 것은 initMixin(Vue)

Open init

export function initMixin (Vue) {
  Vue.prototype._init = function (options?: Object) {
    const vm = this
    // a uid 
    vm._uid = uid++
    
    let startTag, endTag
    /* istanbul ignore if */
    if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
      startTag = `vue-perf-start:${vm._uid}`
      endTag = `vue-perf-end:${vm._uid}`
      mark(startTag)
    }

    // a flag to avoid this being observed
    vm._isVue = true
    // 处理传入的options
    // merge options
    if (options && options._isComponent) {
      // optimize internal component instantiation
      // since dynamic options merging is pretty slow, and none of the
      // internal component options needs special treatment.
      initInternalComponent(vm, options)
    } else {
       // 传入的options,默认的options一起合并挂载到vm.$options上
      vm.$options = mergeOptions(
        resolveConstructorOptions(vm.constructor),
        options || {},
        vm
      )
    }
    /* istanbul ignore else */
    if (process.env.NODE_ENV !== 'production') {
      // 代理
      initProxy(vm)
    } else {
      vm._renderProxy = vm
    }
    // 生命周期
    initLifecycle(vm)
     // emit on 事件
    initEvents(vm)
    // 处理render vdom
    initRender(vm)
    callHook(vm, 'beforeCreate')
    // 处理Injections
    initInjections(vm) // resolve injections before data/props
    // 双向数据绑定,监听订阅
    initState(vm)
    initProvide(vm) // resolve provide after data/props
    callHook(vm, 'created')
    
    /* istanbul ignore if */
    if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
      vm._name = formatComponentName(vm, false)
      mark(endTag)
      measure(`vue ${vm._name} init`, startTag, endTag)
    }
    // 渲染到dom
    if (vm.$options.el) {
      vm.$mount(vm.$options.el)
    }
  }
}
lifecycle#🎜 🎜#

lifecycle을 열면

export function callHook (vm: Component, hook: string) {
  // disable dep collection when invoking lifecycle hooks
  pushTarget()
  //执行对象的周期函数,周期函数最后被处理成数组
  const handlers = vm.$options[hook]
  const info = `${hook} hook`
  if (handlers) {
    for (let i = 0, j = handlers.length; i < j; i++) {
      invokeWithErrorHandling(handlers[i], vm, null, vm, info)
    }
  }
  if (vm._hasHookEvent) {
    vm.$emit('hook:' + hook)
  }
  popTarget()

callHook에 해당하는 주기가 실행됩니다. 개발자는 주기 함수에

Events

를 작성합니다. #🎜 🎜#initEvents는 방출 및 기타 방법을 구현합니다. 여기에 자세히 설명되지 않은 리스너 구독자 모델을 참조하세요

render

renderMixin 함수

$nextTick _render 프로토타입 객체 추가

$nextTick은 DOM이 업데이트된 후 즉시 호출됩니다

nextTick(fn, this)은 자체 실행 함수입니다# 🎜🎜#

_render는 dom이 아닌 노드의 js 데이터를 반환합니다

made Vdom

initRender function

add _c 및 $createElement to vm

state

if (!(key in vm)) {
      proxy(vm, `_props`, key)
    }
을 렌더링하는 데 사용되는 메서드는 vue 속성에 대한 프록시 역할을 합니다. this.a에 액세스하여 this.data.a의 값을 얻을 수 있습니다.

export function initState (vm: Component) {
  vm._watchers = []
  const opts = vm.$options
  if (opts.props) initProps(vm, opts.props)
  if (opts.methods) initMethods(vm, opts.methods)
  if (opts.data) {
    initData(vm)
  } else {
    observe(vm._data = {}, true /* asRootData */)
  }
  if (opts.computed) initComputed(vm, opts.computed)
  if (opts.watch && opts.watch !== nativeWatch) {
    initWatch(vm, opts.watch)
  }
}
#🎜🎜 #데이터 모니터링

stateMixin 함수

프로토타입 객체 추가

 Vue.prototype.$set = set
 Vue.prototype.$delete = del

Others

#🎜🎜 #src/compiler가 컴파일을 수행했습니다.

# 🎜🎜#위 전체 구조해석이 완료되었습니다

첨부사진

위 내용은 Vue 소스 코드 아키텍처 해석(상세)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제