在 Vue 3 中,ref 是用于创建 响应式引用 的一种方法。ref 主要用于处理 原始数据类型(如字符串、数字、布尔值等)或 DOM 元素 的响应式状态。
基本用法
1. 创建响应式引用
使用 ref 可以创建一个响应式引用,它会将传入的值变成响应式对象。我们可以通过 .value 来访问或修改它的值。
import { ref } from 'vue';
const count = ref(0); // 创建一个响应式变量 count
count.value++; // 修改响应式变量的值
console.log(count.value); // 输出修改后的值:1
在模板中直接使用 count,Vue 会自动解包 .value。
<template>
<div>{{ count }}</div> <!-- 不需要 .value -->
</template>
2. 访问和修改 ref 的值
ref 创建的变量本质上是一个对象,实际的值保存在 .value 属性中。要访问或修改其值,必须通过 .value。
const message = ref("Hello World");
console.log(message.value); // 输出: Hello World message.value = "Hello Vue"; // 修改值 console.log(message.value); // 输出: Hello Vue
在模板中直接使用 `message`,Vue 会自动处理 `.value`。
html 复制代码 ```
3. 与 watch 一起使用
ref 通常与 watch 一起使用来观察某个响应式变量的变化。当 ref 的值发生变化时,watch 会被触发。
import { ref, watch } from 'vue';
const message = ref("Hello");
watch(message, (newVal, oldVal) => {
console.log(`Message changed from "${oldVal}" to "${newVal}"`);
});
message.value = "Hello Vue"; // 触发 watch,输出变化
4. ref 与 reactive 的区别
ref用于处理单个数据值(如数字、字符串、布尔值等原始数据类型)以及 DOM 元素。reactive用于处理 对象 或 数组,并且返回的是代理对象(proxy)。
import { reactive, ref } from 'vue';
const state = reactive({
count: 0,
message: "Hello Vue"
});
const count = ref(0); // 使用 ref 创建原始数据响应式变量
const message = reactive({ text: "Hello Vue" }); // 使用 reactive 创建对象响应式变量
5. ref 和 DOM 元素的结合
ref 也可以用来引用 DOM 元素,允许你直接操作 DOM 元素。在模板中使用 ref 来标记元素,然后在脚本中通过 ref 引用它。
<template>
<div ref="myDiv">Hello, Vue!</div>
<button @click="changeText">Change Text</button>
</template>
<script setup>
import { ref } from 'vue';
const myDiv = ref(null); // 创建一个引用
const changeText = () => {
myDiv.value.textContent = "Text changed!";
};
</script>
6. ref 和 v-model 结合使用
Vue 3 中的 v-model 可以与 ref 一起使用,通常用于父子组件的双向绑定。
在父组件中:
<template>
<ChildComponent v-model="parentMessage" />
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const parentMessage = ref("Hello from parent");
</script>
在子组件中:
<template>
<input v-model="message" />
</template>
<script setup>
import { ref, defineProps, defineEmits } from 'vue';
const { modelValue } = defineProps(['modelValue']);
const emit = defineEmits(['update:modelValue']);
const message = ref(modelValue);
watch(message, (newValue) => {
emit('update:modelValue', newValue);
});
</script>
7. ref 与计算属性结合使用
你也可以将 ref 与计算属性一起使用,这样可以在 ref 值改变时动态地计算结果。
import { ref, computed } from 'vue';
const count = ref(0);
const doubledCount = computed(() => count.value * 2);
console.log(doubledCount.value); // 输出: 0
count.value = 5;
console.log(doubledCount.value); // 输出: 10
8.接下来展示一个小例子和运行结果
<script setup>
import { ref, watch } from "vue";
const message = ref("dd")
const change = () => {
message.value = "dd超帅"
}
watch(message,(newVal,oldVal)=>{
console.log(`新值为: ${newVal},旧值为:${oldVal}`);
})
const user=ref({
name:"kk"
})
watch(()=>user.value.name,(newVal,oldVal)=>{
console.log(`新值为: ${newVal},旧值为:${oldVal}`);
})
const changeUser=()=>{
user.value.name='jjj'
}
</script>
<template>
{{ message }}
<button @click="change">改变基本元素</button>
<button @click="changeUser">改变对象</button>
</template>
点击后: