在Vue.js中,为什么在导入组件后必须导出组件?

时间:2018-08-27 11:45:50

标签: vue.js vuejs2

PHP中,当我们包含另一个文件中的代码时,便包含了它,仅此而已,代码现在在执行包含的文件中可供我们使用。但是在Vue.js中,导入组件后,我们还必须导出它。

为什么?我们为什么不简单地导入它?

5 个答案:

答案 0 :(得分:6)

  

Vue.js中,导入组件后,我们还必须将其导出。

我想您可能会参考User.vue中的以下几行,想知道为什么将UserDetailUserEdit导入到文件中,然后导出到脚本导出的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.

demo 1

当Vue尝试在<user />的模板中呈现App.vue时,Vue不知道如何解析内部的<app-user-detail><app-user-edit>,因为它们的组件注册丢失了。可以通过在User.vue(即上面显示的components属性)中注册本地组件来解决错误。

或者,可以使用UserDetailUserEdit中的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(...);

demo 2

答案 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-detailapp-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)

TL;DR

这里的 importexport 在概念上是不同且不相关的东西,两者都必须使用。


导入 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 字段中指定这些子组件来注册这些子组件。