目录
1.父传子(父给子传参)
2.子传父(子调用父的方法)
3.父调用子的方法
4.顶层给底层传参,底层调用顶层的方法
5.模板引用
1.父传子(父给子传参)
①.步骤
父组件中给子组件通过绑定属性的方式传递往子组件的参数
子组件内部通过props选项进行接收
②.示例
父组件:
<script setup>
// 局部组件,导入之后就可以进行使用
import chlid from '@/components/child.vue'
import { ref } from 'vue';
const money = ref(50);
const add = () =>{money.value += 10;
}
</script><template><div><h3>父组件 {{ money }}<!-- 在父组件中改变了往子组件传递的值,子组件会接收到最新的值,并更新视图 --><button @click="add"> 挣钱</button></h3><!-- 给子组件,以添加属性的方式进行传递,可以传递固定值或者动态值--><chlid car = "BYD" :money = "money"></chlid></div>
</template>
子组件:
<template>
<!-- 在模板中可以直接使用参数,不需要通过prop.的方式 -->
<div class="son"> 子组件 {{ car }} - {{ money }}
<button>花钱</button>
</div>
</template><script setup>
const prop = defineProps({money:Number,car:String
})
const emit = defineEmits(['sub'])
// 在js中需要prop.的方式来使用参数
console.log(prop.car)</script>
<style scoped>
.son {border:1px solid #000;padding: 30px;
}
</style>
③.说明
在父组件中,导入子组件可以直接进行使用。
在父组件中,需要在子组件上以属性的方式进行参数传递,可以传递固定值或者动态值。
在父组件中,改变了给子组件传递的值,子组件会实时接收到最新的值,并更新视图。
在子组件中,通过defineProps来接收父组件传递的参数,参数id和父组件中子组件上的属性一致。
在子组件中,模板中可以直接使用参数,在js中要通过对象.属性的方式进行使用。
2.子传父(子调用父的方法)
①步骤
在父组件中给子组件标签通过@方式绑定自定义事件
在子组件通过defineEmits编译器宏生成emit方法
在子组件中触发自定义事件,并传递参数
②示例
父组件:
<script setup>
// 局部组件,导入之后就可以进行使用
import chlid from '@/components/child.vue'
import { ref } from 'vue';
const money = ref(50);
const add = () =>{money.value += 10;
}const subs = (val) =>{
money.value = val;
}
</script><template><div><h3>父组件 {{ money }}<!-- 在父组件中改变了往子组件传递的值,子组件会接收到最新的值,并更新视图 --><button @click="add"> 挣钱</button></h3><!-- 给子组件,以添加属性的方式进行传递,可以传递固定值或者动态值--><chlid car = "BYD" :money = "money" @sub="subs"></chlid></div>
</template>
子组件:
<template>
<!-- 在模板中可以直接使用参数,不需要通过prop.的方式 -->
<div class="son"> 子组件 {{ car }} - {{ money }}
<button @click="send">花钱</button>
</div>
</template><script setup>
const prop = defineProps({money:Number,car:String
})
const emit = defineEmits(['sub'])
// 在js中需要prop.的方式来使用参数
console.log(prop.car)const send = () =>{emit("sub",5);
}</script>
<style scoped>
.son {border:1px solid #000;padding: 30px;
}
</style>
③说明
父组件中的自定义事件名和子组件中defineEmits数组中的时间名和emit方法中的事件名,这三个事件名必须保持一致。
3.父调用子的方法
①步骤
默认情况下载<script setup>语法糖下组件内部的属性和方法时不开放给父组件访问的,
可以通过defineExpose编译宏指定哪些属性和方法允许访问。
②示例
父组件:
<script setup>
// 局部组件,导入之后就可以进行使用
import chlid from '@/components/child.vue'
import { ref } from 'vue';
const name = ref('xiaolin');
const updateName = () => {name.value = 'xiaoli';
}
const money = ref(50);
const add = () =>{money.value += 10;
}const subs = (val) =>{
money.value = val;
}// 定义子组件ref对象,调用子组件的方法及属性
const childRef = ref(null);
const gerChild = () =>{console.log(childRef.value);console.log(childRef.value.info);childRef.value.fun1('123');
}
</script><template><div><h3>父组件 {{ money }}<!-- 在父组件中改变了往子组件传递的值,子组件会接收到最新的值,并更新视图 --><button @click="add"> 挣钱</button></h3><!-- 给子组件,以添加属性的方式进行传递,可以传递固定值或者动态值--><chlid ref="childRef" car = "BYD" :money = "money" @sub="subs"></chlid><button @click="gerChild">获取子组件</button></div>
</template>
子组件:
<template>
<!-- 在模板中可以直接使用参数,不需要通过prop.的方式 -->
<div class="son"> 子组件 {{ car }} - {{ money }}
<button @click="send">花钱</button>
<input ref="inputRef"/>
</div>
</template><script setup>
import { ref,onMounted } from 'vue';
const prop = defineProps({money:Number,car:String
})
const emit = defineEmits(['sub'])
// 在js中需要prop.的方式来使用参数
console.log(prop.car)const send = () =>{emit("sub",5);
}
// 模板引用
// 1.通过调用ref函数生成一个ref对象
// 2.通过ref标识进行绑定
// 通过ref对象的.value属性就能获取到绑定元素或组件的方法及属性(必须渲染完成之后才能获取)
const inputRef = ref(null);
onMounted(()=>{console.log(inputRef.value);inputRef.value.focus();
})// 下面的属性和方法要想被父组件访问,需要defineExpose宏函数指定要访问的属性和方法
const info = 1234556;
const fun1 = (val) =>{console.log("调用到了子组件的方法",val);
}
defineExpose({info,fun1
})
</script>
<style scoped>
.son {border:1px solid #000;padding: 30px;
}
</style>
③说明
通过defineExpose显示暴露子组件内部的属性和方法。
在父组件中通过ref函数获取到子组件的实例,然后通过.value来调用子组件的属性及方法。
4.顶层给底层传参,底层调用顶层的方法
①步骤
顶层组件通过provide函数提供数据
底层组件通过inject函数获取数据
传递参数,一般传递响应式变量
传递方法,方法中可以接收参数
②示例
顶层组件
<script setup>
// 局部组件,导入之后就可以进行使用
import chlid from '@/components/child.vue'
import { provide, ref } from 'vue';
const name = ref('xiaolin');
const updateName = () => {name.value = 'xiaoli';
}
const money = ref(50);
const add = () =>{money.value += 10;
}const subs = (val) =>{
money.value = val;
}// 定义子组件ref对象,调用子组件的方法及属性
const childRef = ref(null);
const gerChild = () =>{console.log(childRef.value);console.log(childRef.value.info);childRef.value.fun1('123');
}
// 顶层组件给底层组件传递参数
// 在顶层组件通过provie向底层组件传递参数,数据是响应式的,在顶层组件中修改了传递给底层组件的参数,底层组件会接收到最新的值。
const title= ref("主题1");
provide("title",title);
const updateBottom = () =>{title.value = "主题修改了";
}
// 顶层组件给底层组件传递方法
provide('updateTitile', (newVal) =>{title.value = '主题修改为' + newVal;
})
</script><template><div><h1>父组件 {{ money }}<!-- 在父组件中改变了往子组件传递的值,子组件会接收到最新的值,并更新视图 --><button @click="add"> 挣钱</button></h1><!-- 给子组件,以添加属性的方式进行传递,可以传递固定值或者动态值--><chlid ref="childRef" car = "BYD" :money = "money" @sub="subs"></chlid><button @click="gerChild">获取子组件</button><!-- 修改向底层组件传递的内容 --><button @click="updateBottom"> 修改向底层组件传递的内容</button></div>
</template>
中间组件
<template>
<!-- 在模板中可以直接使用参数,不需要通过prop.的方式 -->
<div class="son"><h2>子组件 {{ car }} - {{ money }} </h2>
<button @click="send">花钱</button>
<input ref="inputRef"/>
<bottom></bottom>
</div></template><script setup>
import { ref,onMounted } from 'vue';
import bottom from './bottom.vue';
const prop = defineProps({money:Number,car:String
})
const emit = defineEmits(['sub'])
// 在js中需要prop.的方式来使用参数
console.log(prop.car)const send = () =>{emit("sub",5);
}
// 模板引用
// 1.通过调用ref函数生成一个ref对象
// 2.通过ref标识进行绑定
// 通过ref对象的.value属性就能获取到绑定元素或组件的方法及属性(必须渲染完成之后才能获取)
const inputRef = ref(null);
onMounted(()=>{console.log(inputRef.value);inputRef.value.focus();
})// 下面的属性和方法要想被父组件访问,需要defineExpose宏函数指定要访问的属性和方法
const info = 1234556;
const fun1 = (val) =>{console.log("调用到了子组件的方法",val);
}
defineExpose({info,fun1
})
</script>
<style scoped>
.son {border:1px solid #000;padding: 30px;
}
</style>
底层组件
<template>
<div> <h3>我是底层组件 - {{ title }}</h3><button @click="update">调用顶层组件的方法</button>
</div>
</template><script setup>
import { inject } from 'vue';// 底层组件通过inject接收顶层组件的参数
const title = inject('title');// 底层组件通过inject接收顶层组件的方法
const updateTitile = inject('updateTitile');const update = () =>{updateTitile('底层调用顶层');
}</script>
③说明
通过provide及inject实现顶层组件向任意的底层组件传递数据和方法,实现跨层组件通信。如果不使用这种方式,只能一级级组件进行通信,或者使用全局状态管理(如pinia)。
在顶层组件中通过provide提供响应式变量及方法,在底层组件中铜鼓inject可以进行调用。
5.模板引用
①步骤
调用ref函数生成一个ref对象。
通过ref标识绑定ref对象到标签中。
②示例
<template>
<!-- 在模板中可以直接使用参数,不需要通过prop.的方式 -->
<div class="son"> 子组件 {{ car }} - {{ money }}
<button @click="send">花钱</button>
<input ref="inputRef"/>
</div>
</template><script setup>
import { ref,onMounted } from 'vue';
const prop = defineProps({money:Number,car:String
})
const emit = defineEmits(['sub'])
// 在js中需要prop.的方式来使用参数
console.log(prop.car)const send = () =>{emit("sub",5);
}
// 模板引用
// 1.通过调用ref函数生成一个ref对象
// 2.通过ref标识进行绑定
// 通过ref对象的.value属性就能获取到绑定元素或组件的方法及属性(必须渲染完成之后才能获取)
const inputRef = ref(null);
onMounted(()=>{console.log(inputRef.value);inputRef.value.focus();
})const info = 1234556;
const fun1 = () =>{console.log("调用到了子组件的方法");
}
</script>
<style scoped>
.son {border:1px solid #000;padding: 30px;
}
</style>
上面示例实现了画面加载后焦点放在输入框上。
③说明
通过ref标识获取真实的dom对象或者组件对象实例,这就就通过dom对象或者组件实例来调用方法和属性。常见的示例如下:
获取form表单的dom对象,调用validate()进行校验处理。
获取imput输入框的dom对象,调用focus(),将焦点放在输入框上。
获取子组件的对象实例,调用子组件的方法或者获取子组件的属性。
注意:通过ref方式获取dom对象有一个前提,必须是页面渲染完成之后才能获取到,最早在onmounted中可以获取到。