Vue的传值

news2024/12/24 20:58:34

目录

1. 属性传值

1.1 语法

1.2 属性和数据源同名

2. 反向传值

2.1 属性绑定+自定义事件

简单案例:

购物车算总价案例:

2.2 v-model 组件的双向数据绑定

3. 透传(多层组件传值)

3.1 类型透传

3.2 属性穿透 v-bind="$attrs"

 3.3 方法穿透 v-on="$listeners"

 4. 获取组件

5. 依赖provide注入indect


1. 属性传值

1.1 语法

父组件中,其中msg是父组件的数据

// 静态传值 直接将静态数据hello传过去
<Box1 title="hello"></Box1>
// 动态传值 msg为app父组件的数据源
<Box1 :title="msg"></Box1>

子组件中,当数据源中没有同名的数据时,可以通过this来访问这个属性

<!-- template标签中——使用 -->
<h2>box1组件-----{{ title }}</h2>

//script标签中——注册
    props:["title"],

    methods: {
        fn() {
            console.log(this.title);
        }
    },

结果:

1.2 属性和数据源同名

当属性和数据源中的data的数据同名时:vue2.x劫持的顺序不同 所有有优先级;vue3.x data中的同名数据不做代理(不生效)

子组件的模板中显示的是属性传值过来的内容,访问时,得到的是子组件本身数据源中的数据,并且会报警告。

子组件不能通过this直接修改这个同名变量(vue2.x可以直接修改同名变量的值,且子组件模板会刷新,但父组件数据不变;vue3.x不可以,会报错,title为只读)

原因: 单向数据流:数据只能由父级组件流向子组件(父级组件的数据源更新,会重新刷新模板,重新传新的属性,两个模板都会刷新)。反过来,数据不能由子级组件流向父级组件(会造成死循环),否则程序混乱且难以管理

注:vue2.0 一个template标签只能有一个根元素(简单说就是只能有一个div标签,其余的都在这个div中写);vue3.0解决了这个问题,但还是使用2.0的习惯吧

补充知识:函数声明在a作用域,在b作用域调用,那它就在声明作用域中运行

2. 反向传值

像上面可以知道,子组件不能修改父组件传过来的值,但在实际开发中还是需要通过子组件来修改父组件中的数据,那这个时候就需要通过反向传值,将子组件的值传给父组件。

2.1 属性绑定+自定义事件

子级组件想要修改父级组件的数据,需要绑定事件,将子级组件修改的数据通过事件的实参传给父级组件,然后再把父级组件的数据改为子级组件传过来的数据,从而刷新页面。

语法:

父组件:监听事件<Box :title="msg" @myevent="(el)=>{this.msg=el}" />

Box子组件内部:触发事件 this.$emit("myevent","传参数")

简单案例:

//父组件
<Box1 :title="msg" @myevent="box1_change_msg"></Box1>
//方法,监听自定义事件myevent
methods: {
    box1_change_msg(arg) {
      this.msg = arg;
    }
  }

//box1子组件
<h2>box1组件-----{{ title }}</h2>
<button @click="change_app_data">box1_change_app_data</button>
//方法:自定义事件myevent 触发事件 将要修改的数据传过去
methods: {
    change_app_data() {
        this.$emit("myevent","box1向app反向传过去的数据")
   }
}

购物车算总价案例:

        前面文章中有用html实现购物车的功能,现在将这个功能用Vue框架来实现,体现了反向传值(子组件的按钮点击了,不能直接修改父组件中的count,需要利用属性绑定和自定义事件来实现数据的反向传值)

父组件(App):

<template>
  <div>
    <Goodsbox v-for="(el, index) in arr" :goods="el" :index="index" @decrease="fn" @increase="fn2"></Goodsbox>
    <p>总价:{{ total }}元</p>
  </div>
</template>
<script>
import Goodsbox from "./components/Goodsbox.vue"
export default {
  data() {
    return {
      arr: [
        { id: 1, title: "goods1", price: 12, count: 0 },
        { id: 2, title: "goods2", price: 3, count: 0 },
        { id: 3, title: "goods3", price: 22, count: 0 },
        { id: 4, title: "goods4", price: 33, count: 0 },
      ]
    }
  },
  methods: {
    fn(arg) {
      if (this.arr[arg].count) {
              this.arr[arg].count--;
      }
    },
    fn2(arg) {
      this.arr[arg].count++;
    }
  },
  computed: {
    total() {
      return this.arr.reduce((n1, n2) => {
        return n1 + n2.count * n2.price
      }, 0)
    }
  },
  components: {
    Goodsbox
  }
}
</script>

子组件(Goodsbox):

<template>
    <div>
        商品名:{{ goods.title }}---
        价格:{{ goods.price }}---
        数量:<button @click="decrease">-</button>
        {{ goods.count }}
        <button @click="increase">+</button>
    </div>
