前置

大小 vue 项目都离不开组件通讯, 在这里总结一下vue组件通讯方式并列出, 都是简单的例子. 适合像我这样的小白。如有错误,欢迎指正。

温馨提示: 下文没有列出 vuex, vuex 也是重要的组件通讯方式。

props

  • 最常用的组件通讯方式
  • 值可以是数组或对象,使用对象时可以配置高级选项,如类型检测、自定义验证和设置默认值
  • 方向:父 -> 子

Son.vue

export default {
props: {
text: {
type: String,
required: true,
},
}, mounted() {
console.log(this.text) // 我是父组件提供给子组件的值
},
}

App.vue

<template>
<Son text='我是父组件提供给子组件的值'/>
</template> <script>
import Son from './components/dispatch/Son'
export default {
name: 'app',
components: {
Son,
}
},
</script>

$refs

  • 常用的方式
  • 返回注册过 ref 特性的所有 DOM 元素和组件实例
  • 可以用来操作 DOM
  • 可以用来传值
  • 方向:子 -> 父

Son.vue

export default {
methods: {
sonFunc() {
console.log('我是子组件的值')
},
},
}

App.vue

<template>
<Son ref="sonref"/>
</template> <script>
import Son from './components/dispatch/Son'
export default {
name: 'app',
components: {
Son,
},
mounted() {
this.$refs.sonref.sonFunc()
},
}
</script>

控制台打印: 我是子组件的值

$emit

  • $emit 用来触发当前实例上的事件
  • 方向:父 -> 子
  • 参数一:来触发的当前实例上的事件函数
  • 参数二:附加参数,传给监听器回调

Son.vue

export default {
mounted() {
this.$emit('customFunc', '我是子组件传给父组件的值')
},
}

App.vue

<template>
<Son v-on:customFunc="fatherFunc" />
</template> <script>
import Son from './components/dispatch/Son'
export default {
name: 'app',
components: {
Son,
}, methods: {
fatherFunc(value) {
console.log(value) // 我是子组件传给父组件的值
},
},
}
</script>

@update

  • 需要配合 .sync 使用
  • 与上面的 $emit 写法类似
  • 不同之处在于$emit 的第一个参数不在是当前实例上的事件函数
  • 方向:子 -> 父

Son.vue

export default {
mounted() {
this.$emit("update:text", '我是子组件传给父组件的值')
}
}

App.vue

<template>
<Son :text.sync='text'/>
</template> <script>
import Son from "./components/dispatch/Son"
export default {
data() {
return {
text: ''
}
},
mounted() {
console.log(this.text); // 我是子组件传给父组件的值
}
}
</script>

接下来看下面的写法,上面这种写法是对如下方式的简写, 或者称之为语法糖。可以不借助 .sync

Son.vue

export default {
mounted () {
this.$emit('update:text','我是子组件传给父组件的值')
}
}

App.vue

 <Son @update:text="v => (this.value = v)" />

 import Son from "./components/dispatch/Son"
export default {
mounted() {
console.log(this.value) // 我是子组件传给父组件的值
}
}

v-model

  • v-model 常用来给 input 实现双向数据绑定
  • v-model 也可以用来传值
  • 有局限性,只能传 input value
<input v-model="text">

等价于:

<input
v-bind:value="text"
v-on:input="text = $event.target.value"
>

接下来看如何通过 v-model 传值。

Son.vue

<template>
<input
v-bind:value="value"
v-on:input="$emit('input', $event.target.text)"
/>
</template> <script>
export default {
data() {
return {
value: '我是子组件传给父组件的值',
}
}
}
</script>

App.vue

<template>
<Son v-model="text" />
</template> <script>
import Son from './components/dispatch/Son'
export default {
name: 'app',
components: {
Son,
}
}
</script>

$parent $childred

  • $parent: 父实例,如果当前实例有的话
  • $children: 当前实例的直接子组件
  • $parent $childred 通过封装可以实现不同方向的传值

$children 并不保证顺序,也不是响应式的。可以使用一个数组配合 v-for 来生成子组件,使用 Array 作为真正的来源。

App.vue

