Vue笔记(五)--组件进阶

这一节了解一下Vue3中的组件进阶,组件在被创建出来到渲染完成会经历一系列过程,同样组件的销毁也会经历一系列过程,组件从创建到销毁的这一系列过程被称为组件生命周期,生命周期的节点被定义一系列方法,也被称为生命周期钩子。简单总结:

API

  1. beforeCreate

含义:组件实例刚创建,数据、方法都未初始化 作用:几乎不用,不能操作 this 数据

javascript 复制代码
<script>
export default {
  beforeCreate() {
    console.log('组件即将创建')
  }
}
</script>
  1. created

含义:组件创建完成,数据 / 方法已初始化,但未生成 DOM 作用:请求接口、初始化数据、定时器

javascript 复制代码
<script>
export default {
  data(){return {list:[]}},
  created(){
    console.log('组件创建完毕,可请求数据')
  }
}
</script>
  1. beforeMount

含义:挂载 DOM 之前 作用:挂载前最后一次修改模板数据

javascript 复制代码
<script>
export default {
  beforeMount(){
    console.log('即将渲染DOM')
  }
}
</script>
  1. mounted 最常用

含义:DOM 已渲染挂载完成 作用:操作 DOM、初始化插件、开启定时器、请求数据

javascript 复制代码
<template><view>我是组件</view></template>
<script>
export default {
  mounted(){
    console.log('DOM已挂载完毕')
  }
}
</script>
  1. beforeUpdate

含义:数据变化,视图重新渲染前 作用:更新前获取旧 DOM 状态

javascript 复制代码
<script>
export default {
  beforeUpdate(){
    console.log('视图即将更新')
  }
}
</script>
  1. updated

含义:视图更新完成 作用:更新后操作 DOM

javascript 复制代码
<script>
export default {
  updated(){
    console.log('视图已更新')
  }
}
</script>
  1. beforeUnmount

含义:组件销毁前 作用:清除定时器、移除监听

javascript 复制代码
<script>
export default {
  beforeUnmount(){
    clearInterval(this.timer)
  }
}
</script>
  1. unmounted

含义:组件完全销毁 作用:收尾清理工作

javascript 复制代码
<script>
export default {
  unmounted(){
    console.log('组件已销毁')
  }
}
</script>
  1. props 类型校验

含义:限制传入参数类型 作用:规范传参、控制台报错提示

javascript 复制代码
<script>
export default {
  props:{
    name:String,
    age:Number
  }
}
</script>
  1. props required

含义:强制必须传参 作用:保证组件必备参数

javascript 复制代码
<script>
export default {
  props:{
    title:{
      type:String,
      required:true
    }
  }
}
</script>
  1. props default 默认值

含义:未传参时使用默认值 作用:防止报错、给默认展示

javascript 复制代码
<script>
export default {
  props:{
    msg:{
      type:String,
      default:'默认提示'
    }
  }
}
</script>
  1. props validator 自定义校验

含义:自定义规则校验参数 作用:范围、格式限制

javascript 复制代码
<script>
export default {
  props:{
    score:{
      validator(val){
        return val>=0 && val<=100
      }
    }
  }
}
</script>
  1. props 单向只读

含义:子组件不能修改 props 作用:遵循单向数据流,避免数据混乱

javascript 复制代码
<template>
<view>{{ title }}</view>
</template>
<script>
export default {
  props:['title'],
  methods:{
    change(){
      // 错误:不能修改 props
      // this.title = 'xxx'
    }
  }
}
</script>
  1. 局部 Mixin

含义:抽取公共逻辑复用 作用:复用生命周期、方法、数据

javascript 复制代码
<script>
// 定义混入
const myMixin = {
  created(){console.log('mixin 加载')}
}
export default {
  mixins:[myMixin]
}
</script>
  1. 全局 Mixin

含义:所有组件自动混入 作用:全局公共逻辑

javascript 复制代码
import { createApp } from 'vue'
const app = createApp()
app.mixin({
  mounted(){console.log('每个组件都触发')}
})
  1. Mixin 合并规则

含义:生命周期先执行 mixin 再组件;选项以组件优先 作用:理解覆盖逻辑

javascript 复制代码
<script>
const m = { mounted(){console.log('mixin')}}
export default {
  mixins:[m],
  mounted(){console.log('组件自身')}
}
</script>
  1. 局部自定义指令

含义:封装 DOM 操作逻辑 作用:自动聚焦、权限按钮

javascript 复制代码
<template>
<input v-focus />
</template>
<script>
export default {
  directives:{
    focus:{
      mounted(el){el.focus()}
    }
  }
}
</script>
  1. 全局自定义指令

含义:全局所有组件可用

