文章参考:https://libusi.blog.csdn.net/article/details/131668644
1 绑定的属性可否驼峰式? —>不可以
父子组件通信 props 如果用到驼峰标识会遇到问题(v-bind目前版本不支持驼峰,必须进行转化使用),一般建议props不使用驼峰传值,如果非要使用驼峰命名传值,需要注意格式;
<div :c-info="info"></div>
props:{
cInfo:{
type: Object, // Array, String
default() { return {}}
}
}
2 类型不一样,算传值成功了吗? --》不可以
总体:
两步走:
1、在子组件身上定义一个属性,将数据传递给子组件
<child-component :xxx="data"></child-component>
? 2、子组件使用props接收数据
? 在template同级的地方,写props:["xxx"]
<template>
<div>
<child-component :parentData="data"></child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
data () {
return {
data: '父组件传递的数据'
}
}
}
</script>
<template>
<div>
子组件接收到的数据:{{ parentData }}
</div>
</template>
<script>
export default {
props: {
parentData: String
}
}
</script>
总结:
props完整的写法是一个对象,其中default代表默认值,如果父组件没有传数据过来,就显示默认值; type是检查传过来的数据的类型;
可以设置传递时的类型(String,Number,Boolean,Array, Object,Date,Function,Symbol),也可以设置默认值等;
类型:
props:{
//必须是数字类型
propA: Number,
//必须是字符串或数字类型
propB: [String, Number],
//布尔值,如果没有定义,默认是true
propC: {
type:Boolean,
default:true
},
//数字,而且必须上传
propD: {
type: Number,
required:true
},
//自定义一个验证函数
propE: {
validator: function(value){
return value > 10;
}
},
//如果是数组或对象,默认必须是一个函数来返回
propF: {
type: Array,
default:function(){
return [];
}
}
}
});
使用 p a r e n t 和 parent和 parent和children父组件向子组件传递数据,
父组件通过$children获取子组件实例并调用子组件方法传递数据
<template>
<div>
<button @click="handleClick">向子组件传递数据</button>
<child-component ref="child"></child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
methods: {
handleClick () {
this.$refs.child.handleData('父组件传递的数据')
}
}
}
</script>
<template>
<div>
子组件
</div>
</template>
<script>
export default {
methods: {
handleData (data) {
console.log('子组件接收到的数据:' + data)
}
}
}
</script>
父组件向子组件传递属性和事件,子组件通过 a t t r s 获取属性,通过 attrs获取属性,通过 attrs获取属性,通过listeners获取事件并绑定在子组件上。
<template>
<div>
<child-component attr1="属性1" attr2="属性2" @event1="handleEvent"></child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
methods: {
handleEvent (data) {
console.log('父组件接收到的数据:' + data)
}
}
}
</script>
<template>
<div>
子组件
</div>
</template>
<script>
export default {
mounted () {
this.$emit('event1', '子组件传递的数据')
}
}
</script>
父组件向子组件传递数据,父组件通过provide提供数据,子组件通过inject注入数据。
<template>
<div>
<child-component></child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
provide () {
return {
parentData: '父组件提供的数据'
}
}
}
</script>
<template>
<div>
<child-component></child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
provide () {
return {
parentData: '父组件提供的数据'
}
}
}
</script>
子组件可以通过$parent获取父组件的实例,进而访问父组件的属性和方法。
<template>
<div>
<child-component></child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
data () {
return {
parentData: '父组件数据'
}
},
methods: {
handleParent () {
console.log('父组件的方法')
}
}
}
</script>
<template>
<div>
<button @click="handleChild">调用父组件方法</button>
</div>
</template>
<script>
export default {
methods: {
handleChild () {
console.log(this.$parent.parentData)
this.$parent.handleParent()
}
}
}
</script>
子组件可以通过$root获取根组件的实例,进而访问根组件的属性和方法
<template>
<div>
<child-component></child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
mounted () {
console.log('根组件的数据:' + this.rootData)
this.rootMethod()
},
data () {
return {
rootData: '根组件的数据'
}
},
methods: {
rootMethod () {
console.log('根组件的方法')
}
}
}
</script>
<template>
<div>
子组件
</div>
</template>
<script>
export default {
mounted () {
console.log('根组件的数据:' + this.$root.rootData)
this.$root.rootMethod()
}
}
</script>
组件向父组件传递数据,子组件通过** e m i t 触发 ? ? 事件,父组件通过 ? ? emit触发**事件,父组件通过** emit触发??事件,父组件通过??on监听**事件并接收数据。
子传父的要点:子组件修改父组件的数据,本质上是去触发父组件修改数据
1.子级通过this.$emit('xxx', arg);
2.父级 <tag @xxx="fatherEvent" ></tag>
<template>
<div>
<child-component @childEvent="handleChild"></child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
methods: {
handleChild (data) {
console.log('父组件接收到的数据:' + data)
}
}
}
</script>
<template>
<div>
<button @click="handleClick">点击触发事件</button>
</div>
</template>
<script>
export default {
methods: {
handleClick () {
this.$emit('childEvent', '子组件传递的数据')
}
}
}
</script>
父组件可以通过$refs获取子组件的实例,进而访问子组件的属性和方法
<template>
<div>
<button @click="handleParent">向子组件传递数据</button>
<child-component ref="child"></child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
methods: {
handleParent () {
this.$refs.child.childData = '父组件修改的数据'
}
}
}
</script>
<template>
<div>
子组件接收到的数据:{{ childData }}
</div>
</template>
<script>
export default {
data () {
return {
childData: '子组件原始数据'
}
}
}
</script>
父组件和子组件之间通过中央事件总线(EventBus)进行通信。
import Vue from 'vue'
export const EventBus = new Vue()
<template>
<div>
<button @click="handleParent">向子组件传递数据</button>
<child-component></child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
import { EventBus } from './EventBus'
export default {
components: {
ChildComponent
},
methods: {
handleParent () {
EventBus.$emit('parent-event', '父组件传递的数据')
}
}
}
</script>
<template>
<div>
子组件接收到的数据:{{ childData }}
</div>
</template>
<script>
import { EventBus } from './EventBus'
export default {
data () {
return {
childData: ''
}
},
mounted () {
EventBus.$on('parent-event', data => {
this.childData = data
})
}
}
</script>
父组件和子组件之间通过Vuex进行通信,共享同一状态树。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
data: '共享的数据'
},
mutations: {
setData (state, data) {
state.data = data
}
}
})
<template>
<div>
<button @click="handleParent">向子组件传递数据</button>
<child-component></child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
import store from './store'
export default {
components: {
ChildComponent
},
methods: {
handleParent () {
store.commit('setData', '父组件传递的数据')
}
}
}
</script>
<template>
<div>
子组件接收到的数据:{{ childData }}
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
computed: {
...mapState(['data']),
childData () {
return this.data + ',子组件加工处理后的数据'
}
}
}
</script>
provide / inject 可以让祖先组件向所有后代组件注入一个依赖,让这些组件使用相同的依赖注入。
<template>
<div>
<child-component></child-component>
<grand-child></grand-child>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
import GrandChild from './GrandChild.vue'
export default {
components: {
ChildComponent,
GrandChild
},
provide: {
sharedObj: {
message: '这是祖先组件注入的对象'
}
}
}
</script>
<template>
<div>
子组件
</div>
</template>
<script>
export default {
inject: ['sharedObj']
}
</script>
<template>
<div>
子组件接收到的数据:{{ childData }}
</div>
</template>
<script>
export default {
inject: ['sharedObj'],
computed: {
childData () {
return this.sharedObj.message + ',子组件加工处理后的数据'
}
}
}
</script>
使用provide / inject注入Vuex的实例,使所有组件使用相同的Vuex实例。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
data: '共享的数据'
},
mutations: {
setData (state, data) {
state.data = data
}
}
})
<template>
<div>
<child-component></child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
import store from './store'
export default {
components: {
ChildComponent
},
provide () {
return {
store
}
}
}
</script>
<template>
<div>
组件接收到的数据:{{ componentData }}
</div>
</template>
<script>
export default {
inject: {
store: {
default: null
}
},
computed: {
componentData () {
return this.store.state.data + ',组件加工处理后的数据'
}
}
}
</script>
使用浏览器缓存来存储数据,在需要通信的组件中存储并监听缓存中的数据。
<template>
<div>
<button @click="handleClick">向组件B传递数据</button>
</div>
</template>
<script>
export default {
methods: {
handleClick () {
localStorage.setItem('data', '组件A传递的数据')
}
}
}
</script>
<template>
<div>
组件B接收到的数据:{{ data }}
</div>
</template>
<script>
export default {
data () {
return {
data: ''
}
},
mounted () {
window.addEventListener('storage', this.handleStorageUpdate)
this.updateData()
},
beforeDestroy () {
window.removeEventListener('storage', this.handleStorageUpdate)
},
methods: {
handleStorageUpdate (event) {
if (event.key === 'data') {
this.updateData()
}
},
updateData () {
this.data = localStorage.getItem('data') || ''
}
}
}
</script>
使用一个消息中心,订阅者向消息中心订阅消息,发布者向消息中心发布消息,消息中心将消息通知给所有订阅者。
// PubSub.js
export const PubSub = {
events: {},
subscribe (event, callback) {
if (!this.events[event]) {
this.events[event] = []
}
this.events[event].push(callback)
},
publish (event, data) {
if (!this.events[event]) {
this.events[event] = []
}
this.events[event].forEach(callback => callback(data))
}
}
<template>
<div>
<button @click="handleClick">向组件B传递数据</button>
</div>
</template>
<script>
import { PubSub } from './PubSub'
export default {
methods: {
handleClick () {
PubSub.publish('event', '组件A传递的数据')
}
}
}
</script>
<template>
<div>
组件B接收到的数据:{{ data }}
</div>
</template>
<script>
import { PubSub } from './PubSub'
export default {
data () {
return {
data: ''
}
},
mounted () {
PubSub.subscribe('event', data => {
this.data = data
})
}
}
</script>
使用WebSocket协议实现实时通信,将所有组件连接到同一个WebSocket服务器,通过推送消息实现通信。
const ws = new WebSocket('ws://localhost:3000')
ws.onopen = function () {
console.log('WebSocket已连接')
}
ws.onclose = function () {
console.log('WebSocket已关闭')
}
ws.onerror = function () {
console.log('WebSocket出错')
}
<template>
<div>
<button @click="handleClick">向组件B传递数据</button>
</div>
</template>
<script>
const ws = new WebSocket('ws://localhost:3000')
export default {
methods: {
handleClick () {
ws.send('组件A传递的数据')
}
}
}
</script>
<template>
<div>
组件B接收到的数据:{{ data }}
</div>
</template>
<script>
const ws = new WebSocket('ws://localhost:3000')
export default {
data () {
return {
data: ''
}
},
mounted () {
ws.onmessage = event => {
this.data = event.data
}
}
}
</script>
使用路由参数来传递数据,通常适用于父子组件之间或兄弟组件之间的通信。
<template>
<div>
点击以下链接可以传递数据:<br>
<router-link :to="{ name: 'child', params: { data: '父组件传递的数据' } }">传递数据到子组件</router-link>
</div>
</template>
<template>
<div>
子组件接收到的数据:{{ $route.params.data }}
</div>
</template>
<script>
export default {
mounted () {
console.log('子组件接收到的数据:' + this.$route.params.data)
}
}
</script>
<template>
<div>
兄弟组件接收到的数据:{{ $route.params.data }}
</div>
</template>
<script>
export default {
mounted () {
console.log('兄弟组件接收到的数据:' + this.$route.params.data)
}
}
</script>
使用Vuex管理公共状态,组件通过Vuex进行通信。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
data: '共享的数据'
},
mutations: {
setData (state, data) {
state.data = data
}
}
})
<template>
<div>
<button @click="handleClick">向组件B传递数据</button>
</div>
</template>
<script>
import store from './store'
export default {
methods: {
handleClick () {
store.commit('setData', '组件A传递的数据')
}
}
}
</script>
<template>
<div>
组件B接收到的数据:{{ data }}
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
computed: {
...mapState(['data'])
},
mounted () {
console.log('组件B接收到的数据:' + this.data)
}
}
</script>