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>
相关推荐
林希_Rachel_傻希希18 小时前
学React治好了我的焦虑症,1小时速通React 前20分钟。
前端·javascript·面试
Cache技术分享18 小时前
435. Java 日期时间 API - Clock 灵活获取当前时间
前端·后端
独泪了无痕19 小时前
Vue3中防御XSS攻击的“特效药”-DOMPurify
前端·vue.js·安全
小小199219 小时前
idea 配置less转化为css
前端·css·less
hhb_61819 小时前
Less嵌套避坑:优先级冲突实战解析
前端·css·less
hhcgchpspk20 小时前
汇编语言传递数据和地址的误区
汇编·笔记·nasm·masm
智者知已应修善业20 小时前
【51单片机2个外部中断显示中断历时,初始化8左移3位共阳数码管】2024-6-6
c++·经验分享·笔记·算法·51单片机
云水一下20 小时前
Vue.js从零到精通系列(五):全局状态管理——Pinia 核心与实践
前端·javascript·vue.js
我不是外星人20 小时前
浅谈我对 AI 发展的看法
前端·ai编程·claude
老马聊技术20 小时前
AI对话功能之SpringBoot整合Vue3
vue.js·人工智能·spring boot·后端