Skip to content

组件化

1. 组件基础

1.1 组件定义

js
// 全局组件
Vue.component('my-component', {
  template: '<div>{{ message }}</div>',
  data() {
    return {
      message: 'Hello Component'
    }
  }
})

// 局部组件
export default {
  name: 'LocalComponent',
  components: {
    ChildComponent
  }
}

1.2 组件注册

js
// 全局注册
Vue.component('component-name', Component)

// 局部注册
export default {
  components: {
    'component-name': Component
  }
}

2. 动态组件

2.1 基本用法

vue
<template>
  <component :is="currentComponent"></component>
</template>

<script>
export default {
  data() {
    return {
      currentComponent: 'ComponentA'
    }
  },
  components: {
    ComponentA,
    ComponentB
  }
}
</script>

2.2 keep-alive缓存

vue
<keep-alive>
  <component :is="currentComponent">
    <!-- 缓存的动态组件 -->
  </component>
</keep-alive>

3. 异步组件

3.1 基本异步组件

js
// Vue2写法
Vue.component('async-component', () => import('./AsyncComponent.vue'))

// Vue3写法
import { defineAsyncComponent } from 'vue'
const AsyncComponent = defineAsyncComponent(() => import('./AsyncComponent.vue'))

3.2 高级异步组件配置

js
const AsyncComponent = defineAsyncComponent({
  loader: () => import('./AsyncComponent.vue'),
  loadingComponent: LoadingComponent,
  errorComponent: ErrorComponent,
  delay: 200,
  timeout: 3000
})

4. 组件复用策略

4.1 混入 (Mixins)

js
// 定义混入对象
const myMixin = {
  created() {
    this.hello()
  },
  methods: {
    hello() {
      console.log('mixin hook called')
    }
  }
}

// 使用混入
export default {
  mixins: [myMixin]
}

4.2 高阶组件 (HOC)

js
// 高阶组件工厂函数
function withSubscription(WrappedComponent) {
  return {
    props: WrappedComponent.props,
    created() {
      // 添加额外的功能
    },
    render(h) {
      return h(WrappedComponent, {
        props: this.$props
      })
    }
  }
}

5. 组件生命周期

5.1 Vue2生命周期

js
export default {
  beforeCreate() {
    // 实例初始化之后,数据观测和事件配置之前
  },
  created() {
    // 实例创建完成后被立即调用
  },
  beforeMount() {
    // 挂载开始之前被调用
  },
  mounted() {
    // 实例被挂载后调用
  },
  beforeUpdate() {
    // 数据更新时调用
  },
  updated() {
    // 数据更改导致的虚拟DOM重新渲染后调用
  },
  beforeDestroy() {
    // 实例销毁之前调用
  },
  destroyed() {
    // 实例销毁后调用
  }
}

5.2 Vue3生命周期

js
import { onMounted, onUpdated, onUnmounted } from 'vue'

export default {
  setup() {
    onMounted(() => {
      // mounted
    })
    
    onUpdated(() => {
      // updated
    })
    
    onUnmounted(() => {
      // unmounted
    })
  }
}

6. 依赖注入 (provide/inject)

6.1 基本使用

js
// 父组件提供数据
export default {
  provide() {
    return {
      theme: 'dark'
    }
  }
}

// 子组件注入数据
export default {
  inject: ['theme']
}

6.2 响应式注入

js
// Vue3中的响应式注入
import { provide, inject, ref } from 'vue'

// 提供者
export default {
  setup() {
    const theme = ref('dark')
    provide('theme', theme)
  }
}

// 注入者
export default {
  setup() {
    const theme = inject('theme')
    return { theme }
  }
}

7. 组件通信方式

7.1 Props传递

vue
<!-- 父组件 -->
<child-component :message="parentMessage"></child-component>

<!-- 子组件 -->
export default {
  props: {
    message: {
      type: String,
      required: true
    }
  }
}

7.2 事件通信

vue
<!-- 子组件 -->
<button @click="$emit('custom-event', data)">触发事件</button>

<!-- 父组件 -->
<child-component @custom-event="handleEvent"></child-component>

8. 最佳实践

8.1 组件设计原则

  1. 单一职责
  2. 低耦合高内聚
  3. 可复用性
  4. 可测试性

8.2 性能优化

  1. 合理使用异步组件
  2. 使用keep-alive缓存
  3. 避免不必要的组件嵌套
  4. 合理使用计算属性和侦听器

8.3 代码组织

components/
  ├── common/         # 通用组件
  ├── layout/         # 布局组件
  ├── business/       # 业务组件
  └── pages/          # 页面级组件