html中js向vue组件传值,Vue 组件之间传值

本文详细介绍了Vue组件间的通信方式,包括同一个路由下父向子组件通过props单向绑定传递值,子向父组件利用$emit发送自定义事件,以及非父子组件间利用事件总线(eventBus)实现通信。同时讨论了动态组件、$refs、$children以及依赖注入(provide/inject)等通信场景,并提到了$attrs和$listeners在组件间传递非props属性和事件监听器的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#同一个路由下,父向子组件传值

props属性 -- 单向绑定

import childOne from '../components/childOne.vue';

export default{

data() {

return{

msg: '我是动态data中的数据!'

}

},

components: {

childOne

}

}

{{ info }}

{{ msg }}

export default{

props: ['info','msg']

}

父组件中

给childOne绑定一个自定义静态prop属性,这里是info

使用v-bind绑定动态prop属性,这里是msg

childOne中,在props中接收传递过来的prop属性,info、msg,可直接使用

props的具体校验规则等,详见:

#同一个路由下,子向父组件传值

使用$emit发送自定义事件

import childOne from '../components/childOne.vue';

export default{

methods:{

/* E */

sendEv(a,b,c) {

console.log(a,b,c);

}

},

components: {

childOne

}

}

按钮

export default{

created() {

//B

this.send()

},

methods:{

send() {

//A

this.$emit('s-send', '来自childOne的消息!', { name: 'Tom' }, [1,2,3,4])

}

}

}

子组件中

首先先有 A ,this.$emit() 这一段代码

何时发给父组件(任选)

① 注释B:在子组件生命周期中发送

② 注释C:在DOM中写一个事件,触发这个事件时发送

父组件中

注释D:使用子组件$emit的自定义事件绑定一个自己的事件,这个是必须的

注释E:methods中的事件参数,可以获取来自子组件传的值

//$emit的使用

this.$emit()

@params

参1:自定义事件名

参2 ~ 参n:传递的参数,支持Number、String、Object、Array、Function、this 等

#同一路由下,非父子之间传值

可以是兄弟之间、爷孙之间、或者是父子之间,总之都可以使用!

事件总线:eventBus

下面演示兄弟之间传值,childOne与childTwo是一对兄弟组件;

childOne向childTwo传值

/* 首先先创建一个eventBus.js */

import Vue from 'vue';

export default new Vue()

import childOne from '../components/childOne.vue';

import childTwo from '../components/childTwo.vue';

export default{

components: {

childOne,

childTwo

}

}

childOne

// A

import eventBus from '../eventBus.js';

export default{

// D

created() {

this.send()

},

methods:{

send() {

// B

eventBus.$emit('childOneEv', '你好啊,childTwo!')

}

}

}

// E

import eventBus from '../eventBus.js';

export default{

created() {

// F

eventBus.$on('childOneEv', res=>{

console.log(res) // 你好啊,childTwo!

})

}

}

childOne组件中

注释A:导入eventBus.js

注释B这段代码是必须的,使用$emit发射一个自定义事件并携带参数

发送时机:

可以是触发一个事件发送(注释 C)

也可以直接在生命周期中发送(注释 D)

childTwo组件中

注释E:带入eventBus.js

注释F这段是必须的,使用$on订阅发射的事件,并在回调中接收参数

接收时机:在生命周期中接收(建议在created中接收)

如果在childOne - beforeDestroy中发送事件,此时childTwo的mounted还没有触发,

但created已经触发了,所以在created接收最好。

详见:https://blog.youkuaiyun.com/m0_37508531/article/details/103847541

#关于eventBus的另一种写法

/* eventBus.js */

import Vue from 'vue';

let bus = new Vue();

//直接挂在在Vue原型上

Vue.prototype.bus = bus;

//然后在childOne、childTwo中

//就可以不用导入eventBus.js了

//eventBus.$emit() 写成 this.bus.$emit() 即可

/* eventBus.js */

import Vue from 'vue';

export default new Vue()

//如果你想更严谨一点,可以导入到main.js中去挂载

/* main.js */

import bus from '../eventBus.js';

Vue.prototype.bus = bus;

//然后在childOne、childTwo中

//就可以不用导入eventBus.js了

//eventBus.$emit() 写成 this.bus.$emit() 即可

#eventBus的原理

事件总线的原理其实就是发布订阅模式

能够实现的原理就是需要有两个方法,$on:订阅 $emit:发布

