vue3 setup语法糖,常用的几个:defineProps、defineEmits、defineExpose、

news2024/11/17 13:47:06

vue3和vue2组件之间传参的不同

<script setup> 是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。

<script setup> 中的代码会在每次组件实例被创建的时候执行

任何在 <script setup> 声明的顶层的绑定 (包括变量,函数声明,以及 import 导入的内容) 都能在模板中直接使用,使用双花括号:{{自定义的声明}}。

在 <script setup> 中要使用动态组件的时候,应该使用动态的 :is 来绑定,结合三元运算符。

效果展示:

一、defineProps父传子

理论知识:

父组件通过 :传参名=“传递的数据” 向子组件传递参数

子组件通过 defineProps<{接收的数据}>() 来接收数据

在 script setup 中,引入的组件会自动注册,所以可以直接使用,无需再通过components进行注册。 

 代码:

父组件:

<div class="projects">实际已维修项目</div>
<AllTable
     :widthIndex="100"
     :AllTableData="data.AllTableData"
     :tableColumns="data.tableColumns"
     :heights="data.heights"
     :option="true"
     @changeTbaleData="changeTbaleData"
></AllTable>
<div class="isNewOpenD">
    <el-button
      type="primary"
      plain
      class="mt-4"
      style="width: 100%"
      @click="handleNew"
      >
         维修项目新增
     </el-button>
</div>

 

<script setup>
const changeTbaleData = (value) => {
  data.AllTableData = value;
};
const data = reactive({
  AllTableData:[],

})
</script>

二、defineEmits子传父

在Vue 3中,可以使用 defineEmits 函数来声明子组件可以触发的事件。该函数需要在子组件中使用,并且需要在 setup 函数中调用 。

理论知识:

父组件通过@绑定子组件注册好的事件名,在父组件中进行处理子组件传过来的value

子组件通过两点:

1.defineEmits()函数用来声明子组件可以触发的事件

   语法:const 事件名 = difineEmits(['事件'])

2.在"事件"方法内部,使用注册好的事件,向父组件传参

   语法:声明的事件名('事件',传递的数据)

理论知识代码:

 

子组件:

//封装组件:AllTable.vue
<template>
  <el-table :data="props.AllTableData" :height="props.heights" style="width: 100%"
    :cell-style="{ textAlign: 'center' }" :header-cell-style="{ 'text-align': 'center' }">
    <el-table-column type="index" label="序号" :width="props.widthIndex" />
    <template v-for="(item, index) in props.tableColumns" :key="index">
      <el-table-column :prop="item.value" :label="item.name" width="" :show-overflow-tooltip="true">
      </el-table-column>
    </template>
<el-table-column label="操作" v-if="props.option">
      <template #default="scope">
        <el-popconfirm title="你确定要删除吗?" confirm-button-text="确认" cancel-button-text="取消"
          @confirm="confirmOption(scope.$index)" @cancel="cancelOption(scope.$index)">
          <template #reference>
            <el-button link type="danger" size="small">
              删除
            </el-button>
          </template>
        </el-popconfirm>
      </template>
    </el-table-column>
  </el-table>
</template>
<script setup>
const emits = defineEmits(["changeTbaleData"])
const props = defineProps({
  widthIndex: {
    type: Number,
    default: 180
  },
  AllTableData: Object,
  tableColumns: Object,
  heights: String,
  option: {
    type:Boolean,
    default:false
  },
})
const confirmOption = (index) => {
  props.AllTableData.splice(index, 1)
  emits("changeTbaleData", props.AllTableData)
}
const cancelOption = (index) => {
  ElMessage({
    message: '取消。',
    type: 'warning',
  })
}
</script>

写到这儿,在vue开发中,常用的组件之间就上面两种方式。

但,当情景不止是父<——>子 之间通讯,可以考虑inject注入、defineExpose()暴露、pinia(或vuex) 

 三、defineExpose 获取子组件的实例和内部属性

