父子组件通信
propeventstyle和classnatvie修饰符$listenersv-modelsync修饰符$parent和$children$slots和$scopedSlotsref
跨组件通信
Provide和Injectroutervuexstore模式eventbus
父子组件通信
prop
最常见的组件通信形式,由父组件向子组件传递。prop可接管一个数组或对象
//子组件<script>export default { name: "Comp", //数组形式 props:[....] // ↓ 对象形式 props: { datas: { type: Object, default: () => { return {}; } }, }</script>
event
子组件向父组件发送告诉,并传递参数
子组件
methods:{ // 通过 $emit向父组件发送一个告诉 handleEvent(){ this.$emit('eventMsg', option) } }
父组件
methods:{ // 监听子组件定义的办法 eventMsg(option){ console.log(option); } }
style 和 class
父组件能够向子组件传递style 和 class ,style 和 class将合并到子组件根元素上
父组件
<template> <div id="app"> <HelloWorld style="color:red" class="hello" msg="Welcome to Your Vue.js App" /> </div></template><script>import HelloWorld from "./components/HelloWorld.vue";export default { components: { HelloWorld, },};</script>
子组件
<template> <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 Your Vue.js App</h1> </div></div>
attribute
父组件在应用子组件时,在子组件上定义一些属性,这些属性将作用于子组件的根元素上,然而不包含style和class
父组件
<HelloWorld data-a="1" data-b="2" msg="Welcome to Your Vue.js App" />
子组件
<template> <div> <h1>{{msg}}</h1> </div></template><script>export default { name: "HelloWorld", props: { msg: String, }, created() { // 通过$attrs获取父组件定义的 attribute 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>
Tip:子组件能够通过定义 inheritAttrs:false 来缓和 attribute 附着在子组件根元素上 但不影响通过 $attrs 获取数据
natvie修饰符
在注册事件时,父组件能够通过 navite 修饰符,将事件注册到子组件根元素上
父组件
<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>
最终渲染后果
<template> <div id="app"> <h1>Hello World</h1> </div></template>// 当点击app时。会触发父组件定义的 handleClick 办法
$listeners
子组件能够通过 $listeners 获取父组件传递过去的所有处理函数
v-model
父组件在应用子组件时,能够在子组件上绑定v-model,子组件通过定义model的prop和event还获取父组件定义的值
父组件
`
<Compn v-model="datas" />
`
子组件
<script>export default { //分类筛选组件 name: "sortFilter", //定义实现v-modal的属性与事件 model: { prop: "value", event: "change" }, props: { //绑定的值 value: { type: [String, Number], default: "" } }, created() { console.log(this.value) }, </script>
sync 修饰符
和 v-model相似,用于双向数据绑定,不同点在于 v-model只能针对一个数据进行绑定,而 sync 修饰符没有限度
子组件
<template> <div> <p> <button @click="$emit(`update:num1`, num1 - 1)">-</button> {{ num1 }} <button @click="$emit(`update:num1`, num1 + 1)">+</button> </p> <p> <button @click="$emit(`update:num2`, num2 - 1)">-</button> {{ num2 }} <button @click="$emit(`update: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 :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 class="hello"> <button @click="handelParent">获取父组件实例</button> <button @click="handelChild">获取子组件实例</button> <Child /> </div></template><script>import Child from "./Children.vue";export default { name: "HelloWorld", props: { msg: String, }, components: { Child, }, methods: { handelParent() { console.log("父组件实例:", this.$parent); }, handelChild() { console.log("子组件实例", this.$children); }, },};</script>
ref
在应用组件时,能够通过在组件上定义ref来获取组件实例
<template> <div class="hello"> <button @click="handelChild">获取子组件实例</button> <Child ref="child" /> </div></template><script>import Child from "./Children.vue";export default { name: "HelloWorld", props: { msg: String, }, components: { Child, }, methods: { handelChild() { console.log("子组件实例", this.$refs.child); }, },};</script>
跨组件通信
provide 和 Inject
provide和inject 能够实现深层组件通信,顶层组件只需定义provide,底层组件通过inject承受数据
顶层组件
// 父组件provide(){ msg:'hello Children'},// 子组件inject: ['msg']created () { console.log(this.msg) // hello Children}
router
如果一个组将扭转了地址栏,所有监听地址栏的组将都会做出相应的扭转,
//监听路由变动watch:{ $route(to,from) { console.log(to,from); }}
vuex
vuex 过于轻便,通常不倡议在小型我的项目中应用,小型我的项目能够应用store 或 eventbus代替vuex,vuex实质上就是一个数据仓库。在此不做过多赘述,先挖一个坑,下回再叙。
store 模式
store模式其实就是一个一般的js模块,各组件能够导入该模块,将数据放到data外面,此时store就具备响应式了。
// 导出一个 store.js模块export default { userInfo:{...}, loginInfo:{...}}// A子组件导入 store模块import store from './store.js'export default { name:'Acompon', data(){ userInfo: store.userInfo }}// B子组件导入 store模块import store from './store.js'export default { name:'Bcompon', data(){ loginInfo: store.loginInfo }}
tip: store模式的毛病是无奈跟踪数据的扭转,因为所有组件都能够更改数据
eventbus
eventbus事件总线相当于一个桥梁,作为所有组将的一个事件核心,所有组件皆可往eventbus外面注册事件,也能够监听事件。
// 定义一个eventbus模块import Vue from 'vue'export const EventBus = new Vue()// 在main.js里导入该模块并挂载到全局// main.jsimport eventbus from './eventbus.js'Vue.prototype.$eventBus = eventbus所有子组件向eventbus里组 注册 或者 监听 事件 // 组件A 通过 $emit()注册事件sendMsg() { this.$eventBus.$emit("aMsg", 'from A');}// 组件B 通过 $on 监听事件this.$eventBus.$on("aMsg", (msg) => { // A发送来的音讯 console.log(msg) // from A})// 通过 $off() 能够敞开事件