export default {
data() {
return {
value: '我是父组件的值',
}
},

Son.vue

export default {
mounted: {
console.log(this.$parent.value) // 我是父组件的值
this.$parent.value = 666
console.log(this.$parent.value) // 666
},
}

简单封装一下即可实现$parent 配合 $emit 实现跨级向上传值。

main.js

Vue.prototype.$dispatch = function(event, value) {
let parent = this.$parent
while (parent) {
parent.$emit(event, value)
parent = parent.$parent
}
}

这样使用: this.$dispatch('event',value)

简单封装一下即可实现$children 配合 $emit 实现向下传值。

Vue.prototype.$broadcast = function(event, value) {
const broadcast = children => {
children.forEach(child => {
child.$emit(event, value)
if (child.$children) {
broadcast(child.$children)
}
})
}
broadcast(this.$children)
}

这样使用: this.$broadcast('event',value)

$attrs

  • 获取父组件通过 v-bind 传过去的所有值
  • class 和 style 除外
  • 可以通过 v-bind="$attrs" 传入内部组件
  • 只能在 <template> 中使用
  • 方向:子 -> 父

App.vue

<template>
<Son :value1="123" :value2="456" />
</template> import Son from './components/dispatch/Son'
export default {
name: 'app',
components: {
Son,
},
}

Son.vue

<template>
<div>{{$attrs}}</div>
</template> <script>
export default {
inheritAttrs: false,
}
</script>

$listener

  • 获取父作用域中的 () v-on 事件监听器。
  • 不含 .native 修饰器修饰的时间监听器。
  • 可以通过 v-on="$listeners" 传入内部组件(孙子组件)。
  • 方向:父 -> 子

App.vue

<template>
<Son @customFunc="fatherFunc"/>
</template> <script>
import Son from './components/dispatch/Son'
export default {
name: 'app',
components: {
Son,
},
methods: {
fatherFunc() {
console.log('666')
},
},
}
</script>

Son.vue

<template>
<button @click="$listeners.customFunc()">看</button>
</template>

provide inject

  • provideinject 不推荐直接用于应用程序代码中
  • 与 React 的上下文特性很相似。这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效
  • provide 选项应该是一个对象或返回一个对象的函数。该对象包含可注入其子孙的属性。在该对象中你可以使用 ES2015 Symbols 作为 key,但是只在原生支持 Symbol 和 Reflect.ownKeys 的环境下可工作
  • provideinject 绑定并不是可响应的。这是 vue 刻意为之
  • 如果你传入了一个可监听的对象,那么其对象的属性还是可响应的

这里有一个简单的示例:

App.vue

<template>
<Son />
</template> <script>
import Son from './components/dispatch/Son'
export default {
name: 'app',
components: {
Son,
},
provide() {
return {
text: '我是父组件的值',
}
},
}
</script>

Son.vue

export default {
inject: ['text'],
mounted() {
console.log(this.text) // 我是父组件的值
},
}

事件总线

  • EventBus 又称为事件总线
  • 不是一个具体的 API,EventBus 代表一种思路
  • 可以看作 vuex 的究极压缩版

App.vue

<template>
<div>
<Son />
</div>
</template> <script>
import Son from './components/dispatch/Son'
export default {
name: 'app',
components: {
Son,
},
mounted() {
this.$EventBus.$emit('event', 'app.vue')
},
}
</script>

Son.vue

export default {
mounted() {
this.$EventBus.$on('event', function(v) {
console.log(v)
})
},
}

Observable

  • observable 可以让一个对象可响应
  • vue 内部会用它来处理 data 函数返回的对象
  • 返回的对象可以直接用于渲染函数和计算属性内,并且会在发生改变时触发相应的更新
  • 可以作为最小化的跨组件状态存储器,用于简单的场景

store.js

import Vue from 'vue'

export const store = Vue.observable({ text: '我是store里的' })
export const mutations = {
setText(text) {
store.text = text
},
}

App.vue

import { store, mutations } from '../store'
export default {
mounted() {
console.log(store.text) //我是store里的
mutations.setText('我在App.vue中将你改变')
console.log(store.text) //我在App.vue将你改变
},
}

composition-api

  • composition-api 包含 vue3 的新特性
  • provideinject 可以实现嵌套组件之间的数据传递
  • 这两个函数只能在 setup 函数中使用
  • 父级组件中使用 provide 函数向下传递数据
  • 子级组件中使用 inject 获取上层传递过来的数据
  • 不限层级。

App.vue

<template>
<provideAndInject />
</template> <script>
import { provide } from "@vue/composition-api"
import provideAndInject from "./components/provideAndInject" export default {
name: "app",
components: {
provideAndInject
},
setup() {
// provide('数据名称', 要传递的数据)
provide("customVal", "我是父组件向子组件传递的值");
}
};
</script>

Son.vue

<template>
<h3>{{ customVal }}</h3>
</template> <script>
import { inject } from "@vue/composition-api"; export default {
setup() {
//调用 inject 函数,通过指定的数据名称,获取到父级共享的数据
const customVal = inject("customVal"); return {
customVal
};
}
};
</script>

父组件可以通过 ref 创建响应式数据通过 provide 共享给子组件。

vue 听说你很会传值?的更多相关文章

  1. 【转】Vue组件一-父组件传值给子组件

    Vue组件一-父组件传值给子组件 开始 Vue组件是学习Vue框架最比较难的部分,而这部分难点我认为可以分为三个部分学习,即 组件的传值 - 父组件向子组件中传值 事件回馈 - 子组件向父组件发送消息 ...

  2. vue组件定义方式,vue父子组件间的传值

    vue组件定义方式,vue父子组件间的传值 <!DOCTYPE html> <html lang="zh-cn"> <head> <met ...

  3. 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十║Vue基础终篇:传值+组件+项目说明

    缘起 新的一天又开始啦,大家也应该看到我的标题了,是滴,Vue基础基本就到这里了,咱们回头看看这一路,如果你都看了,并且都会写了,那么现在你就可以自己写一个Demo了,如果再了解一点路由,ajax请求 ...

  4. 浅谈vue父子组件之间的传值

    前言:本章主要说下父子组件的传值,为商品列表组件之间的传值做一个基础预热.Github:https://github.com/Ewall1106/mall(请选择分支chapter23) 1.父组件向 ...

  5. vue 实现子向父传值

    父组件 <template> <div id="app"> <child @onChange='onChildValue'></child ...

  6. vue中非父子组件的传值bus的使用

    非父子之间的组件传值,可以使用vuex.简单的状态管理,也可以用vue bus vue bus可以实现不同组件间.不同页面间的通信,比如我在A页面出发点击事件,要B页面发生变化,使用方法如下: 全局定 ...

  7. Vue.js父子组件如何传值 通俗易懂

    父子组件传值原理图 一般页面的视图App.vue应为这样 一.父组件向子组件传值 1.创建子组件,在src/components/文件夹下新建一个Child.vue 2.Child.vue的中创建pr ...

  8. Vue组件创建和组件传值

    Vue创建组件的方式 使用Vue.Extend()和Vue.component全局注册组件 首先我们定义一个组件并接收 var com1 =Vue.extend({ template:"&l ...

  9. vue几种简单的传值方式

    除了一下的几种方式外,可以参考 https://www.cnblogs.com/hpx2020/p/10936279.html 组件传值的方法: 一.父组件向子组件传递数据(props) 第1:父组件 ...

随机推荐

  1. ASP.NET Core 中间件自定义全局异常处理

    目录 背景 ASP.NET Core过滤器(Filter) ASP.NET Core 中间件(Middleware) 自定义全局异常处理 .Net Core中使用ExceptionFilter .Ne ...

  2. 个人理解TCP中SYN Cookie

    说起SYN Cookie还是得从TCP3次握手开始说起,先给出计网的体系结构图 然后解释一下SYN,seq,ack,ACK的相关名词 SYN(建立连接) ACK(确认后全部为1) PSH(传送) FI ...

  3. 开源网站云查杀方案,搭建自己的云杀毒-搭建ClamAV服务器

    开源网站云查杀方案,搭建自己的云杀毒 搭建ClamAV服务器 1        前言: 在上一篇我们已经演示了整个方案,传送门<开源网站云查杀方案,搭建自己的云杀毒>:https://ww ...

  4. 一起了解 .Net Foundation 项目 No.14

    .Net 基金会中包含有很多优秀的项目,今天就和笔者一起了解一下其中的一些优秀作品吧. 中文介绍 中文介绍内容翻译自英文介绍,主要采用意译.如与原文存在出入,请以原文为准. .NET Core .NE ...

  5. html5插件完成滚屏幕效果

    首先想要完成这样的效果要用到jquery-fullpage插件我们需要他的js文件和css样式文件如图  因为是jquery的插件所以我们还要导入jquery-min.js 在页面引入这些样式和插件 ...

  6. si4745 FM-AM-SW 音量控制芯片 驱动详解

    在论坛上看到有人发这个dsp 芯片,仔细看了下,发现功能正合我意,网上能找到的资料(源码)不多 软件环境:linux4.1.36  arm-linux-gcc 4.3.2 实现功能:自动搜台,上一台, ...

  7. scrapy mid中间件一般处理方法

    import user_agent import requests class UA_midd(object): def process_request(self,request,spider): r ...

  8. mongo请求超时

    no_cursor_timeout=True参数的使用 实例: import pymongo handler = pymongo.MongoClient().db.col with handler.f ...

  9. (转)ARM GNU常用汇编语言介绍

    ARM GNU常用汇编语言介绍 原文地址:http://zqwt.012.blog.163.com/blog/static/120446842010445441611/ ARM汇编语言源程序语句,一般 ...

  10. 云CRM系统安全吗

    云CRM系统有一个特点只要连接互联网就能够进行访问,这种访问可以是移动端也可以是电脑端的,而且本地CRM系统只允许电脑端访问.云CRM系统将数据存储在云服务器上,很多人就会问云CRM系统安全吗?下面和 ...