解决vue3使用ref 获取不到子组件属性问题

需求:

父子组件使用<script setup>语法糖,父组件通过给子组件定义ref访问子组件内部属性或事件。

关键点:

子组件中,setup语法糖需要用defineExpose把要读取的属性和方法单独暴露出去,否则会访问失败;如果子组件使用setup()函数,则在父组件通过ref可以直接访问其属性,不需要用defineExpose暴露数据。

子组件:src/components/BaseInfoDialog.vue

javascript 复制代码
<template>
  <el-dialog v-model="dialogTableVisible" title="Shipping address" width="800">
    <el-table :data="gridData">
      <el-table-column property="date" label="Date" width="150" />
      <el-table-column property="name" label="Name" width="200" />
      <el-table-column property="address" label="Address" />
    </el-table>
  </el-dialog>
</template>

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

const dialogTableVisible = ref(false);

const gridData = [
  {
    date: "2016-05-02",
    name: "John Smith",
    address: "No.1518,  Jinshajiang Road, Putuo District"
  },
  {
    date: "2016-05-04",
    name: "John Smith",
    address: "No.1518,  Jinshajiang Road, Putuo District"
  },
  {
    date: "2016-05-01",
    name: "John Smith",
    address: "No.1518,  Jinshajiang Road, Putuo District"
  },
  {
    date: "2016-05-03",
    name: "John Smith",
    address: "No.1518,  Jinshajiang Road, Putuo District"
  }
];


// 把数据暴露出去供父组件调用
defineExpose({
  dialogTableVisible
});
</script>

父组件:src/App.vue

javascript 复制代码
<script setup lang="ts">
import BaseInfoDialog from "./components/BaseInfoDialog.vue";
import { ref } from "vue";

const childComponentRef = ref(null);

const logChildMessage = () => {
  if (childComponentRef.value) {
    childComponentRef.value.dialogTableVisible = true;
  }
};
</script>

<template>
  <div>
    <div>
      <BaseInfoDialog ref="childComponentRef" />
    </div>
    <div>
      <el-button type="primary" @click="logChildMessage">open dialog</el-button>
    </div>
  </div>
</template>

<style scoped>

</style>

package.json

javascript 复制代码
{
  "name": "latest-vue3-ts",
  "version": "0.0.0",
  "private": true,
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "run-p type-check \"build-only {@}\" --",
    "preview": "vite preview",
    "build-only": "vite build",
    "type-check": "vue-tsc --build --force"
  },
  "dependencies": {
    "element-plus": "^2.7.6",
    "vue": "^3.4.29"
  },
  "devDependencies": {
    "@tsconfig/node20": "^20.1.4",
    "@types/node": "^20.14.5",
    "@vitejs/plugin-vue": "^5.0.5",
    "@vue/tsconfig": "^0.5.1",
    "npm-run-all2": "^6.2.0",
    "typescript": "~5.4.0",
    "unplugin-auto-import": "^0.17.6",
    "unplugin-vue-components": "^0.27.0",
    "vite": "^5.3.1",
    "vite-plugin-vue-setup-extend": "^0.4.0",
    "vue-tsc": "^2.0.21"
  }
}

vite.config.ts

javascript 复制代码
import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import VueSetupExtend from 'vite-plugin-vue-setup-extend'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    VueSetupExtend(),
    AutoImport({
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [ElementPlusResolver()],
    })
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
})
相关推荐
计算机学姐4 小时前
基于SpringBoot的小型民营加油站管理系统
java·vue.js·spring boot·后端·mysql·spring·tomcat
sunbyte6 小时前
50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | Expanding Cards (展开式卡片)
javascript·vue.js·ecmascript
重生之后端学习7 小时前
02-前端Web开发(JS+Vue+Ajax)
java·开发语言·前端·javascript·vue.js
黄鹂绿柳10 小时前
Vue+Vite学习笔记
vue.js·笔记·学习
来自星星的坤10 小时前
【Vue 3 + Vue Router 4】如何正确重置路由实例(resetRouter)——避免“VueRouter is not defined”错误
前端·javascript·vue.js
清风细雨_林木木16 小时前
Vue 中生成源码映射文件,配置 map
前端·javascript·vue.js
繁依Fanyi18 小时前
ColorAid —— 一个面向设计师的色盲模拟工具开发记
开发语言·前端·vue.js·编辑器·codebuddy首席试玩官
codelxy18 小时前
vue引用cesium,解决“Not allowed to load local resource”报错
javascript·vue.js
Zww089119 小时前
el-dialog鼠标在遮罩层松开会意外关闭,教程图文并茂
javascript·vue.js·计算机外设
sunbyte19 小时前
50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | 页面布局 与 Vue Router 路由配置
前端·javascript·vue.js·tailwindcss