大厂面试题分享 面试题库
前后端面试题库 (面试必备) 推荐:★★★★★
地址:前端面试题库 web前端面试题库 VS java后端面试题库大全
组件之前的通信方法
1. props/$emit
父传子 props 这个只能够接收父组件传来的数据 不能进行修改 可以静态传递 也可以动态传递(一个表达式,一个对象或者布尔值等)父组件属性绑定 子组件用props接收
子改父 子组件的内部通过emit子组件的内部通过emit去触发这个事件 同时也可以传参过去 v-on去传递事件是写在子组件的标签身边的,然后回调函数是写在父组件的methods身上的
//父组件 <template> <div> <child :msg="msg" @changeMsg="changeMsg"></child> <p>{{msg}}</p> </div> </template> <script> import child from "../components/Child"; export default { data() { return { msg: "hello" }; }, components: { child }, methods:{ changeMsg(value){ this.msg=value } } }; </script> // 这是子组件 <template> <div> <div @click="change">改变父组件的{{msg}}</div> </div> </template> <script> export default { props: ["msg"], methods:{ change(){ this.$emit("changeMsg",123) } } }; </script> 复制代码
2.parent/children
$parent 子组件可以获取到父组件身上的属性以及方法,但是一定要注意,如果说这个组件的父组件不止一个的话 那么容易发生报错
ℎ父组件拿到自己身上的子组件的属性已经方法,如果身上的子组件不止一个的话打印ℎ.children父组件拿到自己身上的子组件的属性已经方法,如果身上的子组件不止一个的话打印this.children的时候会以数组的形式展示出来
3.ref
父组件想要拿到子组件身上的数据 还可以给子组件写上ref="名字" 然后在父组件身上 this.$ref.名字就可以拿到子组件 身上的方法已经数据都可以获取到
4.v-model
v-model:将数据传递下去的同时 子组件可以修改父组件提供过来的数据(emit方法)
// 这是父组件 <template> <div> <child v-model="msg"></child> <p>{{msg}}</p> </div> </template> <script> import child from "../components/Child"; export default { data() { return { msg: "hello" }; }, components: { child } }; </script> // 这是子组件 <template> <div> <input :value="value" @input="$emit('input',$event.target.value)"> </div> </template> <script> export default { props: ["value"] }; </script> 复制代码
5.sync
sync:将数据传递下去的同时 允许子组件可以修改数据
// 父组件 <template> <div> {{num}} <child-a :count.sync="num" /> </div> </template> <script> import childA from "../components/ChildA"; export default { data() { return { num: 0 }; }, components: { childA } }; </script> // 子组件 <template> <div> <div @click="handleAdd">ADD</div> </div> </template> <script> export default { data() { return { counter: this.count }; }, props: ["count"], methods: { handleAdd() { this.$emit("update:count", ++this.counter); } } }; </script> 复制代码
6.,attrs,listeners
attrs包含的是父组件不被prop所识别的特性(📢:inheritAttrs为true属性才会渲染false时属性不会被渲染)可以通过v−bind="attrs"传给内部的组件 包含父组件啊种−事件监听器通过−="listeners包含父组件啊种v−on事件监听器通过v−on="listeners" 传给内部的足迹爱
<template> <div> <!-- 父组件 --> <h1>{{ count }}</h1> <son :msg="msg" :foo="foo" :boo="boo" :coo="coo" :doo="doo" title="前端工匠" @click.native="handleClick" v-on:focus="handleFocus" /> </div> </template> <script> import son from "./son.vue"; export default { name: "FatherVue", components: { son }, data() { return { msg: "父组件的msg", foo: "Javascript", boo: "Html", coo: "CSS", doo: "Vue", }; }, computed: { count() { return this.$children[0] && this.$children[0].count; }, }, mounted() { console.log(this.$children); // [子组件1, 子组件2,......] }, methods: { handleClick() { console.log("handleClick"); }, handleFocus() { console.log("handleFocus"); }, }, }; </script> <!-- 子组件 son.vue --> <template> <div> {{ msg }} <p>father 父组件的$attrs: {{ $attrs }}</p> <button @click="handleClick">click</button> <smallson v-bind="$attrs"></smallson> </div> </template> <script> import smallson from "./smallson.vue"; export default { name: "FuSon", components: { smallson }, inheritAttrs: true, // 可以关闭自动挂载到组件根元素上的没有在props声明的属性 computed: { msg() { return this.$parent.msg; }, }, data() { return { count: "我是子组件的count", }; }, methods: { handleClick() { console.log(this.$listeners); }, }, }; </script> <!-- smallson 组件 --> <template> <div> <h1>smallson</h1> {{ $attrs }} </div> </template> <script> export default { name: "SmallSon", inheritAttrs: false, }; </script> 复制代码
7.provide/inject
provide 提供变量 inject 注入变量
📢:
- 不论层级多深 只要调用了inject那么久可以注入provide的变量
- provide提供的数据在父组件中假设发生了变化 默认后辈的组件是不会响应式变化的 但是如果给的数据是this的数据的话 那么就是响应式的书
<template> <div id="app"> <myInject></myInject> </div> </template> <script> import myInject from "./components/zujiantongxin/inject.vue"; export default { name: "App", provide: { for: "provide", }, // provide() { // return { // baba: this, // msg: this.msg, // }; // }, 这个时候的数据就可以做到响应式的了 给的就是this的数据 给的就是响应式的数据 就可以做到响应式 components: { myInject, }, }; </script> <template> <div> <h2>inject 组件</h2> <h1>{{ for1 }}</h1> </div> </template> <script> export default { name: "myInject", data() { return { for1: this.for,//这一步可以省略的 }; }, inject: ["for"], mounted() { console.log(this.for); }, }; </script> 复制代码
7.eventBus
EventBus 本质上就是一个vue实例对象,它可以实现兄弟组件之前的通信,首先在A组件中设置EventBus.��自定义事件名称以及回调函数,然后�组件就是通过��������.on自定义事件名称以及回调函数,然后B组件就是通过eventbus.emit去触发那个自定义事件,将数据传递给A组件
Eventbus的原理实际上就是发布订阅的模式
发布订阅模式 :其实就是一种对象间一对多的依赖关系,当一个对象的状态发生改变的时候,所有依赖于它的对象都将得到状态改变的通知
vue中常见的发布订阅就是����emiton
redux中常见的就是subscribe
// eventBus.js import Vue from "vue"; export default new Vue(); <template> <!-- comA子组件 --> <div> <h1>{{ msg }}</h1> </div> </template> <script> import eventBus from "./eventBus"; export default { name: "面试ComA", data() { return { msg: "", }; }, mounted() { eventBus.$on("message", (val) => { this.msg = val; }); }, }; </script> <template> <div> <button @click="sendMsg">click 点击 想 COMA 发消息</button> </div> </template> <script> import eventBus from "./eventBus"; export default { name: "面试ComB", data() { return {}; }, methods: { sendMsg() { eventBus.$emit("message", "我是来自comB的数据"); }, }, }; </script> <template> <div id="app"> <comA></comA> <comB></comB> </div> </template> <script> import comA from "@/components/zujiantongxin/comA.vue"; import comB from "@/components/zujiantongxin/comB.vue"; export default { name: "App", components: { comA, comB, }, }; </script>