vue中的一个组件就是一个vue实例吗?
用单文件组件开发时,只有main.js中有一个new Vue(),其他的组件都没有new啊,那也是一个vue实例吗?
vue中的一个组件就是一个vue实例吗?
用单文件组件开发时,只有main.js中有一个new Vue(),其他的组件都没有new啊,那也是一个vue实例吗?
简单的讲,带uid的都是vue的实例。
根也叫根组件,和其他的组件没有本质区别,还有通过函数调用(像各个组件库的弹窗)这些,通过append讲dom添加到body里的也是。
为什么各个单文件组件没有new的过程,因为这个过程在你看不到的地方进行了(应该是在vue-loader里)
是的。
所有组件都是实例这句话,意思是,你可以单独使用一个组件,因为单一组件已经具有成为一个实例的条件。
这里也体现了一个开发的指导意义,当组件不能单一实例化,说明组件化的实施不合理,例如依赖数据的通信需求,是否妥善处理组件的通信等。
1.每个组件都是一个vue实例
所有的 Vue 组件同时也都是 Vue 的实例,所以可接受相同的选项对象 (除了一些根级特有的选项) 并提供相同的生命周期钩子。
vue官网,什么时组件?
2.单文件组件开发 个人理解
main.js时一个根vue实例的创建入口,而其他.vue文件是为了方便我们开发将html、js、css放到同一个文件中,webpack编译的时候会使用vue-loader去处理这些.vue文件,生成一个个vue组件定义。当某个地方import并使用了这个组件,其实就是new了一个这个组件的vue实例
组件就是实例,只不过用单文件组件开发,利用脚手架,内部代码的编译楼主是看不到的,不知道楼主这么问
是有啥功能无法实现?就好像一切皆对象,一个道理,用别人的框架就要遵守他的思想,首先要把框架的规约记住了,
这样学的才简单,
这句话,这是官方文档说的
不过严谨来说,应该是
一个单页应用就是一个 vue 的实例
每个自定义组件就是一个 vueComponent 实例,
只不过 vueComponent 的构造器和 vue 的构造器的内容是基本一样的。效果表现也一致,两者对比如下
<div id="app">{{uname}}</div>
<script>
// 仅有Vue实例
var app = new Vue({
el: "#app",
data() {
return {
uname: "小红",
};
},
methods: {
say() {
console.log("调用了say方法");
},
},
mounted() {
this.say();
},
});
</script>
<div id="app"></div>
<script>
// 组件
const RootCmp = {
data() {
return {
uname: "小红",
};
},
methods: {
say() {
console.log("调用了say方法");
},
},
mounted() {
this.say();
},
template: "<div>{{uname}}</div>",
};
var app = new Vue({
el: "#app",
render: (h) => h(RootCmp),
});
</script>
我们创建个 vue 项目
<div id="app">
{{ message }}
<cmp-one></cmp-one>
------
<cmp-two></cmp-two>
</div>
<script>
// 全局组件
Vue.component("CmpOne", {
template: "<div>组件1</div>",
});
var app = new Vue({
el: "#app",
data: {
message: "Hello Vue!",
},
components: {
CmpTwo: {
// 局部组件
template: "<div>组件2</div>",
},
},
});
</script>
然后开始分析源码
以下是 vue.js 部分代码,
我们很快找到 Vue 的类,并添加个 log
function Vue(options) {
console.log("Vue构造类");
if (!(this instanceof Vue)) {
warn("Vue is a constructor and should be called with the `new` keyword");
}
this._init(options);
}
结果发现,Vue 构造函数只会被执行一次,也就是你手动 new 的时候。
这足以证明每个组件(或.vue)文件不是 Vue 的实例。
我们继续看源码,通过代码分析我们得知
全局组件 or 局部组件的注册初始化,是走这里
...
var Sub = function VueComponent (options) {
console.log('VueComponent组件的构造类');
this._init(options);
};
...
// 其中vnode.componentOptions.Ctor就是VueComponent类
new vnode.componentOptions.Ctor(options);
如上代码中,VueComponent组件的构造类
会被打印两次。
这也就是说,它才是组件实例的构造函数(类)。
Vue.extend = function (extendOptions, is) {
var Super = this;
// ...
var Sub = function VueComponent(options) {
console.log("VueComponent组件的构造用来 实例化");
this._init(options);
};
Sub.prototype = Object.create(Super.prototype);
Sub.prototype.constructor = Sub;
// ...
return Sub;
};
function initAssetRegisters(Vue) {
// ...
ASSET_TYPES.forEach(function (type) {
Vue[type] = function (id, definition) {
if (!definition) {
return this.options[type + "s"][id];
} else {
if (type === "component" && isPlainObject(definition)) {
definition.name = definition.name || id;
definition = this.options._base.extend(definition);
}
return definition;
}
};
});
}
function initGlobalAPI(Vue) {
// ...
initAssetRegisters(Vue);
}
initGlobalAPI(Vue);
解读:
项目初始化进来的时候会执行一个全局方法 initGlobalAPI
initGlobalAPI里会调用initAssetRegisters
initAssetRegisters的作用是给你定义的一些全局Asset
扩展一些属性
枚举ASSET_TYPES 就是全局Asset
:包含 component,directive,filter
比如我的组件 CmpOne,原本只有 template 属性,经过扩展后,就会多出如下属性
{
cid: 1
component: ƒ ( id, definition )
directive: ƒ ( id, definition )
extend: ƒ (extendOptions, is)
extendOptions: {template: '<div>组件1</div>', name: 'CmpOne', _Ctor: {…}}
filter: ƒ ( id, definition )
mixin: ƒ (mixin)
options: {components: {…}, directives: {…}, filters: {…}, template: '<div>组件1</div>', _base: ƒ, …}
sealedOptions: {components: {…}, directives: {…}, filters: {…}, template: '<div>组件1</div>', _base: ƒ, …}
super: ƒ Vue(options)
superOptions: {components: {…}, directives: {…}, filters: {…}, _base: ƒ}
use: ƒ (plugin)
}
其中重要的一点就是给CmpOne组件指定了构造器
那是怎么指定的呢?
this.options._base.extend(definition);
这句代码本质上就是调用了Vue.extend
来创建了一个Vue的子类。
那么情况就明了了,组件构造函数是继承自Vue构造。
最后vue在创建vdom的时候,就会去实例化组件类,即new VueComponent()
Vue组件构造类
是继承自Vue类
所有的Vue组件都是Vue实例
这句话只是官方为了方便咱们理解,但严格来说并不对,严格来说应该是所有的Vue组件都是Vue的子类实例
在多页应用下或vue2的Vue.extend
和vue3的createApp
,才会形成多个Vue实例
Vue.component和Vue.extend的联系:
Vue.component注册或获取全局组件。注册还会自动使用给定的 id 设置组件的名称,如上id就是组件名CmpOne,内部实质上调用了Vue.extend,最后返回"子类"(构造器),这个子类构造器。
9 回答1.8k 阅读✓ 已解决
6 回答1.8k 阅读
3 回答1.5k 阅读✓ 已解决
4 回答1.4k 阅读✓ 已解决
3 回答1.3k 阅读
2 回答1.3k 阅读✓ 已解决
3 回答1.5k 阅读✓ 已解决
1.整个项目是一个vue的实例
2.每个页面或者每个组件是一个vuecomponent的实例