参考:
https://blog.csdn.net/weixin_33813128/article/details/94177294
类似方法调用或属性访问
目标
- 子组件给父组件传参数 $emit(触发父组件里的事件),松藉合(掌握)
- 通过 $parent 获取父组件数据和调用父组件方法,强藉合(了解)
- 子组件访问根组件 $root(了解)
- 动态组件
当父组件获取的数据,需用通过子组件来动作(click、change等)改变后数据,这时候我们通过ref是获取不到的,获取的也是改变前的数据。这时候需要用$emit
一、子组件给父组件传参数 $emit
emit 为触发之意,主要作用是子组件触发父组件事件,完成对父组件的操作
触发事件与方法调用不同,方法调用另侧必须响应,但触发事件,父类可以不响应,不响应也不会报错
vm.$emit( event, arg )
$emit 绑定一个自定义事件event,当这个这个语句被执行到的时候,就会将参数arg传递给父组件;父组件通过@event监听并接收参数。
这里面隐式的定义了子-父传递的步骤:
- 子组件$emit中的第一个参数定义父组件的接收事件event,第二个参数是传输的数据
- 父组件用@event监听并接收参数,指定接收到数据后的处理函数
父组件
<template>
<div>
<h1>{{title}}</h1>
<child @getMessage="showMsg" ></child>
</div>
</template>
<script>
import child from '@/components/emit/child'
export default {
data() {
return {
title:'我是父组件的初始值'
};
},
components:{child},
methods: {
showMsg(param_title) {
this.title=param_title;
}
},
}
</script>
子组件
<template>
<h1>我是测试EMIT的子组件</h1>
</template>
<script>
export default {
mounted:function(){
this.$emit('getMessage','我是子组件给父组件传递的值')
},
data() {
return {
};
}
}
</script>
路由
import emittest from '@/components/emit/parent'
{
path: '/emittest',
name: 'emittest',
component: emittest
}
测试
http://localhost:8080/#/emittest
$emit传递多个参数
改造子组件
<script>
export default {
mounted:function(){
//第一步:子组件把数据发射给父组件,并约定好父组件用@child-msg绑定接收的方法
this.$emit('getMessage','我是子组件给父组件传递的值','追加的数据')
},
data() {
return {
};
}
}
</script>
父组件第一种写法
<template>
<div>
<p>我是父组件</p>
<!-- step 2父类响应子类的事件,并且指派给showmessage方法进行处理-->
<child @getMessage="showmessage"></child>
</div>
</template>
<script>
import child from '@/components/emit/emitchild'
export default{
data(){
return {
}
},
components:{
child
},
//step3 写对应的事件处理函数
methods:{
showmessage:function(data,data2){
alert(`我收到的子类的信息为`+" "+data+" "+data2);
//可以根据业务进行后处理
}
}
}
</script>
父组件第二种写法
<template>
<div>
<p>我是父组件</p>
<!-- step 2父类响应子类的事件,并且指派给showmessage方法进行处理
arguments参数名是固定的,不能任意改-->
<child @getMessage="showmessage(arguments)"></child>
</div>
</template>
<script>
import child from '@/components/emit/emitchild'
export default{
data(){
return {
}
},
components:{
child
},
//step3 写对应的事件处理函数
methods:{
showmessage:function(data){
for (var i = 0; i < data.length; i++) {
alert(data[i]);
}
}
}
}
</script>
关键代码
![](https://img.haomeiwen.com/i13938574/32d6c8c1e87edfea.png)
![](https://img.haomeiwen.com/i13938574/6cbbdcb485e73fdd.png)
![](https://img.haomeiwen.com/i13938574/3d34adbb5558cea4.png)
典型应用:
比如两个平行的子组件,一个是菜单,一个是列表,他俩有共同父组件,如果想联动,点击菜单项时可以触发父组件的方法,然后这个方法负责去调用列表组件更新
第二种子类增加或减少参数时,父类不需要修改代码,扩展性更强,建议使用
通过$parent 获取父组件数据或调用父组件方法
子组件
<template>
<div>
<p>子组件</p>
<button @click="showParentMsg">点我获取父组件的msg</button>
</div>
</template>
<script>
export default{
data(){
return {
msg:''
}
},
methods:{
showParentMsg:function(){
let msg=this.$parent.msg;
alert(msg);
}
}
}
</script>
父组件
<template>
<div>
<child001></child001>
</div>
</template>
<script>
import child001 from '@/components/parentdemo/child001'
export default{
data(){
return {
msg:'我是父组件里的msg'
}
},
components:{child001}
}
</script>
<style>
</style>
路由
import parentdemo from '@/components/parentdemo/parent'
{
path: '/parentdemo',
name: 'parentdemo',
component: parentdemo
}
调用父类的方法
父类里新增加方法
methods:{
say:function(){
alert("大家好");
}
}
子类调用
this.$parent.say();
子组件访问根组件 $root(不常用,了解)
子组件访问根组件 $root 当前组件树的根 Vue 实例。如果当前实例没有父实例,此实例将会是其自已。
改造上面的子组件child001里的showParentMsg方法
methods:{
showParentMsg:function(){
let msg=this.$root.msg;
console.log(msg);
}
}
再执行发现为undefined
$root找的是最根上的对象,在脚手架里是 main.js
在 main.js里添加上如下内容,再试一下,就可以了
data(){
return{
msg:'根下的msg'
}
},
![](https://img.haomeiwen.com/i13938574/71a851e6e604dc75.png)
高级篇:动态组件
有的时候,在不同组件之间进行动态切换是非常有用的,比如在一个多标签的界面里,可以通过component :is来指定当前切换到哪个页面。
例子:动态切换template形式组件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="../js/vue.min.js"></script>
</head>
<body>
<div id="app">
<button @click="activeobj='runoob'">切换到页面1</button>
<button @click="activeobj='runoob2'">切换到页面2</button>
<!-- <runoob></runoob> -->
<!--这个位置变成动态切换的-->
<component :is="activeobj"></component>
</div>
<template id="temp1">
<div>
<h1>我是第一行内容</h1><br>
<h2>我是第2行</h2>
</div>
</template>
<template id="temp2">
<div>
<h1>temp2我是第一行内容</h1><br>
<h2>temp2我是第2行</h2>
</div>
</template>
<script>
//Vue.component(componentname,options)
Vue.component('runoob', {
template: '#temp1'
})
Vue.component('runoob2', {
template: '#temp2'
})
var vue1 = new Vue({
el: '#app',
data:{activeobj:'runoob2'}
})
</script>
</body>
</html>
网友评论