响应式状态
<script setup> import { ref, reactive, computed, watch, watchEffect } from "vue"; //reactive 响应式对象 只能用于对象、数组和集合类型 const author = reactive({ name: "John Doe", books: ["Vue 2 - Advanced Guide", "Vue 3 - Basic Guide", "Vue 4 - The Mystery"], }); //计算属性 值会基于其响应式依赖被缓存。计算属性仅会在其响应式依赖更新时才重新计算。 const publishedBooksMessage = computed(() => { return author.books.length > 0 ? "Yes" : "No"; }); // 声明响应式状态 const firstName = ref("John"); const lastName = ref("Doe"); const fullName = computed({ get() { return firstName.value + " " + lastName.value; }, set(newValue) { [firstName.value, lastName.value] = newValue.split(" "); // 解构赋值语法 }, }); const fullname_text = ref(null); const fullname_num_text = ref(null); const num = ref(5); // 侦听器 使用 watch 函数在每次响应式状态发生变化时触发回调函数 // 可以直接侦听一个 ref watch(num, (newnum, oldnum) => { if (newnum > 30) { num.value = 0; } }); // getter 函数 watch( () => firstName.value + " " + lastName.value, (full_name) => { fullname_text.value.textContent = `Full name is: ${full_name}`; } ); // 多个来源组成的数组 watch([num, () => firstName.value + " " + lastName.value], ([newnum, full_name]) => { fullname_num_text.value.textContent = `Full name is: ${full_name},num is:${newnum}`; }); const todoId = ref(1); const todoData = ref(null); // watchEffect 自动跟踪回调的响应式依赖。 watchEffect(async () => { const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${todoId.value}`); todoData.value = await response.json(); }); </script> <template> <div> <!-- 计算属性 --> <div> <p> Has published books:<span>{{ publishedBooksMessage }}</span> </p> </div> <div> <p>num: <input v-model.number="num" /></p> <p>名:<input v-model.trim="firstName" />姓:<input v-model.trim="lastName" /></p> <p>姓名:<input v-model.trim="fullName" /></p> <p ref="fullname_text">Full name is: {{ fullName }}</p> <p ref="fullname_num_text">Full name is: {{ fullName }} , num is: {{ num }}</p> </div> <!-- 侦听器 --> <div> <p>Todo id: {{ todoId }}</p> <button @click="todoId++">Fetch next todo</button> <p v-if="!todoData">Loading...</p> <pre v-else>{{ todoData }}</pre> </div> </div> </template> <style scoped> </style>