程序员scholar 程序员scholar
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
npm

(进入注册为作者充电)

  • Vue2

  • Vue3

    • 初识Vue3
    • 组合式API
    • Vue3中的data数据
    • vue3 的 script标签
    • setup函数中执行顺序
    • toRefs() 与 toRef()
    • computed()
    • Vue3弱化this
    • watch() 和 watchEffec()
    • define函数用法
    • defineExpose() 和 ref 属性
      • 1. defineExpose 函数
        • defineExpose 语法格式
        • 使用 defineExpose 示例
      • 2. 标签的 ref 属性
        • 用在普通 DOM 标签上
        • 用在组件标签上
    • vue.config.js
    • 生命周期
    • Vue3全局API调用
    • 自定义 Hook
    • 传递数据(props)
    • 路由
    • pinia
    • 组件通信
    • getCurrentInstance() 和 nextTick()
    • Vue3 新组件
  • vue3 + TS 项目集成

  • Vue全家桶
  • Vue3
scholar
2024-08-05
目录

defineExpose() 和 ref 属性

# defineExpose() 和 ref 属性

# 1. defineExpose 函数

defineExpose 是 Vue 3 中的新 API,用于显式暴露子组件的数据或方法给父组件。它通常用于 <script setup> 语法下,让父组件可以访问和调用子组件中的数据和方法。

在 Vue 2 中,父组件可以通过 $refs 获取子组件实例并调用其方法。然而,在 Vue 3 的 <script setup> 语法下,组件实例不再自动暴露给外部。为了解决这个问题,Vue 3 引入了 defineExpose 函数。

通过 defineExpose 函数可以将子组件的方法和数据暴露出去。任何组件在获取了子组件的引用实例后,都可以直接调用子组件暴露出去的方法或访问其数据。

# defineExpose 语法格式

import { ref, defineExpose } from 'vue';

// 定义子组件的数据或方法
let name = ref('张三');
let age = ref(18);

// 使用 defineExpose 函数暴露数据或方法给父组件
defineExpose({
  name,
  age,
  someMethod() {
    console.log('子组件的方法');
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 使用 defineExpose 示例

子组件通过defineExpose暴露数据

<script lang="ts" setup>
import { ref, defineExpose } from 'vue';

// 定义子组件的数据或方法
let name = ref('张三');
let age = ref(18);

function someMethod() {
  console.log('子组件的方法');
}

// 使用 defineExpose 函数暴露数据或方法给父组件
defineExpose({
  name,
  age,
  someMethod
});
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

父组件调用子组件暴露出去的数据

<template>
  <Person ref="personRef"/>
  <button @click="test">测试</button>
</template>

<script lang="ts" setup>
import { ref } from 'vue';
import Person from './components/Person.vue';

// 定义 ref 引用,用于获取子组件实例
let personRef = ref<{ name: string; age: number; someMethod: () => void } | null>(null);

// 方法:测试组件实例
function test() {
  if (personRef.value) {
    // 访问子组件暴露的数据
    console.log(personRef.value.name); // 打印子组件的 name
    console.log(personRef.value.age); // 打印子组件的 age
    // 调用子组件暴露的方法
    personRef.value.someMethod(); // 调用子组件的方法
  }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

总结

  • defineExpose 是 Vue 3 中用于显式暴露子组件数据和方法给父组件的 API。
  • 它解决了 <script setup> 语法下无法自动暴露子组件实例的问题。
  • 通过 defineExpose,父组件可以方便地访问子组件的状态和方法,增强了组件之间的交互性和可维护性。

# 2. 标签的 ref 属性

作用:用于注册模板引用。

  • 用在普通 DOM 标签上,获取的是 DOM 节点。
  • 用在组件标签上,获取的是组件实例对象。

# 用在普通 DOM 标签上

步骤

  1. 在普通 DOM 标签上添加 ref 属性并指定引用名。
  2. 在 <script> 中通过 ref 函数创建对应引用,并初始化为 null。
  3. 通过引用的 value 属性访问 DOM 节点。
<template>
  <div class="person">
    <h1 ref="title1">尚硅谷</h1>
    <h2 ref="title2">前端</h2>
    <h3 ref="title3">Vue</h3>
    <input type="text" ref="input"> <br><br>
    <button @click="showLog">点我打印内容</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import { ref } from 'vue';

// 定义 ref 引用
let title1 = ref<HTMLElement | null>(null);
let title2 = ref<HTMLElement | null>(null);
let title3 = ref<HTMLElement | null>(null);
let input = ref<HTMLInputElement | null>(null);

function showLog() {
  // 通过 id 获取元素
  const t1 = document.getElementById('title1');
  
  // 打印内容,通过 id 获取的元素
  console.log((t1 as HTMLElement).innerText); // 使用 as 进行类型断言
  console.log((<HTMLElement>t1).innerText); // 使用 <类型> 进行类型断言
  console.log(t1?.innerText); // 使用可选链操作符
  
  /************************************/
  
  // 打印内容,通过 ref 获取的元素
  console.log(title1.value?.innerText); // 打印 title1 内容
  console.log(title2.value?.innerText); // 打印 title2 内容
  console.log(title3.value?.innerText); // 打印 title3 内容
  console.log(input.value); // 打印 input 节点
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

# 用在组件标签上

步骤

  1. 在组件标签上添加 ref 属性并指定引用名。
  2. 在 <script> 中通过 ref 函数创建对应引用,并初始化为 null。
  3. 在子组件中使用 defineExpose 函数暴露需要给父组件访问的数据或方法。
  4. 通过引用的 value 属性访问组件实例对象。
<!-- 父组件App.vue -->
<template>
  <Person ref="ren"/>
  <button @click="test">测试</button>
</template>

<script lang="ts" setup name="App">
import { ref } from 'vue';
import Person from './components/Person.vue';

// 定义 ref 引用
let ren = ref<{ name: string; age: number } | null>(null);

function test() {
  if (ren.value) {
    console.log(ren.value.name); // 打印子组件的 name
    console.log(ren.value.age); // 打印子组件的 age
  }
}
</script>

<!-- 子组件Person.vue -->
<script lang="ts" setup name="Person">
import { ref, defineExpose } from 'vue';

// 定义子组件的数据
let name = ref('张三');
let age = ref(18);

// 使用 defineExpose 将组件中的数据暴露给外部
defineExpose({ name, age });
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
编辑此页 (opens new window)
上次更新: 2025/01/30, 23:55:43
define函数用法
vue.config.js

← define函数用法 vue.config.js→

Theme by Vdoing | Copyright © 2019-2025 程序员scholar
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式