javascript 复制代码
app.directive('focus',{
  mounted(el){el.focus()}
})
  1. 指令传参

含义:指令可传递参数、修饰符 作用:灵活配置指令行为

javascript 复制代码
<template>
<view v-color="red">文字</view>
</template>
<script>
export default {
  directives:{
    color:{
      mounted(el,binding){
        el.style.color = binding.value
      }
    }
  }
}
</script>
  1. provide 提供

含义:父 / 祖先向下提供数据 作用:多层嵌套不用逐层 props

javascript 复制代码
<script setup>
import { provide } from 'vue'
provide('appName','Vue3项目')
</script>
  1. inject 注入

含义:后代组件接收数据 作用:跨层级取值

javascript 复制代码
<script setup>
import { inject } from 'vue'
const name = inject('appName')
</script>
  1. Teleport

含义:将组件 DOM 传送到指定节点 作用:弹窗、浮层不受父样式嵌套影响

javascript 复制代码
<template>
<teleport to="body">
  <view class="mask">我是全局弹窗</view>
</teleport>
</template>
<style>
.mask{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.5);}
</style>

栗子:

javascript 复制代码
<template>
  <view class="container">
 
    <button @click="showLife = !showLife">显示/隐藏生命周期组件</button>
    <view v-if="showLife">
      <LifeDemo />
    </view>

    <PropsDemo title="我是标题" :score="88" />

    <view class="mt20">
      <input v-focus placeholder="进入页面自动聚焦" class="input" />
    </view>

    <InjectDemo />

    <button @click="showModal = true" class="mt20">打开Teleport弹窗</button>
    <teleport to="body">
      <view v-if="showModal" class="mask">
        <view class="modal-box">
          <text>全局弹窗,不受父样式限制</text>
          <button @click="showModal = false" class="mt20">关闭</button>
        </view>
      </view>
    </teleport>
  </view>
</template>

<script setup>
import { ref, provide } from 'vue'

// 控制生命周期组件显示
const showLife = ref(true)
const showModal = ref(false)

const LifeDemo = {
  created() {
    console.log('1.created 组件创建完成')
  },
  mounted() {
    console.log('2.mounted DOM挂载完毕')
  },
  beforeUnmount() {
    console.log('3.beforeUnmount 准备销毁')
  },
  unmounted() {
    console.log('4.unmounted 组件已销毁')
  },
  template: '<view class="mt20">生命周期组件</view>'
}

const PropsDemo = {
  props: {
    title: {
      type: String,
      default: '默认标题'
    },
    score: {
      type: Number,
      validator: val => val >= 0 && val <= 100
    }
  },
  template: '<view class="mt20">标题:{{title}}  分数:{{score}}</view>'
}

const directives = {
  focus: {
    mounted(el) {
      // 自动聚焦
      el.focus()
    }
  }
}

const myMixin = {
  created() {
    console.log('Mixin 公共逻辑执行')
  }
}

provide('appInfo', {
  name: 'Vue3进阶项目',
  version: '2.0'
})

const InjectDemo = {
  inject: ['appInfo'],
  template: '<view class="mt20">项目名称:{{appInfo.name}}</view>'
}
</script>

<style scoped>
.container {
  padding: 30rpx;
}
.mt20 {
  margin-top: 20rpx;
}
.input {
  border: 1rpx solid #eee;
  padding: 20rpx;
  border-radius: 10rpx;
}
.mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0,0,0,0.5);
  display: flex;
  align-items: center;
  justify-content: center;
}
.modal-box {
  background: #fff;
  padding: 40rpx;
  border-radius: 15rpx;
}
</style>
相关推荐
青山如墨雨如画9 小时前
【Win11下的andrej-karpathy-skills 配置指南】22 万 Star 的极简项目,如何治好 AI 的「过度设计」
前端
sheeta19989 小时前
LeetCode 每日一题笔记 日期:2026.05.21 题目:3043. 最长公共前缀的长度
笔记·算法·leetcode
衫水9 小时前
AI Agent 构建实战笔记(20260524)
人工智能·笔记
逆境不可逃9 小时前
【与我学 ClaudeCode】协作篇 之 Team Protocols :结构化请求 - 响应协作协议
前端
Keep Running *9 小时前
Hermes_学习笔记
笔记·学习
a1117769 小时前
【无标题】
前端·开源·html
晓得迷路了10 小时前
栗子前端技术周刊第 130 期 - Angular 22 RC、Rolldown 1.0.1、pnpm 11.2...
前端·javascript·react.js
审判长烧鸡10 小时前
【AI问答/前端】前端瞒天过海局(三)
前端·vue·html5·js
桔筐10 小时前
【无标题】
前端·vue.js