VueJs中setup的使用(下)

news2025/1/8 5:58:21

fbbe262827ab83c50a88fb5798862a3b.png

前言

Vue当中,父组件想要向子组件传值,是通过在父组件标签上通过自定义属性实现的,而在子组件中是通过props进行接收

Vue2.0里面,在子组件中的选项式API配置项选项中props进行接收就可以了的,在子组件中的模板中可以直接使用

但在Vue3里面与Vue2.0存在一些差异,这个主要是针对组合式APIsetup函数

01

534c25067f2c1e9ef516454bd7352455.png

setup函数接收第一个参数props

setup函数的第一个参数是接收父组件传递过来的props,这个setup函数的props是响应式的,并且会在传入的新的props时同步更新

如下是父组件的数据

<script setup>
import  Comp  from "./Comp.vue"
import { ref } from 'vue'
const name = "https://coder.itclan.cn"
</script>

<template>
  <Comp :name="name" />
</template>

如下是子组件Comp.vue

export default {
    props: {
        name
    },
    setup(props) {
        console.log(props.name);
    }
}

在模板中渲染

<template>
  <h1>{{name}}</h1>
</template>

那如何去修改模板中的数据呢,这个与Vue2.0绑定事件一样,在模板中,通过v-on@进行绑定,函数则通过function定义在setup里面,同时返回出去

<template>
  <h1>{{name}}</h1>
  <button @click="handleChange">修改</button>
</template>

对应的js

<script>
 import { ref } from 'vue'
 export default {
   props: {    // 必须要声明接收才可以,否则页面数据不会显示
     name
   },
   setup(props){
     console.log(props.name);
     let name = ref(props.name);   // 相当于是对props传递过来的数据做了一份拷贝
     function handleChange() {
        console.log(name.value);
        name.value = "川川"
     }
     return {
       name,
       handleChange
     }
   }
 }
</script>

注意事项

[1]. 想要修改父组件传递过来的props值,接收到的props.name必须要使用ref进行响应式处理,否则的话,修改name的值,页面是不起作用的

[2]. 在逻辑中,需要通过xxx.value才能拿到具体的值

[3]. setup中定义的函数,需要返回出去,否则模板中绑定的函数是无效的

当使用选项式API,方法定义在methods内时,想要访问,修改setup()函数内定义的响应式变量或函数时,可以使用this.setup对外暴露的变量

如下代码所示,Comp.vue,下面的方法是定义methods内的,同样是可以实现同样的功能

<template>
  <h1>{{name}}</h1>
  <button @click="handleChange">修改</button>
</template>
<script>
  import { ref } from "vue"
  export default {
    props: {      // Vue2要用props配置项,声明接收,可以对类型进行控制,当然通过this.$attrs.属性也是可以拿到的,只是这种方式没办法控制类型,使用这种方式,是没有声明props,若声明接收了,则实例上会没有$attrs属性的挂载
        name
    },
    methods: {
      handleChange() {
        console.log(this.name);
        this.name = "itclanCoder";  // 通过this.setup函数对外暴露出去的变量
      }
    },
    setup(props) {
        console.log(props.name);
        let name = ref(props.name);  // 这里的值必须要用ref包裹,否则页面的数据不会响应式
      
        return {
          name
        }
    }
}
</script>

通过上面的代码,在选项式API中可以通过this访问组合式API中的变量数据,也可以得出,组合式API内定义的变量和函数,最终都会变为选项式API的配置选项

在选项式API内,可以通过this访问setup内对外暴露的变量和函数

其实,选项式API是在组合式API的基础上实现的,对于Vue2.0的基础知识,放在Vue3里面,也都是通用的

那不用setup函数,直接在script标签上书写setup,这个setup是在单文件组件(sfc)中使用组合式API编译时的语法糖

如下代码所示Comp.vue

<template>
  <h1>{{name}}</h1>
  <button @click="handleChange">修改</button>
</template>
<script setup>
  import { ref} from "vue"
  // 如果直接使用setup在标签上,那么接收父组件传递过来的值,需要使用defineProps()函数,它不需要从vue当中引入,直接在逻辑中就可以使用,使用的编译器宏。会随着 <script setup> 的处理过程一同被编译掉
  const props = defineProps({
    name: {
      type: String
    }
  })
  // 想要修改父组件的值,需要使用defineEmits(['父组件上定义的事件名'])
  const emit = defineEmits(['handleChangeTxt'])
  let newName = ref("itclanCoder");
  function handleChange() {
    emit('handleChangeTxt',newName);  // 第一个参数值是事件名,第二个是具体要修改的参数值
  }
  
</script>

在父组件中的代码如下所示

<script setup>

import Comp from "./Comp.vue"
import { ref } from 'vue'

