我一直感觉搞懂父子组件互相调用方法和传值,你就会vue,用了这么久还不会,最近就需求需要刚刚学会了几种方法
[doc]
方案一:通过ref直接调用子组件的方法;
父组件中
<template>
<div>
<Button @click="handleClick">点击调用子组件方法</Button>
<Child ref="child"/>
</div>
</template>
<script>
import Child from './child';
export default {
methods: {
handleClick() {
this.$refs.child.sing('111');
// 如果有显示隐藏页面时候就使用nextTick
/**
this.$nextTick(() => {
this.$refs.basLocationChildRef.getLocationById(row.id)
})
*/
},
},
}
</script>
子组件
<template>
<div>我是子组件</div>
</template>
<script>
export default {
methods: {
// ret 是父组件带来的参数
sing(ret) {
console.log('我是子组件的方法'+ret);
},
},
};
</script>
方案二:emit调用子组件的方法;
首先我们要了解emit
vm.emit触发。回调函数会接收所有传入事件触发函数的额外参数。
vm.$emit( event, […args] ):触发当前实例上的事件。附加参数都会传给监听器回调。
父组件
<template>
<div>
<div @click="click">点击父组件</div>
<child ref="child"></child>
</div>
</template>
<script>
import child from "./child";
export default {
methods: {
click() {
this.$refs.child.$emit('childMethod','发送给方法一的数据') // 方法1:触发监听事件
this.$refs.child.callMethod() // 方法2:直接调用
},
},
components: {
child,
}
}
</script>
子组件
<template>
<div>子组件</div>
</template>
<script>
export default {
mounted() {
this.monitoring() // 注册监听事件
},
methods: {
monitoring() { // 监听事件
this.$on('childMethod', (res) => {
console.log('方法1:触发监听事件监听成功')
console.log(res)
})
},
callMethod() {
console.log('方法2:直接调用调用成功')
},
}
}
</script>
方案三:父组件传递数据给子组件
父组件:
<parent>
<child :child-msg="msg"></child> //这里必须要用 - 代替驼峰
</parent>
data(){
return {
msg: [1,2,3]
};
}
子组件通过props来接收数据:
方式1:
props: ['childMsg']
方式2:
props: {
childMsg: Array //这样可以指定传入的类型,如果类型不对,会警告
}
方式3:
props: {
childMsg: {
type: Array, //传入的类型
default: [0,0,0] //这样可以指定默认的值
}
}
props参数
props除了数组,也可以是一个对象,此时对象的键对应的props的名称,值又是一个对象,可以包含如下属性
- type: ;类型,可以设置为:String、Number、Boolean、Array、Object、Date等等 ;如果只设置type而未设置其他选项,则值可以直接用类型,例如:props:
- default ;默认值
- required ;布尔类型,表示是否必填项目
- validator ;自定义验证函数
方案四:子组件与父组件通信
子组件:
<template>
<div @click="testClick"></div>
</template>
methods: {
testClick() {
this.$emit('test','123'); //$emit(even,value)even 是一个函数,value 是传给父组件的值 , 触发名为test方法, '123'为向父组件传递的数据
}
}
父组件接收:
<div>
//监听子组件触发的test事件,然后调用change方法
<child @test="change" :msg="msg"></child>
</div>
methods: {
change(val) {
this.msg = val; // val: 123
}
}
方案五:非父子组件通信1
如果2个组件不是父子组件那么如何通信呢?这时可以通过eventHub来实现通信.
所谓eventHub就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件.
let Hub = new Vue(); //创建事件中心
组件1触发
<div @click="eve"></div>
methods: {
eve() {
Hub.$emit('change','hehe'); //Hub触发事件
}
}
组件2接收:
<div></div>
created() {
Hub.$on('change', () => { //Hub接收事件
this.msg = 'hehe';
});
}
方案六:非父子组件通信2
父组件
<template>
<div>
<div v-if="!userShow">
父组件内容区
<el-button @click="lookUserInfo(scope.row)"> 查看</el-button>
</div>
<!-- 子组件 -->
<user-manager v-if="userShow" @close="showUserInfo" ref="child"> </user-manager>
</div>
</template>
<script>
//导入用户页面
import userManager from '../userManager.vue';
export default {
name:'taskManager',
components:{userManager},
data() {
return {
userShow:false,
}
},
methods: {
//显示子组件,隐藏父组件
lookUserInfo(row) {
this.userShow = true;
this.$refs.child.chlidMethods
},
//此方法,子组件会调用,调用返回父页面:隐藏子组件,显示父组件
showUserInfo() {
this.userShow = false;
},
}
}
</script>
子组件
<template>
<div>
<!-- 返回父页面按钮 -->
<div>
<el-button @click="goToParent"> 返回</el-button>
</div>
<div class="white-bg margin auto">
<el-table>
数据表格展示区
</el-table>
</div>
</div>
</template>
<script>
export default {
name:'userManager',
data() {
return {
}
},
methods: {
goToParent() {
//调父页面方法
this.$emit('close');
}
chlidMethods() {
console.log("父组件调子组件方法了")
}
}
}
</script>
七、其他父子案例
- 步骤一、父页面子标签写一个属性
- 步骤二、数据这边定义一个假如随时改变的值
data() {
return {
activeName: 'second',
param: 'DB2',
myParm: 'MySQl'
}
},
- 步骤三、这边就是父标签的随意改变的值
handleClick(tab, event) {
if (tab.name === '0') {
this.param = 'DB2'
} else if (tab.name === '1') {
this.param = 'MySQL'
} else if (tab.name === '2') {
this.param = 'SQL SERVER'
} else if (tab.name === '3') {
this.param = 'DB1'
}
console.log('点击事件-->' + this.param)
}
子页面
- 动态取值,使用 watch:{} 函数
watch: {
param: {
handler(newValue, oldValue) {
this.param = newValue
console.log('ServerBtn页面' + '新值' + newValue + '老值' + oldValue + 'param' + this.param)
this.initBtn()
},
deep: true
}
},
- 子组件取值,使用 props 来取
// 接收父组件值
props: {
param: {
type: String,
default: 'MySQL'
}
},
十、父组件给子组件的子组件操作
- 父组件
<NodeAccessTable ref="nodeAccessTable" />
<el-button v-if="hasPermission"
size="mini" @click="$refs.nodeAccessTable.$refs.allPro.show = true" >
<svg-icon class="drag-handler" icon-class="zongbian" />
设置
</el-button>
- 子组件
<all-project-no-set-modal ref="allPro" :category-arr="categoryArr" :category-id="categoryId" />
- 子组件中子组件
<el-dialog
v-el-drag-dialog
class="dialogBox"
:close-on-click-modal="false"
:title="!operate ? '设置'
:visible.sync="show"
width="60%"
:before-close="closeDialog"
>
</el-dialog>
九、子组件接收值类型
String 字符串
Number 数字
Boolean 判断
Array 数组
Object 对象