技术文档中心
首页
React
Vue
TypeScript
Kotlin
React Native
Electron
Android
首页
React
Vue
TypeScript
Kotlin
React Native
Electron
Android
  • Vue2 基础

    • Vue 学习指南
    • Vue2 快速入门
    • Vue2 模板语法
    • Vue2 组件基础
    • Vue2 计算属性与侦听器
    • Vue2 生命周期
  • Vue2 进阶

    • Vue2 组件通信
    • Vue2 插槽详解
    • Vue2 混入与自定义指令
    • Vue2 过渡与动画
    • Vuex 状态管理
  • Vue2 高级

    • Vue2 性能优化
    • Vue2 服务端渲染(SSR)
    • Vue2 源码解析
  • Vue3 基础

    • Vue3 快速入门
    • Vue3 Composition API
    • Vue3 响应式系统
    • Vue3 组件基础
    • Vue3 生命周期
  • Vue3 进阶

    • Vue3 组合式函数
    • Vue3 组件通信
    • Vue3 Teleport 与 Suspense
    • Pinia 状态管理
    • Vue Router 4
  • Vue3 高级

    • Vue3 TypeScript
    • Vue3 性能优化
    • Vue3 测试
    • Vue3 SSR
    • Vue3 源码解析
  • 实战项目

    • Vue2 实战项目
    • Vue3 实战项目
    • Vue2 迁移 Vue3

Vue2 组件基础

组件注册

全局注册

Vue.component('my-component', {
  template: '<div>A custom component!</div>'
})

局部注册

const ComponentA = {
  template: '<div>Component A</div>'
}

new Vue({
  el: '#app',
  components: {
    'component-a': ComponentA
  }
})

Props

基本用法

Vue.component('blog-post', {
  props: ['title'],
  template: '<h3>{{ title }}</h3>'
})
<blog-post title="My journey with Vue"></blog-post>

Prop 类型

props: {
  title: String,
  likes: Number,
  isPublished: Boolean,
  commentIds: Array,
  author: Object,
  callback: Function,
  contactsPromise: Promise
}

Prop 验证

props: {
  propA: Number,
  propB: [String, Number],
  propC: {
    type: String,
    required: true
  },
  propD: {
    type: Number,
    default: 100
  },
  propE: {
    type: Object,
    default: function () {
      return { message: 'hello' }
    }
  },
  propF: {
    validator: function (value) {
      return ['success', 'warning', 'danger'].indexOf(value) !== -1
    }
  }
}

自定义事件

监听子组件事件

<blog-post @enlarge-text="postFontSize += 0.1"></blog-post>

触发事件

methods: {
  enlargeText() {
    this.$emit('enlarge-text')
  }
}

使用事件抛出值

this.$emit('enlarge-text', 0.1)
<blog-post @enlarge-text="postFontSize += $event"></blog-post>

插槽

基本用法

<!-- 子组件 -->
<div class="container">
  <slot></slot>
</div>

<!-- 父组件 -->
<navigation-link>
  Your Profile
</navigation-link>

具名插槽

<!-- 子组件 -->
<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>

<!-- 父组件 -->
<base-layout>
  <template v-slot:header>
    <h1>Here might be a page title</h1>
  </template>

  <p>A paragraph for the main content.</p>

  <template v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>

作用域插槽

<!-- 子组件 -->
<ul>
  <li v-for="todo in todos" :key="todo.id">
    <slot :todo="todo"></slot>
  </li>
</ul>

<!-- 父组件 -->
<todo-list>
  <template v-slot:default="slotProps">
    <span>{{ slotProps.todo.text }}</span>
  </template>
</todo-list>

动态组件

<component :is="currentTabComponent"></component>

keep-alive

<keep-alive>
  <component :is="currentTabComponent"></component>
</keep-alive>

异步组件

Vue.component('async-example', function (resolve, reject) {
  setTimeout(function () {
    resolve({
      template: '<div>I am async!</div>'
    })
  }, 1000)
})

配合 webpack

Vue.component('async-webpack-example', () => import('./my-async-component'))
最近更新: 2026/1/27 15:51
Contributors: hailong
Prev
Vue2 模板语法
Next
Vue2 计算属性与侦听器