let name = ref('https://coder.itclan.cn')  // 原始数据
function handleChangeTxt(event) {
  name.value = event.value;
}
</script>

<template>
  <Comp @handleChangeTxt="handleChangeTxt" :name="name" />
</template>

以上就是通过在setupscript标签上,接入父组件传递过来的值,需要使用defineProps()函数,它不需要从vue当中引入,直接在逻辑中就可以使用,使用的编译器宏。会随着 <script setup> 的处理过程一同被编译掉

且必须要声明defineProps({}),并接收props值,否则的话,页面是没有任何显示的

而若要修改父组件传递过来的props值,是没有办法直接修改的,在Vue当中是数据父组件向子组件传递数据流失单向的,数据的流动方向只能是自上往下的方向

想要修改的话,如果是使用setup()函数的方式,那么需要使用ref包裹接收的props值,如let name = ref(props.name);,否则页面的数据不会响应式

使用选项式API的方法methods修改页面中的数据,还是直接在setup里面,都是可以修改的

但是如果是通过setup形式,那么需要借用defineEmits('定义的事件名'),这里是有一点绕的

import { ref} from "vue"

  // 想要修改父组件的值,需要使用defineEmits(['父组件上定义的事件名'])
  const emit = defineEmits(['handleChangeTxt'])     // 可以是多个,多个事件,用逗号分开defineEmits(['事件名1','事件名2'])
  let newName = ref("itclanCoder");   // 想要修改的值
  function handleChange() {           // 修改的函数
    emit('handleChangeTxt',newName);  // 第一个参数值是事件名,第二个是具体要修改的参数值
  }

当前子组件的模板

<template>
  <h1>{{name}}</h1>
  <button @click="handleChange">修改</button>
</template>

而在父组件中,调用组件处,绑定事件,事件函数中接收一个参数event,携带的是子组件的内传递过来的数据,在父组件中修改数据,从而达到页面的数据的变更

<script setup>
  import Comp from "./Comp.vue"
import { ref } from 'vue'

let name = ref('https://coder.itclan.cn')
function handleChangeTxt(event) {
  name.value = event.value;
}
</script>

<template>
  <Comp @handleChangeTxt="handleChangeTxt" :name="name" />
</template>

注意事项

在使用setup()函数中,如果是通过解构props对象,那么解构出来的变量将会丢失响应式,也就是你改变此数据,页面不会更新,因此官方推荐通过props.父组件传递给子组件的props值的形式来接收props

setup(props) {
   const {name} = props;  // 此时name的响应式值会丢失
   // 官方推荐如下这种形式,同时对传递过来的props值进行响应式数据处理
   const name = ref(props.name);  
}

如果你确定要结构props对象,或需要将某个prop传到一个外部函数中并保持响应式,可以使用toRefs()toRef()这两个组合式API函数

如下示例代码所示

import { toRefs, toRef } from 'vue'

export default {
  setup(props) {
    // 将 `props` 转为一个其中全是 ref 的对象,然后解构
    const { name } = toRefs(props)
    // `title` 是一个追踪着 `props.name` 的 ref
    console.log(name.value)

    // 或者,将 `props` 的单个属性转为一个 ref
    const title = toRef(props, 'name')
  }
}


02

e897f551e96bd211f445c24bf52a926b.png

setup函数的第二个参数context

setup第一个参数是props,它的值是一个proxy对象,接收组件外部传递过来的props值,且在组件内部声明接收了的属性

