这是我参与更文挑战的第16天,活动详情查看: 更文挑战
前言
在阅读Vue源码的时候,经常会看到一个vm对象,里边有很多属性,并且伴随着各种属性操作。虽然知道这个vm就是当前的Vue实例,但是对源码不清晰的我来说看着看着就晕了,哪个属性是哪个,完全不记得了。这篇文章主要是来整理下这个vm对象,看看它里边的几个常用属性都是什么含义。
先来看下常遇到的vm对象的定义:
vm定义
直接将当前this赋值给vm
const vm: Component = this
复制代码
通过传参进来
function initInternalComponent (vm: Component, options: InternalComponentOptions)
复制代码
从watcher中获得(Watcher构造函数中有一个属性是vm)
const vm = watcher.vm
复制代码
简单看下Watcher构造函数中对vm的定义:
export default class Watcher{
vm: Component;
...
constructor(vm: Component){
this.vm = vm;
if (isRenderWatcher) {
vm._watcher = this
}
vm._watchers.push(this)
...
}
...
}
复制代码
vm属性介绍
从定义处已经看到vm是一个VueComponet,即Vue组件。
看一个具体的Vue组件例子:
<template>
<div id="example" @click="changeMessage">
{{ message }}
<no-rights />
</div>
</template>
<script>
import noRights from '@/common/components/noRights';
export default {
name: 'Test',
components: {
noRights
},
data() {
return {
message: '测试vm'
};
},
watch: {
message() {
console.log('message变了');
}
},
mounted() {
window.vm = this;
},
methods: {
changeMessage() {
this.message = 'value改变了';
}
}
};
</script>
复制代码
对应的vm对象返回:
$el
当前Vue实例的真实DOM节点
$options
先来看下$options的定义:
// merge options
if(options && options._isComponent){
...
const opts = vm.$options = Object.create(vm.constructor.options)
}else {
vm.$options = mergeOptions(
resolveConstructorOptions(vm.constructor),
options || {},
vm
)
}
复制代码
在前边介绍new Vue实例的时候看到过$options,它是Vue构造函数与Vue实例的options合并后的结果。
$parent
当前实例的父Vue实例
$children
当前实例的子组件(在这个例子中就是componets中的rights组件)
$root
当前组件树的根Vue实例。如果没有父实例,则vm.$root就指向自己
$vnode
当前Vue实例的父虚拟节点。如果为null,表示当前是根Vue的实例
vm.$vnode = parentVnode // update vm's placeholder node without re-render
复制代码
_vnode
当前Vue实例的虚拟节点,_vnode有个parent属性又指向实例的父虚拟节点,即$vnode
vm._vnode = vnode
if (vm._vnode) { // update child tree's parent
vm._vnode.parent = parentVnode
}
复制代码
_self
当前Vue实例自己
vm._self = vm
复制代码
_uid
唯一的标志id,在调用Vue实例的私有方法_init时递增
let uid = 0;
Vue.prototype._init = function(Vue: Class<Component>) {
const vm: Component = this;
vm._uid = uid ++;
...
}
复制代码
_isVue
该属性也是在_init方法中定义的,作者给了解释,大概是说这个是为了防止this被observed
// a flag to avoid this being observed
vm._isVue = true
复制代码
来看下observe关于这块的定义:
export function observe (value: any, asRootData: ?boolean): Observer | void {
...
let ob: Observer | void
if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
ob = value.__ob__
} else if (
shouldObserve &&
!isServerRendering() &&
(Array.isArray(value) || isPlainObject(value)) &&
Object.isExtensible(value) &&
!value._isVue
) {
ob = new Observer(value)
}
...
}
复制代码
从代码里可以看到如果_isVue为true,是不会去新建Observer实例的,即如果是Vue实例本身是不会去构造响应式的。
_isMounted
实例是否完成挂载,$mount的时候判断是根Vue实例时,设置为true
if (vm.$vnode == null) {
vm._isMounted = true
callHook(vm, 'mounted')
}
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END