vue 听说你很会传值?
前置
大小 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
provide
和inject
不推荐直接用于应用程序代码中- 与 React 的上下文特性很相似。这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效
provide
选项应该是一个对象或返回一个对象的函数。该对象包含可注入其子孙的属性。在该对象中你可以使用 ES2015 Symbols 作为 key,但是只在原生支持 Symbol 和 Reflect.ownKeys 的环境下可工作provide
和inject
绑定并不是可响应的。这是 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 的新特性provide
和inject
可以实现嵌套组件之间的数据传递- 这两个函数只能在
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 听说你很会传值?的更多相关文章
- 【转】Vue组件一-父组件传值给子组件
Vue组件一-父组件传值给子组件 开始 Vue组件是学习Vue框架最比较难的部分,而这部分难点我认为可以分为三个部分学习,即 组件的传值 - 父组件向子组件中传值 事件回馈 - 子组件向父组件发送消息 ...
- vue组件定义方式,vue父子组件间的传值
vue组件定义方式,vue父子组件间的传值 <!DOCTYPE html> <html lang="zh-cn"> <head> <met ...
- 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十║Vue基础终篇:传值+组件+项目说明
缘起 新的一天又开始啦,大家也应该看到我的标题了,是滴,Vue基础基本就到这里了,咱们回头看看这一路,如果你都看了,并且都会写了,那么现在你就可以自己写一个Demo了,如果再了解一点路由,ajax请求 ...
- 浅谈vue父子组件之间的传值
前言:本章主要说下父子组件的传值,为商品列表组件之间的传值做一个基础预热.Github:https://github.com/Ewall1106/mall(请选择分支chapter23) 1.父组件向 ...
- vue 实现子向父传值
父组件 <template> <div id="app"> <child @onChange='onChildValue'></child ...
- vue中非父子组件的传值bus的使用
非父子之间的组件传值,可以使用vuex.简单的状态管理,也可以用vue bus vue bus可以实现不同组件间.不同页面间的通信,比如我在A页面出发点击事件,要B页面发生变化,使用方法如下: 全局定 ...
- Vue.js父子组件如何传值 通俗易懂
父子组件传值原理图 一般页面的视图App.vue应为这样 一.父组件向子组件传值 1.创建子组件,在src/components/文件夹下新建一个Child.vue 2.Child.vue的中创建pr ...
- Vue组件创建和组件传值
Vue创建组件的方式 使用Vue.Extend()和Vue.component全局注册组件 首先我们定义一个组件并接收 var com1 =Vue.extend({ template:"&l ...
- vue几种简单的传值方式
除了一下的几种方式外,可以参考 https://www.cnblogs.com/hpx2020/p/10936279.html 组件传值的方法: 一.父组件向子组件传递数据(props) 第1:父组件 ...
随机推荐
- 蚂蚁金服开源 | 可视化图形语法G2 3.3 琢磨
G2 是蚂蚁金服数据可视化解决方案 AntV 的一个子产品,是一套数据驱动的.高交互的可视化图形语法. 经过两个多月密锣紧鼓的开发,400+次提交,G2 3.3版本今天终于和大家见面了.自上次3.2版 ...
- Deepin环境下启动Pycharm没有启动图标解决办法
小伙伴们在deepin下运行pycharm时,是不是需要通过sh文件启动? 下面告诉大家如何将pycharm图标放在桌面上: 1.在桌面打开终端,输入命令: sudo gedit /usr/share ...
- 《Javascript中 == 和 === 的区别》
在js中 ==(相等运算符) 和 === (严格运算符)是两种判断两个变量是否相等的运算符. == :判断是否相等,忽略类型进行值的比较.(存在隐式类型转换的比较) ===:判断是否相等,先判断值是否 ...
- 通过nodejs实现文件的上传
通过nodejs实现文件的上传 主要内容 本文将用来讲述如何通过nodejs进行文件上传,将会涉及到以下知识点: 通过express模块进行服务器的搭建 通过multer模块将上传的文件保存到指定目录 ...
- 【10】openlayers 视图view
创建地图: //View对象代表地图的简单2D视图 //创建view let view = new ol.View({ center:[109,34],//视图的初始中心 maxZoom:18,//最 ...
- 为.net Core 3.0 WebApi 创建Linux守护进程
前言 我们一般可以在Linux服务器上执行 dotnet <app_assembly.dll> 命令来运行我们的.net Core WebApi应用.但是这样运行起来的应用很不稳定,关闭终 ...
- Java反射之数组的反射应用
上一篇我们说了Java反射之成员方法的反射 这一篇我们说一说数组的反射应用,数组的有长度等属性,所以也会有相应的方法获得这些属性,这里我们不一一列举哪些方法.我们来了解反射包中的一个类----Arra ...
- Effective Go笔记
一 格式化 使用gofmt程序对go源码进行格式化,以便统一编码风格,可直接在GoLand进行配置[1].Go源码格式使用tab作为缩进,且很少使用括号. 二 注释 Go支持块注释/**/和行注释// ...
- Java的反射基础技术
今天本人给大家讲解一下Java的反射基础技术,如有不对的或者讲的不好的可以多多提出,我会进行相应的更改,先提前感谢提出意见的各位了!!! 什么是反射? 反射它是根据字节码文件可以反射出类的信息.字段. ...
- echarts legend文字配置多个颜色(转)
困扰很久的问题终于解决了 oh yea! echarts legend文字配置多个颜色legend: {data: [{name:‘直接访问’,icon : ‘circle’,textStyle: { ...