子组件将方法、变量暴露给父组件使用,父组件才可通过 ref API拿到子组件暴露的数据。

效果展示:

参考链接:defineexpose的使用

在vue2中,通常会在子组件便签上加,ref来获取子组件的实例和属性方法,在 Vue3的script-setup 模式下,所有数据只是默认 return 给 template 使用,不会暴露到组件外,所以父组件是无法直接通过挂载 ref 变量获取子组件的数据。

如果要调用子组件的数据,需要先在子组件显示的暴露出来,才能够正确的拿到,defineExpose可以实现

1.父组件通过ref中访问子组件的方法、变量

2.子组件中,子组件的方法、变量需要通过defineExpose暴露出去

 代码:

<SelectMaterial ref="selectMaterial"></SelectMaterial>
const selectMaterial = ref();
const selectSystemMaterial = () => {
  //打开弹框
  selectMaterial.value.Open(true);
};

弹框组件:

//弹框组件封装
 <!-- >>> 打开新增弹框 -->
    <MaintainTableDialog
      v-model:modelValue="data.isOpenDialog" //备注:弹框打开与否
      :footer="data.dialogTitle != '查看' ? data.isShowFooter : true"
      :title="'维修项目新增'"
      :dialogWidth="'50%'"
    >
      <template #default>
        <el-table
          ref="multipleTableRef"
          :data="data.mytableData"  //备注:弹框表格的数据
          style="width: 100%"
          height="50vh"
          :row-key="bindRowKeys"
        >
          <el-table-column
            type="selection"
            width="55"
            :reserve-selection="true"
          ></el-table-column>
          <el-table-column type="index" label="序号" width="70" />
          <el-table-column prop="classifyName" label="设备分类" width="170" />
          <el-table-column
            prop="no"
            label="项目编号"
            width="160"
            :show-overflow-tooltip="true"
          />
          <el-table-column
            prop="name"
            label="项目名称"
            width="190"
            :show-overflow-tooltip="true"
          />
          <el-table-column prop="period" label="周期" width="100" />
          <el-table-column prop="manager" label="负责人" width="100" />
        </el-table>
      </template>
      <template #footer>
        <div class="footer-btn">
          <el-button
            type="primary"
            @click="clickNewDialog"
            :loading="data.isLoading"
            class="submit"
            >确认</el-button
          >
          <el-button @click="data.isOpenDialog = false">取消</el-button>
        </div>
      </template>
    </MaintainTableDialog>
<script setup>
const Open = (isAdd) => {
  data.isOpenDialog = isAdd || true;
  data.mytableData = store.selectMaterilReqList;
};
//父组件中访问子组件的方法或者变量需要通过defineExpose暴露出去
defineExpose({
  Open,
});
</script>

写到这儿,以上就是difineExpose()的用法 。

以下是调取接口——数据回显——选中数据传参,可选看

 代码(打开弹框调取接口——数据回显):

const handleNew = () => {
  data.isOpenDialog = !data.isOpenDialog;
  const params = {
    shipGuid: data.ruleForm.shipGuid,
    category: 2,
  };
  console.log(data.AllTableData)
  api.getMaintainItems.post(params).then((res) => {
    // data.mytableData = res.data.data;
    //!!!提示:首先打开弹框把“多选”勾选的数据置空,因为在之后会赋值选中的效果
    multipleTableRef.value.clearSelection();
    let itemGuidLists=[]
    data.AllTableData.forEach(item=>{
      itemGuidLists.push(item.itemGuid)
    })
    console.log(itemGuidLists)
    data.mytableData=res.data.data.filter(item=>{
      if(itemGuidLists.indexOf(item.itemGuid)<0){
        //备注:只显示未勾选的。只显示未选择的
        return true  
      }else{
        return false
      }
    })
    // data.AllTableData.forEach((row) => {
    //   data.mytableData.map((item) => {
    //     if (row.itemGuid == item.itemGuid) {
             //备注:显示所有,并勾选计划内选中的。显示:有选中和未选择的
             //!!!提示:设为true,多选框选中
    //       multipleTableRef.value.toggleRowSelection(item, true);
    //     }
    //   });
    // });
  });
};

