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 练习 :动态切换主题
目标:实现一个简单的切换按钮,允许用户在“浅色”和“深色”主题之间切换。
要求:
- 浅色和深色主题:当点击按钮时,页面的背景颜色和文本颜色会切换。浅色主题背景为白色,文本为黑色;深色主题背景为黑色,文本为白色。
- 使用
computed
来动态计算和应用主题的颜色。 - 点击按钮时能够切换主题。
代码:
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 的方式控制?
练习答案解析:
- 练习 :使用
v-if
。因为用户信息区域在未登录时不应该存在于 DOM 中,所以需要使用v-if
来控制渲染与销毁。 - 练习 :使用
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>
解释:
- CSS:通常,
v-cloak
会配合 CSS 使用,来设置在 Vue 完成实例初始化之前,绑定了v-cloak
的元素不可见。你可以通过display: none;
来隐藏这些元素。 - 在 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>
v-once
所在节点在初次动态渲染后,就视为静态内容了- 以后数据的改变不会引起
v-once
所在结构的更新,可以用于优化性能
<div id="root">
<h2 v-pre>Vue其实很简单</h2>
<h2>当前的n值是:{{n}}</h2>
<button @click="n++">点我n+1</button>
</div>
v-pre
指令:
- 跳过其所在节点的编译过程。
- 可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译