</template>
<script>
export default {
    //注册属性
    props: ["goods", "index"],
    methods: {
        decrease() {
            // 自定义事件名  通过this访问父级组件传过来的index下标
            this.$emit("decrease", this.index);
        },
        increase() {
            this.$emit("increase", this.index);
        }
    }
}
</script>

2.2 v-model 组件的双向数据绑定

语法:

父组件:<Box2 v-model:value="msg"></Box2>

vue2.0  v-model是语法糖:  :value="msg"  @input="(arg)=>{this.msg=arg}"

vue3.0  v-model:value是语法糖 :value="msg" @update:value=(arg)=>{ msg = arg}

子组件:注册属性,方法中使用this.$emit("update:"属性名","要传的数据")

简单案例:

// 父组件
<Box2 v-model:value="msg" v-model:keywords="key"></Box2>
//父组件数据源
data() {
    return {
      msg: "app组件中的数据",
      key: "app中的key数据",
    }
 }

//子组件Box2
<h2>box2组件-----{{ value }}----{{ keywords }}</h2>
<button @click="v_model_passValue">v_model_passValue</button>
//注册属性
props: ["value","keywords"],
//方法 传值
methods: {
    v_model_passValue() {
        this.$emit("update:value", "box2传给app的value数据");
        this.$emit("update:keywords","box2传给app的keywords数据")
    }
}

3. 透传(多层组件传值)

3.1 类型透传

语法:<Box3 class="box" />

父组件中设置了类名,子组件渲染时会自动加上父组件设置的类名;子组件也有类名时,会合并两个类名。

父级组件绑定属性 子组件中给孙组件绑定穿透属性:v-bind="$attrs" 事件透传 同理:v-on="$listeners"

3.2 属性穿透 v-bind="$attrs"

Box3将属性传给下一级组件(Box4)时,自己Box3是不能注册该属性的,才能传给下一子级。

//父组件 app中 通过属性传值
<Box3 class="box" :count="num"></Box3>

//子组件 box3
<div class="box3">
    <h2>box3组件----{{ count }}</h2>
    <Box4 v-bind="$attrs"></Box4>
</div>
//要传给自己,就不注册;不传,就注册来自己用
// props:["count"],

//孙组件 box4
<h2>box4组件----{{ count }}</h2>
//注册的属性名应该为父组件的属性名
props:["count"],

如果即要自己用,又想传给自己的子组件时,使用$attrs属性透传。$attrs中保存了父组件传给一级子组件的所有属性值,后代组件可以通过this.$attrs来访问。一级子组件Box3不注册,要透传属性给谁,就在这个标签上面添加v-bind:$attrs,但不能注册。使用时:this.$attrs.属性名

//父组件 app中 通过属性传值
<Box3 class="box" :count="num"></Box3>

//子组件 box3
<div class="box3">
    <h2>box3组件----{{ this.$attrs.count }}</h2>
    <Box4 v-bind="$attrs"></Box4>
</div>

//孙组件 box4
<h2>box4组件----{{ this.$attrs.count }}</h2>
// 属性透传给box5
<Box5 v-bind="$attrs"></Box5>

// 曾孙组件 box5
<h2>box5组件----{{ count }}</h2>
//注册的属性名应该为父组件的属性名
props:["count"],

 

3.3 事件穿透 v-on="$listeners"

vue2.x版本中:父组件app绑定的事件,想要通过孙组件Box4来触发该事件时,需要给子组件Box3添加v-on="$listeners",将事件穿透过去,然后在Box4中来触发该事件。

vue3.x版本中,直接通过v-bind="$attrs"就可以实现事件的穿透,$listenners弃用。

 4. 获取组件

$parent/$root/$options——方便,但尽量不要用,会引起不必要的麻烦,不好解决

$refs(获取组件中节点或者组件)

    <h2>box4组件----{{ count }}</h2>
    <Box5></Box5>
    <p ref="p1">box4中的p1标签</p>
    <button @click="box4_btn">box4_btn</button>

    methods: {
        box4_btn() {
            // 上级元素
            console.log(this.$parent);
            // 根级元素
            console.log(this.$root);
            // 子级元素
            console.log(this.$options.components);
            // 获取组件中节点或者组件
            console.log(this.$refs.p1);
        }
    }

5. 依赖provide注入indect

父级组件提供数据,组件链上的子级组件注入并使用。

简单案例:

// 父组件 app
  provide: {
    msgGlobal: 'provided by app',
    numGlobal: 999
  }

// 子组件们 box2 box3均相同
// 使用
<h2>global---{{ msgGlobal }}</h2>
<h2>numGlobal----{{ numGlobal }}</h2>
// 注入
inject: ["msgGlobal", "numGlobal"],

 虽然看起来很好用,但官方还是不建议使用,因为害怕使用者管理不好,容易出错。

总结:

1. 属性传值  <Box title="静态传值" />  <Box title="变量" /> Box内部设计的时候,可以props:["属性名"] 或 props:{属性名:验证函数}

        父组件的数据源更新了就会让子组件接收新的属性值

        父组件给子组件传的数据,可以通过子组件再传给它自己的子组件

2. 反向传值(子组件给父组件传值)重点

因为父组件属性传值给子组件后,子组件不能直接修改属性值(框架设计时单项数据流:数据只能由父级组件流给子级组件)。父组件监听事件(绑定函数),子组件触发事件(调用函数传数据)

语法:<Box :title="msg" @myevent="(el)=>{this.msg=el}" />

        Box内部:this.$emit("myevent","传参数")

        组件的双向数据绑定: <Box v-model:title="msg" />

                                             Box内部:this.$emit("update:title","参数")

3 .透传(多层组件传值)

<Box class="box" @click="fn /> box类名会直接绑定在box组件的根元素上

<Box :title="msg" @myevent2="fn />

Box内部可以直接传给下一级组件 <Box2 v-bind="$attrs" v-on="$listeners" />

4. 获取组件 $parent $root $options.components

5. 提供provide注入inject

父级组件提供数据,子级组件注入并使用

6. 中央事件总线、仓库——兄弟组件间的传值

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

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

相关文章

『2023北京智源大会』6月9日会议内容

『2023北京智源大会』6月9日上午|开幕式及全体大会 文章目录 一. 黄铁军丨智源研究院院长1. 大语言模型2. 大语言模型评测体系FlagEval3. 大语言模型生态(软硬件)4. 三大路线通向 AGI(另外2条路径) 二. Towards Machines that can Learn, Reason, and Plan(杨立昆丨图灵奖得主…

Java的垃圾回收机制详解

目录 1、C语言与Java语言垃圾回收区别 2、System.gc() 3、面试题引入Java垃圾回收 3.1 jvm怎么确定哪些对象应该进行回收 3.1.1 引用计数法 3.1.2 可达性分析算法 3.2 jvm会在什么时候进行垃圾回收的动作 3.2 jvm到底是怎么回收垃圾对象的 4、来回收算法 4.1 标记-清…

java是值传递还是引用传递

文章目录 1.前言2.java是值传递还是引用传递 1.前言 java是值传递&#xff1b;值传递是指在调用方法时将实际参数拷贝一份传递到方法中&#xff0c;这样在方法中如果对参数进行修改&#xff0c;将不会影响到实际参数&#xff1b;当传的是基本类型时&#xff0c;传的是值的拷贝…

探究MES系统:工业生产数字化转型的必需品

随着时代的发展&#xff0c;工业生产数字化转型已经成为不可避免的趋势。而MES系统作为工业生产运营管理领域中的一种重要软件系统&#xff0c;更是在数字化转型过程中扮演着重要的角色。 什么是MES系统 MES系统全称为制造执行系统&#xff08;Manufacturing Execution Syste…

快速傅里叶变换python实现

img { margin: auto; display: block } 一、前言 我想认真写好快速傅里叶变换(Fast Fourier Transform&#xff0c;FFT)&#xff0c;所以这篇文章会由浅到细&#xff0c;由窄到宽的讲解&#xff0c;但是傅里叶变换对于寻常人并不是很容易理解的&#xff0c;所以对于基础不牢的人…

基础知识学习---链表基础

1、本栏用来记录社招找工作过程中的内容&#xff0c;包括基础知识学习以及面试问题的记录等&#xff0c;以便于后续个人回顾学习&#xff1b; 暂时只有2023年3月份&#xff0c;第一次社招找工作的过程&#xff1b; 2、个人经历&#xff1a; 研究生期间课题是SLAM在无人机上的应…

Vue中如何进行音频与视频播放?

Vue中如何进行音频与视频播放&#xff1f; 在Vue中&#xff0c;我们可以使用HTML5的<audio>和<video>标签来实现音频和视频的播放。Vue本身并没有提供专门的音频或视频播放组件&#xff0c;但是可以使用Vue的数据绑定和生命周期钩子来控制音频和视频的播放。 音频…

【gcc, cmake, eigen, opencv,ubuntu】一.gcc介绍

文章目录 gcc介绍1.查看当前gcc 版本2.安装其他版本的gcc3.设置多个版本的优先级4.修改默认的版本5.查看cpu信息 gcc介绍 gcc介绍和makefile介绍 1.查看当前gcc 版本 gcc --version2.安装其他版本的gcc sudo apt install gcc-10 g-10这样我们电脑里包含gcc-9 和 gcc-10两个…

[玩游戏想道理]战略的感受

game&#xff1a;金铲铲之战 战略的定义可以说是非常多了&#xff0c;这里主要是就游戏中的过程谈一些实践感受和理解&#xff1b; 这里也不是谈战略的定义xxxx&#xff0c;这方面的理论包括《孙子兵法》都是强太多了&#xff0c;主要就是在游戏这个“现实模拟器”中&#xff0…

全志V3S嵌入式驱动开发(开机脚本、程序运行)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 目前为止的内容&#xff0c;大部分都是和驱动相关的。就算有部分上层代码&#xff0c;也只是为了测试驱动是否ok而编写的。事实上&#xff0c;作为…

团队管理之性能实施团队日志13

项目经过了&#xff0c;8 个业务系统和 7 个基础架构系统的测试之后&#xff0c;又完成了全链路的两个域的测试&#xff0c;终于进入了尾声。 过程中发现了 257 个问题&#xff08;只统计了 8 个业务系统&#xff09;&#xff0c;平均每个系统 32.125 个。问题 age 达到 861.77…

「微服务架构模式」编曲与编舞——让系统协同工作的不同模式

介绍 Krzysztof&#xff08;采访者&#xff09;&#xff1a;商业组织是由专家组成的&#xff0c;他们在他们最了解的领域提供产品或服务&#xff0c;以获得共同的商业成果。例如&#xff0c;营销团队努力争取新客户&#xff0c;销售团队向这些客户销售产品&#xff0c;客户关系…

用4种回归方法绘制预测结果图表:向量回归、随机森林回归、线性回归、K-最近邻回归

文章目录 表格部分数据如下运行效果如下代码解析完整代码附件 表格部分数据如下 附件里会给出全部数据链接 运行效果如下 代码解析 import pandas as pd import numpy as np import matplotlib.pyplot as plt from matplotlib.font_manager import FontPropertiesfont FontP…

FPGA实现USB3.0 UVC 相机彩条视频输出 基于FT602驱动 提供工程源码和QT上位机源码

目录 1、前言2、UVC简介3、FT602芯片解读4、我这儿的 FT601 USB3.0通信方案5、详细设计方案基于FT602的UVC模块详解 6、vivado工程详解7、上板调试验证8、福利&#xff1a;工程代码的获取 1、前言 目前USB3.0的实现方案很多&#xff0c;但就简单好用的角度而言&#xff0c;FT6…

用代码玩转迷你图:手把手教你用编程语言打造简洁易读的数据图表!

前言 迷你图&#xff08;Mini Chart&#xff09;最早起源于流程图和组织架构图中的一种简化图形&#xff0c;用于表示一个大型数据集合中的趋势和变化。随着数据可视化技术的发展&#xff0c;迷你图也被广泛应用在各种类型的数据图表中&#xff0c;例如折线图、柱形图、散点图…

【027】C++类和对象的基本概念

C类和对象的基本概念 引言一、类的封装性二、定义一个类三、设计一个类3.1、示例一&#xff1a;设计一个Person类3.1、示例二&#xff1a;设计一个Cube类 四、成员函数在类外实现五、类在其他源文件中实现总结 引言 &#x1f4a1; 作者简介&#xff1a;专注于C/C高性能程序设计…

RFID工业读头工作原理和优势

RFID工业读头由天线&#xff0c;耦合元件&#xff0c;芯片&#xff0c;可对RFID标签信息进行读取和写入&#xff0c;在工业上也常作为信息的传输、处理的载体。下面我们就一起来了解一下&#xff0c;工业读头工作原理和优势是什么。 工业读头工作原理 工业RFID读头主要是通过天…

微信小程序嵌入H5页面,最简单的兼容方式web-view

//index.wxml---------------------------------------- <web-view src"{{src}}" />//index.js---------------------------------------- Page({data: {src: "https://dz.wedoyun.cn/mobile/?v20230615",},});

1.6C++双目运算符重载

C双目运算符重载 C中的双目运算符重载指的是重载二元运算符&#xff0c;即有两个操作数的运算符&#xff0c;如加减乘除运算符“”、“-”、“*”和“/”等。 通过重载双目运算符&#xff0c;可以实现自定义类型的运算符操作。 比如可以通过重载加减运算符实现自定义类型的向…

电脑误删文件恢复怎么做?数据恢复,4招就行!

我有定期清理电脑的习惯&#xff0c;一般都会将电脑里的一些垃圾文件删除&#xff0c;但在最近一次的清理中&#xff0c;我不小心把重要的文件当作垃圾文件删除了&#xff0c;请问有什么比较好的解决方法吗&#xff1f;非常感谢&#xff01; 当下电脑的使用越来越频繁&#xff…