在PHP
中,当我们包含另一个文件中的代码时,便包含了它,仅此而已,代码现在在执行包含的文件中可供我们使用。但是在Vue.js
中,导入组件后,我们还必须导出它。
为什么?我们为什么不简单地导入它?
答案 0 :(得分:6)
在
Vue.js
中,导入组件后,我们还必须将其导出。
我想您可能会参考User.vue
中的以下几行,想知道为什么将UserDetail
和UserEdit
导入到文件中,然后导出到脚本导出的components
中属性:
import UserDetail from './UserDetail.vue';
import UserEdit from './UserEdit.vue';
export default {
components: {
appUserDetail: UserDetail,
appUserEdit: UserEdit
}
}
vue-loader
期望.vue
文件的脚本导出包含组件的定义,该定义实际上包括组装组件模板的配方。如果模板包含其他Vue组件,则需要提供其他组件的定义,否则称为component registration。如@ Sumurai8所示,.vue
文件本身的导入未注册相应的单文件组件;而是必须在进口商的components
属性中显式注册这些组件。
例如,如果App.vue
的模板包含<user />
和User.vue
被定义为:
<template>
<div class="user">
<app-user-edit></app-user-edit>
<app-user-detail></app-user-detail>
</div>
</template>
<script>
export default {
name: 'user'
}
</script>
... User
组件将变为空白,并且您会看到以下控制台错误:
[Vue warn]: Unknown custom element: <app-user-edit> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
[Vue warn]: Unknown custom element: <app-user-detail> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
当Vue尝试在<user />
的模板中呈现App.vue
时,Vue不知道如何解析内部的<app-user-detail>
和<app-user-edit>
,因为它们的组件注册丢失了。可以通过在User.vue
(即上面显示的components
属性)中注册本地组件来解决错误。
或者,可以使用UserDetail
和UserEdit
中的global component registration解决错误,这将避免在User.vue
中进行本地注册。请注意,必须在创建Vue实例之前完成全局注册。示例:
// main.js
import Vue from 'vue';
import UserDetail from '@/components/UserDetail.vue';
import UserEdit from '@/components/UserEdit.vue';
Vue.component('app-user-detail', UserDetail);
Vue.component('app-user-edit', UserEdit);
new Vue(...);
答案 1 :(得分:1)
import
将代码导入到当前文件中,但是它不会自行执行任何操作。想象以下非Vue代码:
// File helpers.js
export function tickle(target) {
console.log(`You tickle ${target}`)
}
// File main.js
import { tickle } from 'helpers'
您已经导入了代码,但是它什么也没做。要真正挠痒痒,您需要调用该函数。
tickle('polar bear');
在Vue中,其作用相同。您定义了一个组件(或实际上只是一个对象),但是该组件本身并不做任何事情。您可以导出该组件,以便将其导入Vue库可以对该对象执行某些操作的其他地方。
在Vue组件中,导出当前组件,然后导入在模板中使用的组件。通常,您需要执行以下操作:
<template>
<div class="my-component">
<custom-button color="red" value="Don't click me" @click="tickle" />
</div>
</template>
<script>
import CustomButton from './CustomButton';
export default {
name: 'my-component',
components: {
CustomButton
}
}
</script>
您的组件提到一个名为“自定义按钮”的组件。这不是普通的html元素。它不知道通常如何处理。那么我们该怎么办?我们导入它,然后将其放入components
中。这会将名称CustomButton
映射到您导入的组件。现在,它知道如何渲染组件了。
使用Vue挂载根组件时,通常会在main.js
中发生“魔术”。
import Vue from "vue";
import App from "./App";
Vue.config.productionTip = false;
/* eslint-disable no-new */
new Vue({
el: "#app",
components: { App },
template: "<App/>"
});
这是做什么的?您告诉Vue在<App/>
所标识的html元素中渲染#app
,并告诉它应该在./App.vue
中找到该元素。
但是,如果Vue编译器“更智能”,我们是否不能忽略export
?是的,没有。是的,因为编译器可以将很多东西转换为有效的javascript,而不能,因为它没有意义,并严重限制了您可以对组件执行的操作,同时还使编译器更容易出错,更难以理解且总体上不太有用。
答案 2 :(得分:1)
vue
中的组件可能很棘手。如果您还没有的话,我强烈建议您阅读vue.js网站上有关组件注册如何工作的文档,尤其是tony19提到了global和local registration。您在屏幕快照中显示的代码示例实际上在做两件事。首先,它使组件在本地可用,并且仅在本地(如该.vue文件中)可用。此外,它还可以作为模板提供给模板,就像您在key
对象中提供的components
,在这种情况下,是app-user-detail
和app-user-edit
而不是{{1} }和user-detail
。
重要的是,应该提到实际上user-edit
并不是此组件注册运行所必需的。您可以在一个文件中定义多个组件。使用import
键可以识别该组件正在使用的内容。因此不需要components
,所以import
确实需要vue
键才能了解您用作组件的是什么,以及什么是其他代码。
最后,正如其他答案所暗示的,components
键实际上不是导出。 components
组件的默认签名需要一个vue
,但这不是导出export
键下列出的组件的标志。它正在做的是让components
以自顶向下的方式构建。根据其余应用程序设置的样子,您是否使用单个文件组件。无论哪种方式,vue
都将从顶层vue instance
开始,一直向下遍历各个组件,但全局注册除外,没有顶层组件知道在其之下使用了哪些组件< / strong>。
这意味着vue
要正确渲染事物,每个组件都必须包含对其使用的额外组件的引用。此引用作为高级组件(在您的情况下为vue
)的一部分导出,但不是组件本身(User.vue
)的一部分。
因此,看来UserDetail.vue
在导入后需要第二次导出,但是实际上它在做其他事情以允许根vue实例呈现您的组件。
顺便说一句,关于该主题的vue文档确实非常不错,如果您还没有,请看一下我上面链接的部分。还有一个关于模块导入/导出系统的附加部分,它与您所要求的内容高度相关,您可以在此处找到:Module-systems 。
答案 3 :(得分:0)
为了使App.vue
能够使用User
组件,您需要导出default object
文件的User.vue
。
在export default {
中,您实际上并没有导出新导入的组件。您只是在导出完全正常的JavaScript Object
。该对象恰好具有另一个对象的引用。
当您import
对象(或函数,数组或...)时,实际上并不会将该文件的内容加载到PHP这样的组件中。它只是确保您的编译器(可能是webpack)知道如何构造程序。它基本上是创建参考,因此webpack知道在哪里寻找功能。
答案 4 :(得分:0)
这里的 import
和 export
在概念上是不同且不相关的东西,两者都必须使用。
导入 Vue 组件与 JavaScript 中的任何其他导入相同:
// foo.mjs
export function hello() {
return "hello world!";
}
// bar.mjs
import { hello } from './foo.mjs';
console.log(hello());
现在运行node bar.mjs
,你会感受到导入是如何工作的——你想使用在其他地方定义/实现的东西,那么你必须导入它,不管它是否是一个Vue组件与否。
关于导出,您不是在导出您导入的组件。您唯一要导出的是当前组件。但是,当前组件可能会在其 <template>
中使用其他一些子组件,因此必须通过在导出对象的 components
字段中指定这些子组件来注册这些子组件。