有时候我们需要父组件直接访问子组件(通过$children或$refs),子组件直接访问父组件($parent)。
$children(父访问子)
this.$children是一个对象数组类型,它包括所有子组件对象。通过该对象数组可以读或写子组件中的数据、调用子组件的方法。弊端是有多个子组件时通过对象数组下标访问子组件,无法适应子组件的数量发生变化的情况。
<body> <div id="app"> <cpn></cpn> <!-- 使用单标签此处出问题,在CLI里面不存在该问题 --> <!-- <cpn /> --> <button type="button" @click="btnClick">按钮</button> </div> <template id="cpn"> <div> 我是子组件---{{name}} </div> </template> <script src="vue/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> const app=new Vue({ el:'#app', data:{ message:'wangdou' }, methods:{ btnClick(){ this.$children[0].name='linda' } }, components:{ cpn:{ template:'#cpn', data(){ return { name:'我是子组件中的变量' } }, methods:{ showMessage(){ console.log('showMessage') } } } } }) </script> </body>
$refs(父访问子)
$refs为对象。其中key为子组件ref的属性值、value为子组件对象。通过该$refs对象可以读或写子组件中的数据、调用子组件的方法。
1.在子组件标签中添加 ref属性
2.在父组件中通过this.$refs.key访问子组件。
<body> <div id="app"> <cpn></cpn> <cpn ref="com"></cpn> <cpn></cpn> <!-- 使用单标签此处出问题,在CLI里面不存在该问题 --> <!-- <cpn /> --> <button type="button" @click="btnClick">按钮</button> </div> <template id="cpn"> <div> 我是子组件---{{name}} </div> </template> <script src="vue/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> const app=new Vue({ el:'#app', data:{ message:'wangdou' }, methods:{ btnClick(){ this.$refs.com.name='abc' } }, components:{ cpn:{ template:'#cpn', data(){ return { name:'我是子组件中的变量' } }, methods:{ showMessage(){ console.log('showMessage') } } } } }) </script> </body>
$parent(子访问父)
在子组件中通过this.$parent访问父级对象。它也可以更改父对象中的数据,调用父对象中的方法。还有this.$root访问Vue实例。
例如我写的表单验证:当从子组件中要验证父组件中的属性是否符合规则时
submitForm(formName) { // console.log('this.name', this.$parent.$refs['ruleForm']) let flag = true this.$parent.$refs['ruleForm'].validate((valid) => { flag = valid }) if (!flag) { this.open3() return flag } // console.log(flag) // return this.$refs['ruleForm1'].validate((valid) => { if (valid) { // alert('submit!') console.log(this.ruleForm1) } else { // alert('请填写正确的表单格式') console.log('error submit!!') flag = valid // return false } }) this.$refs['ruleForm'].validate((valid) => { flag = valid if (valid) { console.log(this.ruleForm) } else { console.log('error submit!!') return false } }) return flag },
<body> <div id="app"> <cpn></cpn> {{message}} </div> <template id="cpn"> <div> 我是子组件 <button type="button" @click="btnClick">按钮</button> </div> </template> <script src="vue/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> const app=new Vue({ el:'#app', data:{ message:'linda' }, components:{ cpn:{ template:'#cpn', data(){ return { name:'hello' } }, methods:{ btnClick(){ this.$parent.message='world' } } } } }) </script> </body>