代码(选中传数据):

<el-button
   type="primary"
   @click="clickNewDialog"
   :loading="data.isLoading"
   class="submit"
>确认
</el-button>
<script setup>
const clickNewDialog = (val) => {
  data.isOpenDialog = false;//关闭子弹框
  const selectData = multipleTableRef.value.getSelectionRows();//获取多选,选中的项,
  //比较子弹框传的 和 父列表展示的 ,不存在添加到父列表
  const guidData = data.AllTableData.map((item) => {
    return item.itemGuid;
  });
  selectData.map((item) => {
    // [].indexof() == -1 不存在
    if (guidData.indexOf(item.itemGuid) < 0) {
      data.AllTableData.push(item);
    }
  });
};
</script>

 四、inject注入式父子组件传参

父组件可以向子组件(无论层级)注入依赖,每个子组件都可以获得这个依赖,无论层级。

参考链接:依赖注入

 

代码:

//父组件
<script setup>
import { ref, provide } from 'vue'
import { fooSymbol } from './injectionSymbols'
provide('foo', 'bar')// 提供静态值
const count = ref(0)// 提供响应式的值
provide('count', count)
provide(fooSymbol, count)// 提供时将 Symbol 作为 key
provide('parentData', data.msg);// 提供默认值

const data = reactive({
    msg: "我是父组件的数据",
})
</script>
//子组件
<script setup>
import { inject } from 'vue'
import { fooSymbol } from './injectionSymbols'

// 注入不含默认值的静态值
const api = inject('parentData')
// 注入响应式的值
const count = inject('count')
// 通过 Symbol 类型的 key 注入
const foo2 = inject(fooSymbol)
// 注入一个值,若为空则使用提供的默认值
const bar = inject('foo', 'default value')
// 注入一个值,若为空则使用提供的函数类型的默认值
const fn = inject('function', () => {})

</script>
<template>
    <template>
    <p>我是子组件</p>
    <p>parent组件数据:{{api.parentData}}</p>
    <p>parent组件数据:{{parentData}}</p>
</template>

写到这儿,以上就是注入依赖的用法。 

实际代码,可选看

在项目里,用到最多的是:

1、封装的axios,用于发起网络请求

2、封装的echart,用于调用原生的ecahrt

 在整个项目的main.js文件,

provide():提供一个值,可以被后代组件注入。

//main.js
import * as api from './api/index'
import * as echarts from 'echarts'
import App from './App.vue'
const app = createApp(App);
//演示:
app.provide('$api', api);
app.provide('$echarts', echarts);
app.mount('#app')

inject():注入一个由祖先组件或整个应用 (通过 app.provide()) 提供的值。 

//任何一个vue页面组件
<script setup>
  const api = inject("$api");
  //...调取接口
  api.某某

const _echarts = inject("$echarts");
 myCharts = _echarts.init(
      myChart.value,
      {
        width:"100%",
        height:"100%",
      },
      {
        renderer: "svg",
      }
    );

    window.addEventListener("resize", function () {
      myCharts && myCharts.resize();
    });
</script>

 

 

 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1261937.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

食材管家,轻松搞定!商户选择生鲜配送系统的原因

随着消费者对生鲜食品的需求不断增加&#xff0c;生鲜市场逐渐成为了电商领域中的热门行业。而生鲜配送系统&#xff0c;则是生鲜电商发展中不可或缺的一部分。本文将探讨商户选择生鲜配送系统的几个原因。 1. 提高效率 生鲜配送系统通过智能化的订单处理、路线规划和配送优化…

2023.11.27 关于 Mybatis 增删改操作

