上篇文章: 【Vue】Vue3.0 (十二)、watchEffect 和watch的区别及使用
🏡作者主页:点击!
🤖Vue专栏:点击!
⏰️创作时间:2024年10月18日20点56分
标签属性ref(加在普通标签上、加在组件标签上)有什么区别
在Vue 3.0中,ref
是一个用于创建响应式数据的函数,它可以用来在组件中引用DOM元素或子组件实例。以下是关于ref
的详细介绍:
作用:用于注册模板引用。
用在普通
DOM
标签上,获取的是DOM
节点。用在组件标签上,获取的是组件实例对象。
基本用法
- 在Vue 3.0中,使用
ref
函数来创建一个响应式的引用。例如:
<template>
<div ref="myDiv">这是一个 div 元素</div>
</template>
<script setup>
import { ref } from 'vue';
const myDiv = ref();
</script>
在上述代码中,使用ref
函数创建了一个名为myDiv
的响应式引用,并将其初始值设置为null
。在模板中,通过ref
指令将myDiv
引用与div
元素绑定。这样,在组件挂载后,myDiv
的值将指向该div
元素的实例。
访问DOM元素
- 可以通过
ref
引用访问DOM元素的属性和方法。例如:
<template>
<div ref="myDiv">这是一个 div 元素</div>
<button @click="changeText">改变文本</button>
</template>
<script setup>
import { ref } from 'vue';
const myDiv = ref();
const changeText = () => {
myDiv.value.textContent = '这是改变后的文本';
};
</script>
在上述代码中,定义了一个名为changeText
的方法,在该方法中,通过myDiv.value
访问div
元素的textContent
属性,并将其值修改为'这是改变后的文本'
。当点击按钮时,div
元素的文本内容将被改变。
访问子组件实例
ref
还可以用于访问子组件实例,以便在父组件中调用子组件的方法或访问子组件的数据。例如:
// 子组件
<template>
<div>
<p>{{ message }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue';
const message = ref('这是子组件的消息');
const changeMessage = () => {
message.value = '这是改变后的消息';
};
defineExpose({
changeMessage,
});
</script>
// 父组件
<template>
<div>
<ChildComponent ref="child" />
<button @click="callChildMethod">调用子组件方法</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const child = ref(null);
const callChildMethod = () => {
child.value.changeMessage();
};
</script>
在上述代码中,在子组件中定义了一个名为message
的响应式数据,并定义了一个名为changeMessage
的方法,用于改变message
的值。通过defineExpose
函数将changeMessage
方法暴露给父组件。在父组件中,使用ref
引用获取子组件实例,并在callChildMethod
方法中调用子组件的changeMessage
方法。
注意事项
ref
的值是一个响应式对象,需要通过.value
来访问其实际的值。- 在模板中使用
ref
时,需要确保ref
引用的元素或组件已经挂载,否则ref
的值将为null
。 ref
引用在组件的整个生命周期内都是有效的,可以在组件的任何方法中使用。- 当使用
ref
引用一个组件时,需要确保该组件已经被正确注册。
ref
是Vue 3.0中一个非常有用的特性,它使得在组件中访问DOM元素和子组件实例变得更加方便和灵活。通过ref
,可以轻松地实现对DOM元素的操作和对子组件的交互,从而增强了组件的复用性和可维护性。
举个栗子~
App.vue:
<template>
<h4 class="person" ref="title2">app的H3标签</h4>
<button @click="showTel">点我输出app的h3</button>
<button @click="showRen">点我输出Person标签</button>
<Person ref="ren"/>
</template>
<script lang="ts" setup name="App"> //当前根组件的组件名
import Person from './components/Person.vue'
import {ref} from 'vue'
let title2 =ref();
let ren =ref();
function showTel(){
console.log(title2.value);
}
function showRen(){
console.log(ren.value);
console.log(ren.value.b);
}
</script>
<style >
.app {
background-color: #ddd;
box-shadow: 0 0 10px;
border-radius: 10px;
padding: 20px;
}
</style>
Person.vue
<template>
<div class="person">
<h4 ref="title2">北京</h4>
<h4>尚硅谷</h4>
<button @click="showH3">点我展示H3标签</button>
</div>
</template>
<script lang="ts" setup name="Person">
import { ref, watch,defineExpose } from 'vue'
//数据
let title2 =ref();
let a =ref(0);
let b =ref(1);
let c =ref(2);
function showH3(){
console.log(title2.value);
}
//定义要让父对象能看到的东西 ,注意这个里面要传入一个对象,对象中可以放键值对,这些键值对就是可以让父亲看到的属性
defineExpose({a:a,b:b,c:c});
</script>
<style scoped>
.person {
background-color: skyblue;
box-shadow: 0 0 10px;
border-radius: 10px;
padding: 20px;
}
li {
font: 1em sans-serif;
}
</style>
结果1:
验证1:对于ref标记不会像id属性那样,多个组件之间会互相影响;ref标记及时一样,在一起使用的组件中,那也不会影响,是相互隔离的;
我点击了分别点击了app 和Person中的按钮,分别进行了输出,没有影响
验证2:app中能访问Person中暴露的方法和属性,这样在实际开发中,可以父组件去使用子组件的属性或者方法;
补充知识:局部样式:
一般写样式的时候,会加上scoped属性,这样就保证了这个选择器写的样式只在当前vue中生效,避免了影响其他的组件中同样选择器样式的展示