组件通信
父子通信
目标:为了复用
- 靠属性props
注意:属性与状态的区分
<navbar myname="电影" :myright="false" :myparent="parent"></navbar>
myname是属性;电影是状态
props里包含的是属性;data里包含的是状态
属性不能随意修改,会造成父子之间的数据流紊乱,不统一。
状态可以随意修改。
子父通信
目标:为了满足需求 (抽屉功能)
- 靠事件$emit
兄弟通信——通过中间人父组件实现
事件$emit与属性props结合使用
叔侄通信、表兄弟通信
1、通过bus中央事件总线实现
2、通过vuex状态管理实现,全家桶
bus中央事件总线——订阅发布模式
订阅$on("aaa",()=>{})
发布$emit("aaa")
先关注订阅号$on
,后续订阅号发消息$emit
才能接收的到。
- 生命周期mounted挂载
vuex状态管理
。。。。。
ref组件通信——打破组件之间是隔离的
缺点:打乱数据流向,不易维护
优点:打破组件之间是隔离的,ref绕过通信方案,直接就能改变孩子的状态,也不用传属性props,打破父子之间的壁垒。
比喻:组件通信是成年孩子与父母的交流,父母给孩子愿意接收才算成功;ref是幼儿与父母的交流,父母给不用管孩子的意愿
ref绑定dom节点拿到的就是dom对象
ref绑定组件,拿到的就是组件对象
<!-- 引用ref没放在组件上与放在组件上是有区别的 -->
<input type="text" ref="mytext"/>
<!-- 可以通过v-model拿到输入框的值 还有一个方案:通过ref来拿-->
<input type="password" ref="mypassword"/>
<button @click="handleAdd">add</button>
<child ref="mychild"></child>
methods:{
handleAdd(){
//ref绑定dom节点拿到的就是dom对象
console.log(this.$refs);
//this.$refs是固定的,加s是因为可以绑多个,拿到的是dom节点
console.log(this.$refs.mytext,this.$refs.mypassword);
//拿到的是dom节点
console.log(this.$refs.mytext.value,this.$refs.mypassword.value);
//拿到dom节点的值
//不一定非得绑在input上,绑在div上也是可以的(接下来的操作请三思,最好不要直接操作原生dom)
//绑定在组件上拿到的是组件对象,组件对象有什么用?
console.log(this.$refs.mychild);
//这个时候myname对我来说直接点就可以点到了,不用使用props接收也能得到
console.log(this.$refs.mychild.myname);
//父组件拿到这个状态后不满足,居然想给人家改这个状态
this.$refs.mychild.myname="child-222222";
//相当于不经过孩子的同意拿到他的东西后还给她改了
//ref绕过通信方案,直接就能改变孩子的状态,也不用传属性props,打破父子之间的壁垒,数据流向混乱,使用少。
}
vue.component("child",{
//定义一个状态,child组件中定义一个状态,这个状态只在自己内部用,没打算给父组件自己偷偷摸摸在这用,
data(){
return{
myname:"child_1111111"
}
},
template:`
<div>
child--{{myname}}
</div>
`
})
总结:
1、 dom上定义ref=“aaa”
2、子组件中定义一个状态(属性名)
3、父组件中使用this.$refs.aaa.属性名可以访问到
应用—动态组件—组件的显示与隐藏
点击选项卡切换组件
//主要代码 view中
<component :is="which"></component>
优化:home组件的serch内容点其他的按钮后再回来还在。
<keep-alive>
<component :is="which"></component>
</keep-alive>
原本:
<home v-show="which==='home'"></home>
<list v-show="which==='list'"></list>
<shopcar v-show="which==='shopcar'"></shopcar>
component是固定的,is也是固定的。which就是你说我是谁我就是谁。
<li @click="which='home'">home</li>
<li @click="which='list'">list</li>
<li @click="which='shopcar'">shopcar</li>
<script type="text/javascript">
Vue.component("home",{
template:
`<div>
home
<input type="search"/>
</div>`
})
Vue.component("list",{
template:
`<div>
list
</div>`
})
Vue.component("shopcar",{
template:
`<div>
shopcar
</div>`
})
var vm=new Vue({
el:"#box",
data:{
which:"home"
}
})
</script>