import Vue from 'vue';
import App from './app.vue';
import Home from './home.vue';
new Vue({
el: '#app',
data() {
return {component: App,};
},
template: `<div><button @click="toSwitch"> 切换 </button><component :is="component"/></div>`,
components: {App, Home},// 注册组件,注册的组件名称为 "App"、"Home"
methods: {toSwitch() {if (this.component === App) {this.component = Home;} else {this.component = App;}
},
},
});
<template>
<div>app</div>
</template>
<script>
export default {name: 'app',};
</script>
<template>
<div>home</div>
</template>
<script>
export default {name: 'home',};
</script>
with (this) {return _c('div', [_c('button', { on: { click: toSwitch} }, [_v('切换')]), _c(component, { tag: 'component'})], 1);
}
- 如果 component 标签的 is 属性值是组件选项对象,间接依据该组件选项对象创立节点(VNode 实例)。如果 component 标签的 is 属性值是 components 中注册的组件名称,则依据该组件名称去 components 找到该组件名称对应的组件选项对象,再依据该组件选项对象创立节点。
function _createElement (
context,comp
tag,
data,
children,
normalizationType
) {
...
if (typeof tag === 'string') {
var Ctor;
ns = (context.$vnode && context.$vnode.ns) || config.getTagNamespace(tag);
if (config.isReservedTag(tag)) {...} else if ((!data || !data.pre) && isDef(Ctor = resolveAsset(context.$options, 'components', tag))) {/* 依据该组件名称去 components 找到该组件名称对应的组件选项对象 */
vnode = createComponent(Ctor, data, context, children, tag);
} else {...}
} else {
...
vnode = createComponent(tag, data, context, children);// 此时 tag 指向组件选项对象, 间接依据组件选项对象创立节点。data 值为 {tag:"component"}
}
...
}