而Vue实例本身就是提供了这两个方法,所以直接使用Vue实例即可

#动态组件问题

#$emit 和 $on

//$emit的使用

this.$emit()

@params

参1:自定义事件名(用于传递给$on)

参2 ~ 参n:传递给$on的参数,支持Number、String、Object、Array、Function、this 等

//$on的使用

this.$on()

@params

参1:自定义事件名(用于接收$emit的事件)

参2 ~ 参n:用于接收$emitn的参数,支持Number、String、Object、Array、Function、this 等

#组件传值的边界情况

import childOne from '../components/childOne.vue';

export default{

data() {

return{

msg: 'sendValue'

}

},

components: {

childOne

}

}

按钮

export default{

methods:{

handle() {

let root = this.$root;

let parent = this.$parent;

console.log(root); // A

console.log(parent);// B

console.log(root == parent); // false

}

}

}

已知上面的嵌套关系为:

App.vue --> sednValue.vue --> childOne.vue

在childOne.vue组件中的 $root和 $parent

注释A的 $root 其实是App.vue

在main.js中new Vue()绑定的el的DOM(html)为根实例

通过render函数又把App.vue替换了el绑定的DOM

所以App.vue成了唯一的根实例 $root

注释B的 $parent 是他的父组件sendValue.vue

#父组件中通过ref属性拿到子组件

$refs 只会在组件渲染完成之后生效,并且它们不是响应式的。这仅作为一个用于直接操作子组件的“逃生舱”——你应该避免在模板或计算属性中访问 $refs

import childOne from '../components/childOne.vue';

export default{

components: {

childOne

},

created() {

let ref = this.$refs;

console.log(ref); // B

}

}

注释A中,通过ref属性给组件绑定一个唯一名,这里是child

注释B中,通过 this.$refs 可以拿到所有的ref属性(对象格式)

$refs 只会在组件渲染完成之后生效,并且它们不是响应式的

可以使用 this.$refs.child 拿到这个组件

#使用$children获取子组件

$children 并不保证顺序,也不是响应式的

import childOne from '../components/childOne.vue';

export default{

components: {

childOne

},

created() {

let children = this.$children;

console.log(children); // A

}

}

注释A中:可以拿到所有子组件(数组)

但是顺序不能保证,可能会有异步导入的组件

#依赖注入 provide / inject 传值

首先要明确,使用依赖注入一般都是在开发插件中,因为是开发插件,所以不能使用

eventBus或vuex,因为不能确定是否用户使用了这些,若插件强行导入,会让插件

变得有侵入性,所以放弃;

$root 也不能使用,因为无法确定用户使用插件嵌套的层级

$parent 如果插件嵌套很多层,逻辑会变得更加难懂且复杂

*相当于一个加强的props,props只能父传子;但是provide/inject可以传递多个层级;

同样的缺点就是在追踪数据时,由于太深的层级,导致数据追踪困难

import childOne from '../components/childOne.vue';

export default{

// A

provide() {

return {

info: this.info,

_root: this

}

},

data() {

return {

info: '来自遥远的远方!',

msg: 'provide MSG'

}

},

components: {

childOne

}

}

{{info}}

export default{

// B

inject: ['info', '_root']

// C

inject: {

bar: {

from: 'info'

},

_root: '_root'

}

}

父组件中

注释A,使用provide导入了两个属性,info是父组件data绑定的data值;

_root导出的是this,即父组件,这是允许的

子组件中

注释B,使用inject导入需要的属性

注释C,为了防止变量污染,可以设置别名

#非props属性 $attrs

当父组件向子组件传递值时,但是子组件并没有使用props接收,此时这些属性就是非props属性,$attrs;子组件能通过 this.$attrs 拿到这些属性

attribute 会被添加到这个组件的根元素上

import childOne from '../components/childOne.vue';

export default{

components: {

childOne

}

}

export default{

inheritAttrs: false, // B

created() {

let attr = this.$attrs;

console.log(attr); // A

}

}

在子组件中,因为没有使用props绑定父组件传过来的 placeholder ,所以可以在子组件的 $attrs 中接收;

注释A:子组件中使用$attrs接收所以的非props,数据是一个对象

注释B:因为$attrs是被默认注册到子组件的根元素上的,inheritAttrs设置为false,关闭默认;

注释C:v-bind = "$attrs" ,会将所有的 $attrs 属性依次绑定到指定的元素上。

# $listeners

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值