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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Vue.js中,为什么我们必须在导入后导出组件?相关的知识,希望对你有一定的参考价值。

php中,当我们包含来自另一个文件的代码时,我们包含它,就是这样,代码现在可以在我们执行include的文件中使用。但是在Vue.js中,在导入组件之后我们还必须将其导出。

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

答案

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属性)。

或者,可以使用global component registrationUserDetailUserEdit解决错误,这将消除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

另一答案

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中,这也是一样的。您定义一个组件(或实际上只是一个Object),但该组件本身不会执行任何操作。您导出此组件,以便可以在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>

您的组件提到名为“custom-button”的组件。这不是一个普通的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,并且没有,因为它没有任何意义并且严重限制了您可以对组件执行的操作,同时还使编译器更容易出错,不易理解且总体上不太有用。

另一答案

vue中的组件可能很棘手。如果你还没有,我强烈建议你阅读vue.js网站上关于组件注册如何工作的文档,特别是tony19提到全局和local registration。您在屏幕截图中显示的代码示例实际上是在做一些事情。首先,它使组件在本地可用,并且只在本地(如.vue文件中)使用。此外,正如你在key对象中提供的components,它在模板中可用,在这种情况下,app-user-detailapp-user-edit而不是user-detailuser-edit

重要的是,应该提到的是,该组件注册实际上不需要import。您可以在单个文件中定义多个组件。 components密钥提供了一种识别该组件正在使用的方法。所以import不是必需的,所以vue确实需要components键来理解你作为一个组件使用什么,以及其他代码是什么。

最后,正如其他一些答案所暗示的那样,components密钥实际上并不是出口。 vue组件的默认签名需要export,但这不会导出components键下列出的组件。它正在做的是让vue以自上而下的方式构建。根据应用程序设置的其余部分,您可能正在使用单个文件组件。无论哪种方式,vue将从顶级vue instance开始,并通过组件向下工作,除了全局注册,没有顶级组件知道在它下面使用哪些组件。

这意味着vue可以正确渲染事物,每个组件都必须包含对它使用的额外组件的引用。此引用作为更高级别组件的一部分导出(在您的情况下为User.vue),但不是组件本身(UserDetail.vue)。

所以看起来vue在导入后需要第二次导出,但它实际上正在做其他事情以允许根vue实例渲染你的组件。

顺便说一句,关于这个主题的vue文档确实非常好,如果你还没有看过我上面链接的部分。有一个关于模块导入/导出系统的附加部分似乎与您要求的内容高度相关,您可以在这里找到:Module-systems

另一答案

为了使App.vue能够使用User组件,您需要导出default object文件的User.vue

export default {中,您实际上并不导出新导入的组件。你只是出口一个完全正常的JavaScript Object。这个对象碰巧有另一个Object的引用。

当你import一个对象(或函数或数组或...)时,它实际上并没有像PHP那样将该文件的内容加载到组件中。它只是确保您的编译器(可能是webpack)知道如何构建程序。它基本上创建了一个引用,因此webpack知道在哪里寻找功能。

以上是关于在Vue.js中,为什么我们必须在导入后导出组件?的主要内容,如果未能解决你的问题,请参考以下文章

[vue]js模块导入导出export default

模块js导入/导出问题(vue.js)

为啥在 Vue.js 或 React 中使用组件? [关闭]

Vue JS 路由器组件 - 在路由之间导航后无法重用使用 webpack 导入的 JS 文件

Vue.js - 是不是可以使用 Javascript 动态导入从另一台服务器加载组件?

制作 vue.js 组件库。避免在每次编辑后重建它