Code前端首页关于Code前端联系我们

Vue2里的export default到底是什么?怎么用才对?

terry 1天前 阅读数 18 #Vue
文章标签 Vue2;export default

在Vue2项目里写组件时,“export default”几乎是天天见的代码,但不少刚入门的同学还是搞不清它到底是干啥的、怎么用才对,甚至和其他导出方式混淆,今天就把Vue2里export default的关键知识点拆成问题逐个讲透,不管是组件结构、和其他导出方式的区别,还是避坑技巧,看完心里就有数啦~

Vue2里的export default,本质是在搞啥事儿?

Vue2项目能用上export default,核心是ES6的模块导出语法在起作用,咱们写的每个.vue单文件组件,本质上都是一个独立的JS模块(哪怕里面有templatestyle,最终也会被工具链转成JS),而export default默认导出”这个模块里的核心内容——对于Vue组件来说,就是导出包含组件选项(像datamethodsprops这些)的对象。

举个最直观的例子,一个简单的Vue组件长这样:

<template>
  <div>{{ msg }}</div>
</template>
<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      msg: '你好,Vue2!'
    }
  }
}
</script>

这里的export default后面跟着的对象,就是把这个组件的“配置信息”对外暴露出去,其他文件想复用这个组件时,用import 自定义名称 from './HelloWorld.vue'就能拿到这个对象,Vue会自动把它处理成可渲染的组件实例。

另外得注意,每个JS模块只能有一个export default,这和“命名导出(export)”不一样(命名导出可以有多个,后面会对比),正因为是“默认”,所以import的时候不用像命名导出那样写大括号,还能自己给导入的内容起名字,灵活性很高。

写Vue2组件时,export default里该塞哪些东西?

在Vue2的组件里,export default后面跟的是组件选项对象,里面能配置的内容特别多,核心的有这些:

  • name:给组件起个名字,调试的时候(比如Vue DevTools里看组件层级)特别方便,还能实现组件递归(自己调用自己),比如name: 'MyComponent',递归场景下组件内部用<MyComponent />就能调用自己。
  • data:必须是函数!返回一个对象,里面存组件的私有数据,要是写成对象(比如data: { msg: 'xxx' }),多个组件实例会共享同一份数据,一改全改,踩过这个坑的同学肯定懂有多坑…
  • props:定义组件接收父组件传的值,像props: ['parentMsg']或者更严谨的对象形式props: { parentMsg: { type: String, required: true } },负责组件间的数据传递。
  • methods:放组件的方法,比如事件处理函数、业务逻辑函数,像methods: { handleClick() { ... } },方法里的this默认指向组件实例。
  • computed:计算属性,基于已有数据生成新数据,有缓存特性,比如computed: { fullName() { return this.firstName + this.lastName } },依赖不变就不会重复计算。
  • watch:侦听数据变化做操作,比如watch: { msg(newVal, oldVal) { ... } },能深度侦听对象/数组变化(开deep: true)。
  • 生命周期钩子:像created(实例创建完,数据观测、事件配置好了,但没挂载DOM)、mounted(DOM挂载完成,能操作DOM了)这些,在特定阶段执行逻辑。

举个更完整的例子,一个带交互的组件:

<template>
  <div>
    <p>{{ count }}</p>
    <button @click="increment">+1</button>
  </div>
</template>
<script>
export default {
  name: 'Counter',
  data() {
    return {
      count: 0
    }
  },
  methods: {
    increment() {
      this.count++
    }
  },
  created() {
    console.log('组件创建好啦,count初始值是', this.count)
  }
}
</script>

这里export default里的namedatamethodscreated各司其职,共同撑起组件的功能和逻辑~

export default和export有啥区别?在Vue项目里咋选?

很多同学会把export defaultexport搞混,其实它们是ES6模块里两种不同的导出方式,区别大着呢:

规则层面:

  • export default:每个模块只能有一个默认导出,导入时用import 任意名称 from '模块路径',名字自己定,不用管导出时的名字。
  • export(命名导出):一个模块可以有多个命名导出,导入时必须用import { 导出时的名字 } from '模块路径',名字得和导出时对应,除非用as重命名。

Vue项目里的实际用法:

在Vue2开发中,组件文件(.vue)几乎都用export default,因为一个.vue文件对应一个组件,用默认导出最直观,导入时还能随便起名字,

// 导出(HelloWorld.vue里)
export default { name: 'HelloWorld', ... }
// 导入(其他组件里)
import MyHello from './HelloWorld.vue' // 名字改成MyHello也能用

export(命名导出)更适合工具库、工具函数文件,比如写了个utils.js,里面有多个工具函数:

// utils.js
export function formatTime(time) { ... }
export function deepClone(obj) { ... }
// 其他文件导入
import { formatTime, deepClone } from './utils.js'
// 或者重命名
import { formatTime as ft } from './utils.js'

简单说,Vue组件是“单模块单导出”,用export default;多函数/多常量的工具文件是“单模块多导出”,用export更灵活~

用export default时,哪些坑容易踩?咋避?

写多了组件,总会在export default这儿栽跟头,这些高频坑得提前避:

坑1:data写成对象,不是函数

错误写法:

export default {
  data: { // 错!单文件组件里data必须是函数
    msg: '错啦'
  }
}

后果:多个组件实例会共享同一份data,比如列表里每个项用了这个组件,点一个全变。
解决:改成函数返回对象:

data() {
  return {
    msg: '对啦'
  }
}

坑2:组件选项语法错误,比如少写逗号、钩子名拼错

错误示例:

export default {
  name: 'MyComp'
  data() { // 这里少了逗号,会报语法错
    return { ... }
  },
  mounted() { ... },
  mouted() { ... } // 钩子名mouted拼错,不会执行!
}

后果:要么代码直接报错跑不起来,要么生命周期钩子没触发,逻辑丢了。
解决:写的时候多检查语法,IDE装个Vue插件(比如Volar),能实时提示语法错误;生命周期钩子名记准(像mountedupdated这些)。

坑3:import时路径写错,找不到模块

错误示例:

import MyComp from '../components/MyComp.vue' // 实际文件是MyComponent.vue,路径或文件名错了

后果:浏览器控制台报“Module not found”,组件渲染不出来。
解决:养成好习惯,路径用相对路径时,检查或对不对;文件名大小写也要和实际文件一致(有些系统区分大小写)。

坑4:和Vuex、Vue Router结合时导出不对

比如Vuex模块用命名导出,结果Vuex识别不了:
错误写法(Vuex模块文件):

export const myModule = { // 用命名导出,Vuex默认找export default
  state: { ... },
  mutations: { ... }
}

后果:Vuex注册模块时读不到这个模块,状态管理失效。
解决:Vuex模块要用export default导出:

export default {
  state: { ... },
  mutations: { ... }
}

同理,Vue Router的路由组件配置里,组件导入要确保是默认导出的组件~

大型Vue2项目里,export default咋管理更高效?

当项目变大,组件越来越多,export default的写法也得讲究“高效复用、逻辑分层”,分享几个实用思路:

思路1:组件拆分+单一职责,每个组件export default清晰

把大组件拆成小组件,每个.vue文件只负责一块逻辑,export default里的选项也更简洁,比如一个复杂的表单组件,拆成FormItem.vueFormButton.vue等子组件,每个子组件的export default只关注自己的propsmethods,维护起来更轻松。

思路2:用mixins抽离重复逻辑

多个组件有相同逻辑(比如都要处理表单验证、都要监听窗口resize),可以把这些逻辑写到mixins里,mixins本身也是export default一个对象:

// mixins/resizeMixin.js
export default {
  data() { return { windowWidth: 0 } },
  mounted() {
    window.addEventListener('resize', this.handleResize)
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.handleResize)
  },
  methods: {
    handleResize() {
      this.windowWidth = window.innerWidth
    }
  }
}
// 在组件里用mixins
import resizeMixin from './mixins/resizeMixin.js'
export default {
  mixins: [resizeMixin], // 自动合并mixins里的选项
  name: 'MyComponent',
  ...
}

这样多个组件能复用resize相关逻辑,不用重复写生命周期和方法~

思路3:结合TypeScript增强类型(Vue2+TS场景)

Vue2对TS的支持需要借助defineComponent,写法变成:

<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
  name: 'MyComp',
  data() {
    return {
      count: 0 // TS能推断count是number类型
    }
  },
  props: {
    msg: {
      type: String,
      required: true
    }
  }
})
</script>

defineComponent能让TS更智能地推断组件选项的类型,避免props传错类型、方法里this指向错误等问题,大型项目里类型约束能减少很多 bug~

Vue2里有没有不用export default的替代写法?

其实在Vue2里,export default不是唯一的导出方式,还有两种“替代方案”,但各有适用场景:

方案1:用CommonJS的module.exports(webpack支持)

早期Vue项目没用babel处理ES6模块时,会用CommonJS语法:

<template>...</template>
<script>
const MyComponent = {
  name: 'MyComp',
  data() { ... }
}
module.exports = MyComponent
</script>

导入时用const MyComp = require('./MyComponent.vue'),但现在Vue项目基本都用babel+webpack,支持ES6模块,export default更简洁,所以这种写法逐渐淘汰了。

方案2:用Vue.extend创建组件构造器再导出

Vue.extend是Vue2里创建组件构造器的API,写法:

<template>...</template>
<script>
import Vue from 'vue'
const MyComponent = Vue.extend({
  name: 'MyComp',
  data() { ... }
})
export default MyComponent
</script>

这种写法和直接export default { ... }的区别是:前者是“组件构造器”,后者是“组件选项对象”,但Vue Loader处理单文件组件时,会自动把export default { ... }的选项传给Vue.extend,所以两种写法最终效果一样。实际开发中更推荐直接写export default对象,代码更少更直观。

看完这些问题,是不是对Vue2里的`export default`从“眼熟但模糊”变成“清晰会用”了?简单总结下:它是ES6默认导出语法在Vue组件里的实践,负责把组件的配置对外暴露,和命名导出分工不同;写的时候要注意`data`必须是函数、选项语法正确这些细节;大型项目里结合拆分、mixins、TS能玩出更多效率花样~下次写组件时,再遇到`export default`就不会犯懵,还能避坑高效写代码啦~

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门