目录
一、侦听器
监听基本数据类型:
监听引用数据类型:
计算属性和watch区别?
二、组件通信/传值方式
1.父子组件传值
父组件给子组件传值:
(1)props
(2)provide inject
(3)事件总线 $emit 和 $on vue实例调用方法
子组件给父组件传值:
(1)事件总线 $emit 和 $on vue实例调用方法
2.兄弟组件传值/通信
(1)利用事件总线
(2)vuex
3.祖先后代组件传值/通信
(1)provide inject
一、侦听器
只有监听数据发生改变才会触发侦听器
监听基本数据类型:
通过下面这个小案例来学习,通过监听a和b的值,来实现计算求和的功能
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
</head>
<body><div id="app"><!-- number修饰符 可以让双向数据绑定的值变为number类型 -->a:<input type="text" v-model.number="a"><br>+<br>b:<input type="text" v-model.number="b"><br>=<br><output>{{total}}</output></div><script>let vm = new Vue({// 与模板绑定el:"#app",// 数据模型 存放vue变量data:{a:0,b:0,total:0,name:"",obj:{}},// 存放方法和事件处理程序methods: {},computed:{// total(){// return Number(this.a) + Number(this.b)// }},// 侦听器 监听器 什么时候触发? 只有数据发生变化才会触发watch:{a(newValue,oldValue){// console.log(newValue,oldValue);this.total = newValue + this.b},b(newValue,oldValue){// console.log(newValue,oldValue);this.total = this.a + newValue}}});</script>
</body>
</html>
浏览器运行结果如下:
监听引用数据类型:
当侦听器在监听引用数据类型时存在监听不到的问题,这时我们就需要开启深度监听
params:{handler(n,o){this.getArticle();},//开启深度监听deep:true}}
计算属性和watch区别?
1.计算属性有缓存性,响应式依赖不发生改变,多次调用计算属性会返回之前得计算结果。
2.watch无缓存性,只有数据发生改变侦听器才会执行。
3.watch侦听器一般用于异步操作或者开销较大得操作。
4.计算属性默认可读,设置setter就可修改。
二、组件通信/传值方式
1.父子组件传值
父组件给子组件传值:
(1)props
1.在子组件标签中写入父组件传递数据 向下传递prop
2.在子组件内声明props选项接收父组件传递的数据 props:['','','']
<!-- 动态传递 传递的变量 使用v-bind绑定 --><Header :msg="msg"></Header><!-- 静态传递 --><Header title="我是父组件中title"></Header><!-- 3.传递其他数据类型 除字符串外 传递数组对象number布尔值 动态传参 --><Header :arr="[1,2,3,4]" :obj="{name:'zhangsan'}" :bool="true" :age="20"></Header>
// 子组件使用props接收父组件传递的数据props:['msg'],props:['title'],props: ['msg', 'age', 'bool', 'arr', 'obj'],
(2)provide inject
1.父组件使用provide提供传递数据或者方法(与methods同级)
2.子组件使用inject注入传递的数据或者方法
// 注入传递给后代组件的数据或者方法provide(){return{parent:this.parent,parentSend:this.parentSend,attr:this.attr}}
}
// 使用provide传递的数据方法使用inject注入 后代组件注入祖先组件传递数据和方法inject: ['parent', 'parentSend'],
(3)事件总线 $emit 和 $on vue实例调用方法
1.新建event.js
import Vue from 'vue';
export default new Vue();
// 定义事件总线 导出vue实例对象
import Vue from "vue";
export default new Vue();
2.在父组件中使用$emit发射自定义事件同时传递参数
import Bus from './event.js'
Bus.$emit('自定义事件名称',传递数据)
<!-- 3.第三种传值方式 --><button @click="handler">发射数据给header子组件</button>
handler(){// $emit() 发射自定义事件 参数(自定义事件名称 传递的参数)Bus.$emit('toHeader',this.pMsg,'hello world')},
3.在子组件内部使用$on监听自定义事件同时接收参数
Bus.$on('自定义事件名称',(a,b)=>{
})
// $on监听$emit自定义事件 参数(自定义事件名称,()=>{})Bus.$on('toHeader', (a, b) => {console.log(a, b);this.a = a;this.b = b;})
子组件给父组件传值:
(1)事件总线 $emit 和 $on vue实例调用方法
1.发射自定义事件给父组件同时传递数据
this.$emit('toParent',this.footer);
2.在父组件模板中(在子组件标签上)声明自定义事件
<Footer @toParent='事件处理程序'></Footer>
事件处理程序(接收子组件传递的数据){
}
和父给子传的第三种方式一样
2.兄弟组件传值/通信
(1)利用事件总线
1.定义事件总线 新建xxx.js
import Vue from 'vue';
export default new Vue();
2.在一个兄弟组件中引入事件总线
import Bus from './event.js'
使用Bus.$emit('自定义事件名称',传递的数据)
3.在另一个兄弟组件中引入事件总线
import Bus from './event.js'
使用Bus.$on('emit发射自定义事件名称',(a,b)=>{
})监听发射自定义事件 同时接收数据
同父给子传的第三种方式
(2)vuex
关于vuex后续文章会详细说明,父子组件、兄弟组件、无关系组件任意组件之间的传值。
Vuex本质上也是一种本地存储,比localStorage
的单纯值传递多了方法、属性、异步方法等功能。但是因为是将内容本地化,所以就会被在浏览器中获取到。
3.祖先后代组件传值/通信
(1)provide inject
同父给子传的第二种方式