目录 引言 增加用户操作 删除用户操作 修改用户操作 阅读下述文章之间 建议点击下方链接先了解 MyBatis 的创建与使用 MyBatis 的创建与使用 建议点击下方链接先了解 单元测试 的创建与使用 Spring Boot 单元测试的创建与使用 引言 为了方便下文实现增、删、改操作我们先…

java多线程-扩展知识三:乐观锁与悲观锁

1、悲观锁 悲观锁有点像是一位比较悲观&#xff08;也可以说是未雨绸缪&#xff09;的人&#xff0c;总是会假设最坏的情况&#xff0c;避免出现问题。 悲观锁总是假设最坏的情况&#xff0c;认为共享资源每次被访问的时候就会出现问题(比如共享数据被修改)&#xff0c;所以每次…

Appium 2 和 Appium Inspector 环境部署

前言 自 2022 年 1 月 1 日起&#xff0c;Appium 核心团队不再维护 Appium 1.x。官方支持的平台驱动程序的所有最新版本均不兼容 Appium 1.x&#xff0c;需要 Appium 2 才能运行。 Appium 2是一个自动化移动应用程序的开源工具&#xff0c;它带来了以下重要改进&#xff1a;  …

SpringBootWeb案例_01

Web后端开发_04 SpringBootWeb案例_01 原型展示 成品展示 准备工作 需求&环境搭建 需求说明&#xff1a; 完成tlias智能学习辅助系统的部门管理&#xff0c;员工管理 环境搭建 准备数据库表&#xff08;dept、emp&#xff09;创建springboot工程&#xff0c;引入对应…

神经网络核心组件和流程梳理

文章目录 神经网络核心组件和流程梳理组件流程 神经网络核心组件和流程梳理 组件 层&#xff1a;神经网络的基本结构&#xff0c;将输入张量转换为输出张量。模型&#xff1a;由层构成的网络。损失函数&#xff1a;参数学习的目标函数&#xff0c;通过最小化损失函数来学习各…

HCIP-十一、BGP反射器和联盟

十一、BGP反射器和联盟 实验拓扑实验需求及解法1.配置各设备的接口 IP 地址。2.BGPAS 规划3.BGP 反射器4.BGP 联盟5.ebgp 邻居6.bgp 路由汇总 实验拓扑 实验需求及解法 本实验模拟 BGP 综合网络拓扑&#xff0c;完成以下需求&#xff1a; 1.配置各设备的接口 IP 地址。 所有…

这些汽车托运套路你肯定不知道

这些汽车托运套路你肯定不知道 这些套路你肯定不知道.. 学会这三招 汽车托运不怕吃亏 1 看营业执照 首先确定选择的托运公司是否有保障 要求公司出示营业执照和道路运输经营许可证 如果都没有 那就很有可能是无牌照的小作坊!! 这种出问题就肯定没保障 2 保险跟合同 一车一合同 …

安卓系统修图软件(三)

在之前的推送里面&#xff0c;博主分享过两期关于安卓手机的优质修图软件&#xff0c;今天&#xff0c;博主将带来第三期的分享&#xff0c;这也将是该栏目的最后一期。 之前的8款软件&#xff0c;都是以美化、滤镜的风格为主&#xff0c;今天博主带来的这3款&#xff0c;则是以…

数据结构与算法的精髓是什么?复杂度分析【数据结构与算法】

代码跑一遍存在什么问题&#xff1f;什么是 O 复杂度表示法&#xff1f;如何分析时间复杂度&#xff1f;常见时间复杂度量级有哪些&#xff1f;O(1)O(logn)O(n)O(nlogn)O(mn)O(m*n)O(n^2)O(2^n)O(n!)不同时间复杂度差距有多大&#xff1f;时间复杂度分析总结 如何分析空间复杂度…

2021年06月 Scratch图形化(四级)真题解析#中国电子学会#全国青少年软件编程等级考试

