Computed与watch

1.计算属性computed

1.1介绍

用途:使用属性不存在,需要通过已有属性获得(get和set)

简单情况:

let sum = computed(()=>{
    return price.value*num.value
})

基础情况:

let nickname = ref("")
let setNickName = computed({
    get(){
        return nickname.value;
    },
    set(val:string){
        nickname.value=val;
    }
})

常用情况:由于v-if优先级高于v-for 而且二者不能同时使用。需要循环数组并在其中做筛选来显示的情况时,用computed

<div v-for="item in List" :key="item.id">
    {{item.id}}-{{item.name}}
</div>
let List = [
    {id:1,name="项目一"},
    {id:2,name="项目二"}
]
let listComputed = computed(()=>{
    let items = List.filter((val)=>{
        return val.id>1;
    })
    return items;
})

1.2 练习 :动态切换主题

目标:实现一个简单的切换按钮,允许用户在“浅色”和“深色”主题之间切换。

要求:

  1. 浅色和深色主题:当点击按钮时,页面的背景颜色和文本颜色会切换。浅色主题背景为白色,文本为黑色;深色主题背景为黑色,文本为白色。
  2. 使用 computed 来动态计算和应用主题的颜色。
  3. 点击按钮时能够切换主题。

代码:

Copy Code<template>
  <div :style="themeStyle">
    <button @click="toggleTheme">切换主题</button>
    <p>当前主题是:{{ theme === 'light' ? '浅色' : '深色' }}</p>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';

// 响应式的主题状态
const theme = ref('light'); // 默认为浅色主题

// 计算动态的主题样式
const themeStyle = computed(() => {
  if (theme.value === 'light') {
    return {
      backgroundColor: 'white',
      color: 'black'
    };
  } else {
    return {
      backgroundColor: 'black',
      color: 'white'
    };
  }
});

// 切换主题
const toggleTheme = () => {
  theme.value = theme.value === 'light' ? 'dark' : 'light';
};
</script>

2.监视属性watch

2.1介绍

适用:所监视属性必须存在

简单情况:

  // 创建一个响应式的 message 变量
    const message = ref('');

    // 使用 watch 监听 message 的变化
    watch(message, (newValue, oldValue) => {
      console.log(`message 发生变化: 从 "${oldValue}" 变为 "${newValue}"`);
    });

基础情况:

   // 创建两个响应式的变量 firstName 和 lastName
    const firstName = ref('');
    const lastName = ref('');

    // 计算全名
    const fullName = computed(() => `${firstName.value} ${lastName.value}`);

    // 使用 watch 分别监听 firstName 和 lastName 的变化
    watch([firstName, lastName], ([newFirstName, newLastName], [oldFirstName, oldLastName]) => {
      console.log(`名字发生变化: 从 "${oldFirstName}" 变为 "${newFirstName}"`);
      console.log(`姓氏发生变化: 从 "${oldLastName}" 变为 "${newLastName}"`);
    });

深度监听:

 // 创建一个响应式对象 user
    const user = reactive({
      name: '',
      age: 0,
    });

    // 使用 watch 监听整个对象的变化,开启深度监听
    watch(user, (newValue, oldValue) => {
      for (const key in newValue) {
        if (newValue[key] !== oldValue[key]) {
          console.log(`${key} 属性发生变化: 从 "${oldValue[key]}" 变为 "${newValue[key]}"`);
        }
      }
    }, { deep: true });

用途:

  • 用于防抖,防抖的目的是为了在用户停止输入后延迟一段时间再执行某个操作,这样可以避免在用户输入过程中频繁地触发操作(比如发起网络请求),提高性能并减少不必要的请求。
  • 监听路由变化

2.2练习:延迟处理输入变化

目标: 在用户输入时延迟处理输入变化,防止频繁执行操作。

要求:使用 watch 监听 query 的变化,使用 setTimeout 模拟防抖效果,只有在用户停止输入一段时间后,才执行某个操作(如打印搜索内容)。

一般用到计时器延时,都要写一个清除延时的一起使用。

<template>
  <div>
    <input v-model="query" placeholder="请输入搜索内容" />
    <p>当前搜索内容: {{ query }}</p>
  </div>
</template>

<script>
import { ref, watch } from 'vue';

