乐趣区

关于前端:Vue组件通信方式一文搞懂

本文整顿总结了开发中应用频率比拟多的 vue 组件通信形式,置信无论是面试还是理论开发,总会对你有所帮忙。

Props & $emit

这是应用频率最多、最根底,必须要把握的用法,应用非常简单,用一个 helloworld 组件示例。

<div id="app">
    <HelloWorld msg="Welcome to Your Vue.js App"/>
  </div>
<template>
  <div class="hello">
    <h1>{{msg}}</h1>
  </div>
</template>
export default {
  name: 'HelloWorld',
  props: {msg: String}
}

数据从父级传递到子级,子级组件读取应用,子级不举荐间接在外部批改 props(会导致渲染异样、监听错乱),而应该告诉父组件去更新 msg。

<template>
  <div class="hello">
    <h1>{{msg}}</h1>
    <button @click="resetMsg">i want change msg</button>
  </div>
</template>
export default {
  name: 'HelloWorld',
  props: {msg: String},
  methods: {resetMsg () {this.$emit('update');
    }
  }
}

父组件:

<template>
  <div id="app">
    <HelloWorld :msg="msg" @update="update" />
  </div>
</template>
methods: {update () {this.msg = "Welcome to my Blog";}
  }

$attrs & $listenners

父组件不变,子组件用过 $attrs 在模板和 JS 中应用父组件提供的数据,应用 $listenners 执行父组件内办法(也能够用于跨级组件)。

<template>
  <div class="hello">
    <h1>{{$attrs.msg}}</h1>
    <button @click="resetMsg">i want change msg</button>
  </div>
</template>
export default {
  name: 'HelloWorld',
  methods: {resetMsg () {this.$listeners.update()
      // this.$emit('update');
    }
  }
}

$children & $parent

父组件内应用 $children 能够拜访子组件列表,依据所在序号找到指定组件,获取数据和办法。

<template>
  <div id="app">
    <HelloWorld />
    <button @click="showMsg">show children msg</button>
    <h1>{{msg}}</h1>
  </div>
</template>
showMsg () {console.log(this.$children)
    this.msg = this.$children[0].msg;
 }

应用 $parent 获取父组件实例,也就能够间接调用办法和获取数据了,留神: 此实例获取形式并非响应式,如果父 / 子一侧数据变动,之前获取的数据不会刷新!

<template>
  <div class="hello">
    <h1>{{msg}}</h1>
    <button @click="resetMsg">i want change msg</button>
  </div>
</template>
resetMsg () {console.log(this.$parent);
    this.msg = "Welcome to my Blog";
}

provider & inject

在提供数据的组件中表明提供的数据和办法,在子孙组件中 inject 所需数据和办法。

<template>
  <div id="app">
    <HelloWorld />
  </div>
</template>
provide: function () {
    return {msg: () => this.msg,
      user: this.user,
      reset: this.updateNickName,
      resetMsg: this.updateMsg
    }
  },
  data () {
    return {
      msg: 'Welcome to Your Vue.js App',
      user: {nickName: 'Jack Chen'},
    }
  },
  methods: {updateNickName () {this.user.nickName = "Jet Li";},
    updateMsg () {this.msg = "Welcome to Your Vue.js Blog";}
  }

子 / 孙级组件:

<template>
  <div class="hello">
    <h1>{{_msg}} {{user.nickName}}</h1>
    <button @click="resetMsg">reset msg</button>
    <button @click="reset">reset nickName</button>
  </div>
</template>
inject: ['msg','user', 'reset', 'resetMsg'],
  computed: {_msg () {return this.msg();
    }
  },

同 $children 和 $parent 一样,此形式并非百分百响应式,对于根本类型数据,想要它放弃响应式,须要转换为一个函数,返回此变量,在须要应用的组件中,执行办法或者应用计算属性形式。

ref(s)

这种形式更显著地具备父级拜访子级组件的特色,不能纯正算相互通信,只能作为特定场景的应用计划之一。

<template>
  <div id="app">
    <HelloWorld ref="hellowd"/>
    <button @click="getMsg">get msg</button>
    <h2>{{msg}}</h2>
  </div>
</template>
getMsg () {const hellowd = this.$refs['hellowd'];
  this.msg = hellowd.msg;
},
updateMsg () {const hellowd = this.$refs['hellowd'];
  hellowd.resetMsg();}

通过操作发现,只有是通过实例获取的,均非响应式

async & update

<template>
  <div id="app">
    <HelloWorld :msg.sync="msg"/>
    <h2>{{msg}}</h2>
  </div>
</template>
<template>
  <div class="hello">
    <h1>{{msg}}</h1>
    <button @click="updateMsg">update msg</button>
  </div>
</template>
updateMsg () {this.$emit('update:msg', "Welcome to Your Vue.js Blog");
}

这种更新是响应式的,父组件有援用的中央都会同步更新。

其它形式

  • Vuex 数据管理 Store
  • eventBus 挂载在 Vue 原型上,应用 on 监听,emit 流传事件
  • slot 插槽,次要用于模板解决中
  • 本地缓存
  • 本人实现一个 Store
退出移动版