Scratch等级考试(1~4级)全部真题・点这里 一、单选题(共10题,每题2分,共20分) 第1题 执行下列程序,输出的结果为? A:12 B:24 C:8 D:30 答案:B 第2题 执行下列程序,角色说出的内容是? A:2 B:3 C:4 D:5 答案:A 第3题 执行下列程序,输出结果为?

Spring Security 6.x 系列(5)—— Servlet 认证体系结构介绍

一、前言 本章主要学习Spring Security中基于Servlet 的认证体系结构&#xff0c;为后续认证执行流程源码分析打好基础。 二、身份认证机制 Spring Security提供个多种认证方式登录系统&#xff0c;包括&#xff1a; Username and Password&#xff1a;使用用户名/密码 方式…

接口测试:Jmeter和Postman测试方法对比

前阶段做了一个小调查&#xff0c;发现软件测试行业做功能测试和接口测试的人相对比较多。在测试工作中&#xff0c;有高手&#xff0c;自然也会有小白&#xff0c;但有一点我们无法否认&#xff0c;就是每一个高手都是从小白开始的&#xff0c;所以今天我们就来谈谈一大部分人…

Leetcode98 验证二叉搜索树

题意理解&#xff1a; 首先明确二叉树的定义&#xff0c;对于所有节点&#xff0c;根节点的值大于左子树所有节点的值&#xff0c;小于右子树所有节点的值。 注意一个误区&#xff1a; 根节点简单和左孩子&#xff0c;右孩子比大小是不够的&#xff0c;要和子树比&#xff0c;…

30.0/集合/ArrayList/LinkedList

目录 30.1什么是集合? 30.1.2为什么使用集合 30.1.3自己创建一个集合类 30.1.3 集合框架有哪些? 30.1.2使用ArrayList集合 30.2增加元素 30.3查询的方法 30.4删除 30.5 修改 30.6泛型 30.1什么是集合? 我们之前讲过数组&#xff0c;数组中它也可以存放多个元素。集合…

C++基础 -6-二维数组,数组指针

二维数组在内存中的存放方式和一维数组完全相同 下表把二维数组抽象成了行列形式方便理解 a[0]指向第一行首元素地址 a指向第一行的首地址 所以a地址和a[0]地址相同,因为起点相同 但a[0]1往右偏移 但a1往下方向偏移 方便理解 an控制行 a[0]n控制列(相当于*an) 数组指针指向二…

【EI会议投稿】第四届物联网与智慧城市国际学术会议(IoTSC 2024)

第四届物联网与智慧城市国际学术会议 2024 4th International Conference on Internet of Things and Smart City 继IoTSC前三届的成功举办&#xff0c;第四届物联网与智慧城市国际学术会议&#xff08;IoTSC 2024&#xff09;将于2024年3月22-24日在河南洛阳举办。 智慧城市的…

Redis常用操作及应用(二)

一、Hash结构 1、常用操作 HSET key field value //存储一个哈希表key的键值 HSETNX key field value //存储一个不存在的哈希表key的键值 HMSET key field value [field value ...] //在一个哈希表key中存储多个键值对 HGET key fie…

二叉树OJ题讲解之一

今天我们一起来做一道初级的二叉树OJ题&#xff0c;都是用递归思想解答 力扣965.单值二叉树 链接https://leetcode.cn/problems/univalued-binary-tree/description/ 所谓单值二叉树就是这棵二叉树的所有节点的值是相同的&#xff0c;那我们要做这道题&#xff0c;肯定要…

sql注入靶场

第一关&#xff1a; 输入&#xff1a;http://127.0.0.1/sqli-labs-master/Less-1/?id1 http://127.0.0.1/sqli-labs-master/Less-1/?id1%27 http://127.0.0.1/sqli-labs-master/Less-1/?id1%27-- 使用--来闭合单引号&#xff0c;证明此处存在字符型的SQL注入。 使用order …