整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

vue3中父子组件之间传值的详解

vue3中父子组件之间传值的详解

用 Javascript 的软件项目

首先我们回顾一下vue2中父子组件是怎么传值的,然后对比vue3进行详解。

一、vue2中父子组件传值

<!-- 父组件 -->
<template>
    <div>
  		// name:父组件把值传给子组件test-child
  		// childFn:子组件传递值给父组件的自定义方法
      <test-child :name="name" @childFn="parentFn"></test-child>
      子组件传来的值 : {{message}}
    </div>
</template>

<script>
export default {
    data() {
        return {
          message: '',
          name: '张三'
        }
    },
    methods: {
      // 接收子组件的传值
       parentFn(payload) {
         this.message=payload;
       }
    }
}
</script>
<!-- 子组件 -->
<template> 
    <div>
  			{{name}}
        <input type="text" v-model="message" />
        <button @click="click">发送消息给父组件</button>
    </div>
</template>
<script>
export default {
		props:{
      name:{
        type:String,
        default:''
      }
    }
    data() {
        return {
          message: '我是来自子组件的消息'
        }
    },
    methods: {
      click() {
            // 1、childFn 组件方法名,请对照父组件
            // 2、message是传递给父组件的数据
            this.$emit('childFn', this.message);
        }
    }    
}
</script>

上面的代码可以看到我们vue2中父子组件之间传值是通过prop传值给子组件,子组件通过$emit把值传递给父组件进行交互。那么我们下面看看vue3中是如何进行组件之间传值的。

二、provide & inject

vue3提供了provide() 和 inject() 两个方法,可以实现组件之间的数据传递。父级组件中使用 provide() 函数向子组件传递数据;子级组件中使用 inject() 获取父组件传递过来的数据。代码如下:

<!-- 父组件 -->
<template>
  <div id="app">
    <test-child></test-child>
  </div>
</template>
<script>
import testChild from './components/testChild'
// 1. 按需导入 provide
import { provide } from '@vue/composition-api'
export default {
  name: 'app',
  setup() {
    //  App 根组件作为父级组件,通过 provide 函数向子级组件共享数据(不限层级)
    //  provide('要共享的数据名称', 被共享的数据)
    provide('color', 'red')
  },
  components: {
    testChild
  }
}
</script>
<template>
  <div>
  <!--  通过属性绑定,为标签设置字体颜色 -->
  <h3 :style="{color: themeColor}">Level One</h3>
</div>
</template>
<script>
import { inject } from '@vue/composition-api'
export default {
  setup() {
    // 调用 inject 函数时,通过指定的数据名称,获取到父级共享的数据
    const themeColor=inject('color')
    // 把接收到的共享数据 return 给 Template 使用,进行数据渲染
    return {
      themeColor
    }
  }
}
</script>

通过上面的代码我们可以发现,vue3中数据传值更加简单了,不用再引入子组件标签上写属性,直接通过provide()设置指定的名称,可以在子组件中通过inject()拿到,是不是感觉很简单呢。

S严格来讲是没有引用传递,只有值传递,虽然object类型看起来更改的引用而非value。

当然了你如果非要说objecct这种就叫引用传递,那也是可以的。

值传递与引用传递图例


可以这么来理解。 之前写了手稿图片版,现在给出文字版。

JS数据分为两大类:

  • 1类是原始类型primitive value,就是string,number,undefined,null,booleanSymbol,存放在栈,可以类比为是书和玩具,

  • 另外一类是object,叫引用类型(reference value,也有叫参考的),比如key-value对象、函数、数组等,存放在堆,可以看成是书架或箱子(盒子)。

无论那种数据类型,a=1, 或 a={},a首先是一个地址空间,它要指向1或{}这个value所在的内存地址.1是原始数据类型,存放在栈。{}因为是个盒子,除了盒子本身,里面的物件全是引用指向关系,object存在堆里。

在传递的时候,无轮是原始数据类型的直接量,还是引用类型Object,都是传递的value所在的地址,而不是这个a变量的地址。

看下面的例子:

var a=1;
var b=a;
b=2;

console.log(a, b); // 1, 2

var a={ x: 1};
var b=a;
b.x=2;

console.log(a.x, b.x); // 2, 2

// 所以,当

var a={ x: 1 };
var b=1;
var c={x: 1};

function swap(a, b, d) {
// 这是一个函数,有三个形参a,b,d
// 函数形参a,b是一个新的变量,并非外部的a和b,内部a和b指向外部a和b所指向的value地址
// 注意外部a的value本身是个盒子,传递进来盒子的value后,内部a与外部的a都指向这个盒子
// 当盒子里面的物件改变了时,内部的a和外部的a因为都指向这个盒子,所以里面的东西是一样的

a={ x: 2 };
b=2;
c.x=2;

// 但是我们把内部的a,b做了新的赋值(指向更改),把内部a指向了新的一个{},把内部的b指向了新的2
// 此时内部作用域下变量a,b是新的value,a.x,b都是2, d.x因为与c.x指向相同的引用地址,因此d.x就是c.x
console.log(a.x, b, d.x); // 2, 2, 2

}


// 调用这个函数,传入上面声明的a,b,c变量
swap(a, b, c);

// 但在外部作用域,a与b仍然指向原来的value地址,因为传递是a和b的value地址,而非a和b本身的地址, c因为被函数执行时调用改变,c.x为2

console.log(a.x, b, c.x); // 1, 1, 2

ue路由传参的两种方式query和params

点击打开视频讲解更加详细

【面试题】Vue路由传参的两种方式query和params_哔哩哔哩_bilibili