第二个参数是context,上下文对象,接收外部传递过来的属性,需要关注attrs(相当于vue2.0$attrs)``,emit(触发自定义事件),slots(相当于vue2中的$slots`)

[1]. context.attrs:相当于vue2.0当中的$attrs

[2]. context.emits:相当于vue2.0当中的$emits

如下子组件中Comp.vue

<script>
  export default {
    emits: ['parentFun'],  // 需要声明一下自定义事件,否则会有警告
    setup(props,context) {

      // 子组件绑定的方法
      function childFun() {
        context.emit('parentFun','itclanCoder')
      }

      return {
        childFun
      }
    }
  }
</script>

在父组件中

<template>
   <Comp @parentFun ="showParent"></Comp>
</template>
<script>
  export default {
    setup() {
      function showParent(value) {
        alert("触发了showParent事件,收到的参数是",`${value}`);
      }

      return {
        showParent
      }
    }
  }
</script>

上面的是针对setup函数,如果setup直接写在script上,那么使用defineEmits()

[3]. context.slots: 接收父组件插入的插槽,相当于this.$slots,在vue3中的命名插槽的是v-slot:插槽名字,同时它是使用在template标签上的

上下文对象是非响应式的,可以安全地解构的

export default {
  setup(props, { attrs, slots, emit, expose }) {
    ...
  }
}

需要注意的是,attrsslots 都是有状态的对象,它们总是会随着组件自身的更新而更新。这意味着你应当避免解构它们,并始终通过 attrs.xslots.x的形式使用其中的属性。此外还需注意,和 props不同,attrsslots的属性都不是响应式的。如果你想要基于 attrsslots的改变来执行副作用,那么你应该在 onBeforeUpdate 生命周期钩子中编写相关逻辑

总结

需要知道的是,在使用setup()函数形式时,怎么接收父组件传递过来的值,以及setup直接使用在script标签上的,怎么接收父组件传递过来的值,还有怎么修改

子组件中的数据,分别有两种不同的方式,以及setup()函数的第二个参数上下文对象参数的含义与使用

vuejs中组件的两种不同的编写风格-选项式API及组合式API

2022-12-25

c3c32b02368f3a4f679b3920fcdad545.jpeg

2022-忙碌的一年

2022-12-23

11131ab1d95b1c6c15c47638a9cf2792.jpeg

JS 如何利用浏览器的 cookie 保存用户名

2022-11-09

f538fb825f4103cf793d684488f59826.jpeg

JS如何使用sessionStorage实现计数器功能

2022-11-08

ab8a86e0bebba3e956fa9d2e75662a7e.jpeg
点击左下角查看更多

d9da7c11d5d0abed7bc6da768fbaf610.gif

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

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

相关文章

excel文件管理:如何进行密码保护和破解? 下篇

在上篇文章中&#xff0c;我们提到了设置工作簿的打开权限密码、修改权限密码、保护工作簿的密码、允许编辑区域的密码&#xff0c;并且讲到了两种破解excel密码的方式。今天&#xff0c;我们书接上回&#xff0c;继续讲解excel中常见的密码保护和破解方式&#xff0c;一起来看…

浅谈屏幕适配

文章目录1. 概述2. 屏幕尺寸3. 屏幕分辨率4. 屏幕像素密度5. dp、sp、px6. mdpi、hdpi、xdpi..7. 屏幕分辨率限定符8. 最小宽度限定符8.1 获取设计图最小宽度(dp)8.2 生成对应的dimens.xml文件8.3 尺寸限定符8.4 其它9. 今日头条相关9.1 系统状态栏获取不对问题9.2 autosize1. …

Elasticsearch8.X入门实战(二)Elasticsearch集群架构

Elasticsearch集群由一个或多个节点(服务器)组成,这些节点一起保存Elasticsearch的所有数据,并提供跨所有节点的联合索引和搜索功能。集群由一个唯一的名称来标识,该名称默认为“elasticsearch”(可以在配置文件中修改)。当某个节点被设置为相同的集群名称时,该节点才能…

Docker容器的简单介绍与使用

前言&#xff1a;大家好&#xff0c;我是小威&#xff0c;24届毕业生&#xff0c;曾经在某央企公司实习&#xff0c;目前入职某税务公司。本篇文章将记录和分享docker容器相关的知识点。 本篇文章记录的基础知识&#xff0c;适合在学Java的小白&#xff0c;也适合复习中&#x…

如何更好地进行 Android 组件化开发——路由原理篇

前言 组件化开发的会实现代码隔离&#xff0c;在开发时访问不到模块的代码&#xff0c;降低代码耦合度。那么如何跳转组件的页面、如何进行组件间的通信是个问题。这通常会使用到 ARouter、TheRouter、WMRouter 等路由框架。可能有不少人只知道怎么去调用&#xff0c;并不知道…

Pod内容详情梳理

本篇是笔者的一篇读书笔记&#xff0c;用于梳理pod的详情&#xff0c;方便理解和学习&#xff0c;也方便后续自己查询。一、Pod的概述Pod是k8s里面典型的CR&#xff0c;从它的元数据来看&#xff0c;具有所有CR的基本数据构成&#xff0c;分别是 version、kind&#xff0c;以及…

迅为RK3568开发板支持多屏同显/异显动态方案

iTOP-RK3568开发板采用四核Cortex-A55处理器&#xff0c;芯片内置VOP控制器&#xff0c;支持HDMI、LVDS、MIPI、EDP四种显示接口的多屏同显、异显和异触&#xff0c;可有效提高行业定制的拓展性。 三屏同显&#xff1a; 三屏异显&#xff1a; 双屏同显&#xff1a; 双屏异显&am…

Docker容器里进程的 pid 是如何申请出来的?

大家好&#xff0c;我是飞哥&#xff01;如果大家有过在容器中执行 ps 命令的经验&#xff0c;都会知道在容器中的进程的 pid 一般是比较小的。例如下面我的这个例子。# ps -ef PID USER TIME COMMAND1 root 0:00 ./demo-ie13 root 0:00 /bin/bash21 root …

编程小技巧9-如何生成没有水印的代码图片(IDEA carbon-now-sh插件使用教程)

陈老老老板&#x1f9b8;&#x1f468;‍&#x1f4bb;本文专栏&#xff1a;快速变成小技巧&#xff08;主要讲一些平时常用的、有助于提高开发素的内容&#xff09;&#x1f468;‍&#x1f4bb;本文简述&#xff1a;本文讲一下使用carbon-now-sh插件生成图片超详细教程。&…

STM32

一&#xff1a;生成独立的他.h和.c文件 勾选后&#xff0c;生成单独的.h和.c文件。不勾选的话都在main里面。 二&#xff1a;常用。 1&#xff1a;电平输出。 HAL_GPIO_WritePin(PIN_LED_1_GPIO_Port, PIN_LED_1_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(PIN_LED_1_GPIO_Port, …

django 登录流程实现

一、简介&#xff1a; 1、用户输入正确的用户名、密码、验证码点击登录即可跳转到管理员页面。 2、用户输入错误的用户名或者密码或者验证码需要错误信息提示&#xff08;数据校验&#xff09; 二、实现步骤 1、新建一个项目&#xff08;创建项目过程和数据库略&#xff0c;…

签完三方后无法去实习,有什么可以弥补的吗?

作者&#xff1a;阿秀校招八股文学习网站&#xff1a;https://interviewguide.cn这是阿秀的第「228」篇原创你好&#xff0c;我是阿秀。2023届秋招已经步入尾声&#xff0c;很多小伙伴都已经找到工作&签约三方&#xff0c;慢慢结束了自己的秋招之旅&#xff0c;不过也有一些…

Local Attention和动态深度卷积间的关系

摘要 Local Vision Transformer 是分别在一个个小的局部窗口中进行注意力计算。 作者将局部注意力重新定义为通道级的局部连接层&#xff08;channel-wise locally-connected layer&#xff09;&#xff0c;并4个方面进行分析&#xff1a;两种网络的正则化方式&#xff0c;稀疏…

C语言实现九大排序算法(建议收藏!)

文章目录排序算法稳定性1. 插入排序原理排序过程代码实现性能分析2. 希尔排序原理排序过程关于增量取值代码实现性能分析3. 选择排序原理排序过程代码实现性能分析4. 堆排序原理排序过程代码实现性能分析5. 冒泡排序原理排序过程代码实现性能分析6. 快速排序原理Hoare法挖坑法前…

Easy App Locker - 给你的 mac 应用加锁保护你的隐私

Easy App Locker - 给你的 mac 应用加锁保护你的隐私 Easy App Locker可以对Mac上的单个应用进行密码保护。维护Mac上的隐私。 像如果你的某个应用存在隐私数据就可以使用该软件将此应用上锁&#xff0c;这样当你的朋友使用你的 mac 时你就不用担心你的隐私被泄露了&#xff0…

Java中创建线程的五种方式

目录&#xff1a; 前言 1.进程与线程的区别&#xff1f; 2.进程是操作系统进行资源分配的基本单位&#xff0c;而操作系统是以线程为单位进行调度的。 3. Java操作多线程&#xff0c;依赖最核心的类Thread。 4.关于start和run的区别&#xff1f; 5.使用JDK自带的工具jcon…

ArcGIS基础实验操作100例--实验7分割多部分要素

本实验专栏来自于汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 基础编辑篇--实验7 分割多部分要素 目录 一、实验背景 二、实验数据 &#xff08;1&#xff09;查看多…

第05讲:Redis主从复制

一、关于主从复制 1.1、什么是主从复制 主机数据更新后根据配置和策略&#xff0c; 自动同步到备机的master/slaver机制&#xff0c;Master以写为主&#xff0c;Slave以读为主 1.2、主从复制的作用 读写分离&#xff0c;性能扩展容灾快速恢复 二、一主多从的实验 2.1、原…

GitHub+HEXO博客设置主题

文章目录安装主题修改站点配置文件修改主题配置文件部署到github补充由于之前使用HexoGitHub搭建了个人博客用的是最原始的主题&#xff0c;丑的一批QAQ 用一下Github上面Star最高Next主题look look&#xff01; 上节博客&#xff1a;HexoGitHub搭建个人博客 主题选取网站&a…

CnOpenData中国工业企业基本信息扩展数据

一、数据简介 拉动中国经济的三个产业中&#xff0c;工业企业占有特殊的地位&#xff0c;是推动国内经济发展的重要产业。工业是最主要的物质生产部门&#xff0c;为居民生活、各行业的经济活动提供物质产品&#xff0c;这一重要作用是其他任何产业部门都无法替代的。工业企业为…