写点什么

vue 组件通信方式

用户头像
法医
关注
发布于: 2 小时前
vue组件通信方式

以下这些通信方式,有的在开发中几乎用不到,不用去背,所以不用太纠结,也不要有太多心里负担,有个印象就行了,之所以整理纯粹是为了面试过程中可能会问到:vue 组件之间有哪些通信方式? 回答的时候把名字一说就行了😚

父子组件通信

绝大部分vue本身提供的通信方式,都是父子组件通信


  • prop 最常见的组件通信方式之一,由父组件传递到子组件。

  • event 最常见的组件通信方式之一,当子组件发生了某些事,可以通过event通知父组件。

  • style 和 classstyleclass通信范围比较窄,是传递样式的,父组件可以向子组件传递styleclass,最终它们会合并到子组件的根元素中。


示例:


父组件


<template>  <div id="app">    <HelloWorld    //父组件身上用到了子组件,在这里写的样式会传递到子组件的根元素身上      style="color:red"      class="hello"      msg="Welcome to follow me!"    />  </div></template>
<script>import HelloWorld from "./components/HelloWorld.vue";
export default { components: { HelloWorld, },};</script>
复制代码


子组件


<template>//如果子组件身上已存在class和style属性,那么会与父组件传过来的样式进行合并  <div class="world" style="text-align:center">    <h1>{{msg}}</h1>  </div></template>
<script>export default { name: "HelloWorld", props: { msg: String, },};</script>
复制代码


最终渲染结果:


<div id="app">  <div class="hello world" style="color:red; text-aling:center">    <h1>Welcome to follow me!</h1>  </div></div>
复制代码


  • attributetattributet在开发中很少会用到,如果父组件传递了一些属性( 属性并不包括styleclass,它们会被特殊处理)到子组件,但子组件并没有声明这些属性,则它们被称为attribute,这些属性会直接附着在子组件的根元素上,而且我们可以在子组件中通过this.$attrs拿到


示例


父组件


<template>  <div id="app">    <!-- 除 msg 外,其他都是 attribute -->    <HelloWorld      data-a="1"      data-b="2"      msg="Welcome to Your Vue.js App"    />  </div></template>
<script>import HelloWorld from "./components/HelloWorld.vue";
export default { components: { HelloWorld, },};</script>
复制代码


子组件


<template>  <div>    <h1>{{msg}}</h1>  </div></template>
<script>export default { name: "HelloWorld", inheritAttrs: false,//禁止将attribute附着在子组件的根元素上,但不影响通过`$attrs`获取 props: { msg: String, }, created() { console.log(this.$attrs); // 得到: { "data-a": "1", "data-b": "2" } },};</script>
复制代码


最终渲染结果:


<div id="app">  <div data-a="1" data-b="2">    <h1>Welcome to Your Vue.js App</h1>  </div></div>
复制代码


子组件可以通过inheritAttrs: false配置,禁止将attribute附着在子组件的根元素上,也就是data-a="1" data-b="2"不会出现在子组件的根元素身上,但不影响通过$attrs获取。


  • natvie 修饰符


在注册事件时,父组件可以使用native修饰符,将事件注册到子组件的根元素上。


示例


父组件


<template>  <div id="app">    <HelloWorld @click.native="handleClick" />  </div></template>
<script>import HelloWorld from "./components/HelloWorld.vue";
export default { components: { HelloWorld, }, methods: { handleClick() { console.log(1); }, },};</script>
复制代码


子组件


<template>  <div>    <h1>Hello World</h1>  </div></template>
复制代码


渲染结果


<div id="app">  <!-- 点击该 div,会输出 1 -->  <div>    <h1>Hello World</h1>  </div></div>
复制代码


  • $listeners


子组件可以通过$listeners获取父组件传递过来的所有事件处理函数。


  • v-model

  • sync 修饰符


v-model的作用类似,都是语法糖,用于双向绑定,不同点在于v-model只能针对一个数据进行双向绑定,而sync修饰符没有限制,在 vue3 中没有 sync 修饰符,它会和 v-model 合并成一个。


示例


下面代码做了这样一件事:父组件给子组件传了两个值num1num2,子组件并没有能力修改,但是子组件有一个触发事件的能力,故触发updata1updata2,并且传了两个新值num1 ± 1num2 ± 1让父组件进行处理


子组件


<template>  <div>    <p>      <button @click="$emit(`update1:num1`, num1 - 1)">-</button>      {{ num1 }}      <button @click="$emit(`update1:num1`, num1 + 1)">+</button>    </p>    <p>      <button @click="$emit(`update2:num2`, num2 - 1)">-</button>      {{ num2 }}      <button @click="$emit(`update2:num2`, num2 + 1)">+</button>    </p>  </div></template>
<script>export default { props: ["num1", "num2"],};</script>
复制代码


父组件


<template>  <div id="app">    <Numbers :num1.sync="n1" :num2.sync="n2" />    <!-- 上面 Numbers 等同于下面 Numbers  -->    <Numbers      :num1="n1"      @update:num1="n1 = $event"      :num2="n2"      @update:num2="n2 = $event"    />  </div></template>
<script>import Numbers from "./components/Numbers.vue";
export default { components: { Numbers, }, data() { return { n1: 0, n2: 0, }; },};</script>
复制代码


效果展示:



  • $parent$children


在组件内部,可以通过$parent$children属性,分别得到当前组件的父组件和子组件实例


示例:


<template>  <div id="app">    <h1>法医</h1>    <A />    <A />  </div></template>
<script>import A from "../src/component/A"
export default { components: { A }, mounted(){ console.log(this.$children); }
};</script>
复制代码



  • ref 父组件可以通过ref获取到子组件的实例,也可以用在 dom 身上,拿到当前的 dom 元素

跨组件通信

除了ProvideInject是 vue 提供的通信方式,其余方式都是要依赖第三方间接通信


  • ProvideInject


这个是 vue 提供的跨组件通信方式,但是兄弟组件是不行,只能是父子组件或者祖先和后代这种关系才能通信。


示例


// 父级组件提供 'foo'var Provider = {  provide: {    foo: 'bar'  },  // ...}
// 子组件注入 'foo'var Child = { inject: ['foo'], created () { console.log(this.foo) // => "bar" } // ...}
复制代码


详见:https://cn.vuejs.org/v2/api/?#provide-inject


  • router


如果一个组件改变了地址栏,所有监听地址栏的组件都会做出相应反应


最常见的场景就是通过点击router-link组件改变了地址,router-view组件就渲染其他内容


  • vuex


适用于大型项目的数据仓库


  • store模式


适用于中小型项目的数据仓库


// store.jsconst store = {  loginUser: ...,  setting: ...}
// compAconst compA = { data(){ return { loginUser: store.loginUser } }}
// compBconst compB = { data(){ return { setting: store.setting, loginUser: store.loginUser } }}
复制代码


  • eventbus


组件通知事件总线发生了某件事,事件总线通知其他监听该事件的所有组件运行某个函数


😊 好了, 以上就是我的分享,希望小伙伴们点赞 👍 支持一下哦~ 😘,我会更有动力的 🤞

发布于: 2 小时前阅读数: 5
用户头像

法医

关注

公众号@前端猎手 2020.07.17 加入

我是法医,一只治疗系前端码猿🐒,与代码对话,倾听它们心底的呼声,期待着大家的点赞👍与关注➕。 [微信:wKavin]

评论

发布
暂无评论
vue组件通信方式