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"} } ...}