export default {
  name: 'SearchWatcher',
  setup() {
    // 创建一个响应式的 query 变量
    const query = ref('');

    // 使用 watch 监听 query 的变化,模拟防抖效果
    let timeout;
    watch(query, (newQuery) => {
      // 清除上一个延时
      clearTimeout(timeout);

      // 设置新的延时
      timeout = setTimeout(() => {
        console.log(`搜索内容: ${newQuery}`);
      }, 500); // 设置 500ms 的防抖延迟

    });

    return {
      query,
    };
  },
};
</script>

3.条件渲染 v-if ,v-show

3.1 介绍

v-if适用于:切换频率较低的场景,不展示的DOM元素直接被移除

v-show适用于:切换频率较高的场景,不展示的DOM元素未被移除,仅仅是使用样式隐藏掉

v-if优先级高于v-show

3.2 练习

练习 :切换用户信息

场景描述:你需要根据用户是否登录来决定是否显示用户的个人信息。如果用户未登录,则不显示用户信息区域;如果已登录,则显示。

问题:你应该使用 v-if 还是 v-show 来控制显示用户信息?

思考方向:当用户未登录时,用户信息区域应该完全从 DOM 中移除,而不是仅仅隐藏。只有在用户登录时才需要渲染该区域。


练习 :用户输入验证提示

场景描述:在一个表单中,当用户输入不合法的内容时,你需要显示一条错误提示消息。错误提示应该在输入正确后消失。

问题:你应该使用 v-if 还是 v-show 来控制错误提示的显示?

思考方向:提示信息的显示与隐藏依赖于用户的输入。是否需要每次显示错误信息时重新渲染?还是可以通过切换 CSS 的方式控制?


练习答案解析:

  1. 练习 :使用 v-if。因为用户信息区域在未登录时不应该存在于 DOM 中,所以需要使用 v-if 来控制渲染与销毁。
  2. 练习 :使用 v-show。错误提示信息仅需要显示和隐藏,而不需要频繁重新渲染。v-show 更适合这种场景。

在 Vue 中,v-cloak 是一个指令,用于保留某个元素及其子元素在 Vue 实例完成编译之前的“未编译”状态。通常,这个指令与 Vue 的模板预编译机制配合使用,确保在 Vue 实例初始化时,元素不会被错误地渲染或显示,直到 Vue 完成模板的解析和数据绑定。

4. 延迟渲染 v-cloak

4.1介绍

v-cloak 主要用于解决页面加载时 Vue 模板编译延迟的问题,在 Vue 实例初始化完成之前,HTML 模板的内容k可能会被直接渲染在页面上,如 {{ message }})被渲染出来

基本用法:在 HTML 元素上使用 v-cloak:将 v-cloak 添加到你希望被延迟渲染的元素上,直到 Vue 实例完成编译。

  <style>
    [v-cloak] {
      display: none;
    }
  </style>
  <div id="app" v-cloak>
    <p>{{ message }}</p>

  </div>

解释:

  1. CSS:通常,v-cloak 会配合 CSS 使用,来设置在 Vue 完成实例初始化之前,绑定了 v-cloak 的元素不可见。你可以通过 display: none; 来隐藏这些元素。
  2. 在 Vue 实例挂载后:当 Vue 实例挂载并完成模板编译时,带有 v-cloak 的元素将会被渲染出来,v-cloak 会被移除。
  • 只用于开发模式v-cloak 主要是为了开发时避免 Vue 的渲染闪烁问题,因此它通常不需要在生产环境中使用。在 Vue 的生产环境中,v-cloak 依然会生效,但它的作用已经不再是防止模板闪烁,而是作为一种保持兼容性的标记。Vue 在生产模式下会自动移除 v-cloak 属性,确保它不会影响最终的渲染结果。

5.静态内容 v-once,v-pre

5.1介绍

	<div id="root">
			<h2 v-once>n初始化的值是:{{n}}</h2>
            <h2>n现在的值是:{{n}}</h2>
            <button @click="n++">点我n+1</button>
		</div>
  1. v-once所在节点在初次动态渲染后,就视为静态内容了
  2. 以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能
	<div id="root">
			<h2 v-pre>Vue其实很简单</h2>
			<h2>当前的n值是:{{n}}</h2>
			<button @click="n++">点我n+1</button>
		</div>

v-pre指令:

  1. 跳过其所在节点的编译过程。
  2. 可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值