vue3学习基础之响应式状态

发布时间 2023-12-26 15:23:30作者: carol2014
响应式状态

<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>