Vue
刀刀
3/20/2025
0 字
0 分钟
动态样式
动态 class
作用:通过
v-bind
给标签class
设置动态的值,即把类名保存在vue变量中赋予给标签。
语法: :class="{类名 : 布尔值}"
判断后面的布尔值,如果为真则添加样式类名,否则移除。需要用大括号包括起来。
<template>
<div>
<!-- 语法:
:class="{类名: 布尔值}"
使用场景: vue变量控制标签是否应该有类名
-->
<p :class="{red_str: bool}">动态class</p>
</div>
</template>
<script>
export default {
data(){
return {
bool: true
}
}
}
</script>
<style scoped>
.red_str{
color: red;
}
</style>
复制代码
绑定的数据对象不必内联到模板内,也可写在 data
中。
<div v-bind:class="classObject"></div>
data: {
classObject: {
active: true,
show: false
}
}
数组的形式:
<div v-bind:class="[active, show, {isHas: true}]"></div>
data() {
return: {
active: 'active',
show: 'show'
}
}
动态 style
作用:> 给标签动态设置
style
的值,动态style
的key
都是css
属性名。
语法: :style="{css属性名 : 值}"
<template>
<div>
<!-- 动态style语法
:style="{css属性名: 值}"
-->
<p :style="{backgroundColor: colorStr}">动态style</p>
</div>
</template>
<script>
export default {
data(){
return {
colorStr: 'red'
}
}
}
</script>
<style>
</style>
复制代码
过滤器
过滤器定义与使用
作用:转换格式,
过滤器本质就是一个函数, 必须定义到 filters
节点之下,传入值返回处理后的值。必须要有一个返回值。
过滤器只能用在, *插值表达式和 v-bind
表达式*。
语法:
全局过滤器:
Vue.filter("过滤器名", (值) => {return "返回处理后的值"})
全局过滤器需要先拿到
vue
对象再调用方法。全局过滤器只能定义一次。
html<template> <div> <!-- 全局filter --> <p>{{ msg | firstUp }}</p> </template> <script> // 全局定义 // 需要先拿到vue对象 import Vue from "vue"; // 再调用filter方法定义: 注意只定义一个,所以filter没加s // 函数这里缩写了两个地方: 1.箭头函数 2. 直接返回值 Vue.filter("firstUp", (msg) => msg[0].toUpperCase() + msg.slice(1)); export default { data() { return { msg: "hello world", }; }, }; </script> 复制代码
局部过滤器:
filters: {过滤器名字: (值) => {return "返回处理后的值"}
html<template> <div> <p>{{ msg | reverse }}</p> <p :title="msg | toUp">我</p> </div> </template> <script> export default { data() { return { msg: "hello world", }; }, filters: { reverse(msg) { return msg.split("").reverse().join(""); }, toUp(msg) { return msg.toUpperCase(); }, }, }; </script> 复制代码
为过滤器传参
过滤器传参: vue变量 | 过滤器(实参)
复制代码
<template>
<div>
<!-- 为过滤器传参 -->
<p>{{ msg | reverse(foo) }}</p>
</div>
</template>
<script>
export default {
data() {
return {
msg: "hello world",
foo: 222,
};
},
filters: {
reverse(msg, foo) {
console.log(msg, foo);
return msg.split("").reverse().join("");
},
},
};
</script>
复制代码
多个过滤器使用
多个过滤器: vue变量 | 过滤器1 | 过滤器2
复制代码
<template>
<div>
<!-- 多个过滤器 -->
<p>{{ msg | firstUp | reverse(foo) }}</p>
</div>
</template>
<script>
// 全局定义
// 需要先拿到vue对象
import Vue from "vue";
// 再调用filter方法定义: 注意只定义一个,所以filter没加s
// 函数这里缩写了两个地方: 1.箭头函数 2. 直接返回值
Vue.filter("firstUp", (msg) => msg[0].toUpperCase() + msg.slice(1));
export default {
data() {
return {
msg: "hello world",
foo: 222,
};
},
filters: {
reverse(msg, foo) {
console.log(msg, foo);
return msg.split("").reverse().join("");
},
},
};
</script>
复制代码
计算属性
作用:让一个数据, 依赖另外一些数据计算而来的结果,本质上是一个函数。
语法:
计算属性内定义成函数,函数要有 return
返回值,函数名则作为方法名来使用。
computed: {
"计算属性名" () {
return "值"
}
}
复制代码
计算属性必须定义在 computed
之下,必须定义声明成方法格式。
注意点:
- 计算属性也是vue数据变量, 所以不要和data里重名, 用法和data相同。
- 函数内变量变化, 会自动重新计算结果返回。
- 计算属性具有缓存功能。
<template>
<div>
<p>{{ num }}</p>
</div>
</template>
<script>
export default {
data(){
return {
a: 10,
b: 20
}
},
// 注意: 计算属性和data属性都是变量-不能重名
// 注意2: 函数内变量变化, 会自动重新计算结果返回
computed: {
num(){
return this.a + this.b
}
}
}
</script>
复制代码
缓存
作用:计算属性是基于它们的依赖项的值结果进行缓存的,只要依赖的变量不变, 都直接从缓存取结果。
<template>
<div>
<p>{{ reverseMessage }}</p>
<p>{{ reverseMessage }}</p>
<p>{{ reverseMessage }}</p>
<p>{{ getMessage() }}</p>
<p>{{ getMessage() }}</p>
<p>{{ getMessage() }}</p>
</div>
</template>
<script>
export default {
data(){
return {
msg: "Hello, Vue"
}
},
// 计算属性优势:
// 带缓存
// 计算属性对应函数执行后, 会把return值缓存起来
// 依赖项不变, 多次调用都是从缓存取值
// 依赖项值-变化, 函数会"自动"重新执行-并缓存新的值
computed: {
reverseMessage(){
console.log("计算属性执行了");
return this.msg.split("").reverse().join("")
}
},
methods: {
getMessage(){
console.log("函数执行了");
return this.msg.split("").reverse().join("")
}
}
}
</script>
复制代码
最终结果:执行了三个 getMessage()
函数,只执行了一次 reverseMessage()
函数。
完整写法
作用:可以用于直接赋值,一般给
v-model
使用。
例子:用户点击复选框修改复习框的状态。
但是此刻,我们的复选框是通过v-model将复选框的状态checked和计算属性isAll双向绑定,所有当用户点击复选框修改状态时,就会把isAll计算属性的值一起改了。此时计算属性是函数写法的话就会报错。
因为这是vue框架规定的。我们要用计算属性完整写法。
总结: 用户需要修改计算属性的值时才需要完整写法。
语法:
computed: {
"属性名": {
set(值){
},
get() {
return "值"
}
}
}
复制代码
<template>
<div>
<div>
<span>姓名:</span>
<input type="text" v-model="full">
</div>
</div>
</template>
<script>
export default {
computed: {
full: {
// 给full赋值触发set方法
set(val){
console.log(val)
},
// 使用full的值触发get方法
get(){
return "无名氏"
}
}
}
}
</script>
复制代码
侦听器
作用:可以侦听
data/computed
属性值改变。
侦听器本质上是一个函数,谁要被侦听就把这个数据名当作方法名或函数名即可。
语法:
watch: {
"被侦听的属性名" (newVal, oldVal){
}
}
复制代码
- 第一个参数是修改后的新值。
- 第二个参数是以前的旧值。 例子:
<template>
<div>
<input type="text" v-model="name">
</div>
</template>
<script>
export default {
data(){
return {
name: ""
}
},
watch: {
// newVal: 当前最新值
// oldVal: 上一刻值
name(newVal, oldVal){
console.log(newVal, oldVal);
}
}
}
</script>
复制代码
方法格式的侦听方式的缺点:
- 无法一进入页面就立即侦听。
- 侦听对象时对象属性发生变化也不会触发侦听器。
深度侦听和立即执行
普通的侦听写法只能用于基础数据类型,侦听复杂数据类型只能侦听到它的地址。想要侦听它的属性值,需要用到深度侦听和完整写法。
语法:
watch: {
"要侦听的属性名": {
immediate: true, // 立即执行
deep: true, // 深度侦听复杂类型内变化
handler (newVal, oldVal) {
}
}
}
复制代码
完整例子代码:
<template>
<div>
<input type="text" v-model="user.name">
<input type="text" v-model="user.age">
</div>
</template>
<script>
export default {
data(){
return {
user: {
name: "",
age: 0
}
}
},
watch: {
user: {
handler(newVal, oldVal){
// user里的对象
console.log(newVal, oldVal);
},
deep: true,
immediate: true
}
}
}
</script>
复制代码
总结:
immediate
作用是页面初始化后立即侦听。deep
深度侦听。handler
固定方法,只要侦听到触发。