目录
一、计算属性与侦听
1.1 计算属性 - computed
1.1.1 定义
要用的属性不存在,要通过已有的属性计算得来
1.1.2 原理
底层借助了Object.defineproperty方法提供的getter和setter
1.1.3 get函数何时执行
- 初次读取时会执行一次
- 当依赖的数据发生改变时会被再次调用
1.1.4 优势
与methods实现相比,内部有缓存机制(复用),效率更高,调用更加方便
注意:
- 计算属性最终会出现在vm上,直接读取使用即可,在页面上直接使用{{方法名}}来显示计算结果
- 如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变
1.1.5 简单姓名案例
<div class="root">
姓:<input type="text" v-model="firstName" /><br /><br />
名:<input type="text" v-model="lastName" /><br /><br />
全名:<span>{{fullName}}</span>
</div>
</body>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el: ".root",
data: {
firstName: "冰",
lastName: "墩墩",
},
computed: {
fullName: {
get() {
return this.firstName + "-" + this.lastName;
},
set(value) {
const arr = value.split("-");
this.firstName = arr[0];
this.lastName = arr[1];
},
},
},
});
</script>
计算方法简写方式(只考虑读取,不考虑修改的时候)
computed: {
// 简写(不考虑set的情况下)
fullName() {
return this.firstName + "-" + this.lastName;
},
},
1.2 侦听属性 - watch
1.2.1 侦听属性
- 当被侦听的属性变化时,回调函数自动调用,进行相关操作
- 侦听的属性必须存在,才能进行侦听
- 侦听的两种写法:
- new Vue时传入watch配置
- 通过vm.$watch侦听
1.2.2 案例练习
简单天气变化案例 - 侦听属性
<body>
<div class="root">
<h2>今天天气很{{info}}</h2>
<button @click="change">切换天气</button>
</div>
</body>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el: ".root",
data: {
isHot: true,
},
computed: {
info() {
return this.isHot ? "炎热" : "凉爽";
},
},
methods: {
change() {
this.isHot = !this.isHot;
},
},
watch: {
isHot: {
immediate: true,
handler(newValue, oldValue) {
console.log("isHot被修改了", newValue, oldValue);
},
},
},
});
</script>
第二种写法
vm.$watch("isHot", {
immediate: true,
handler(newValue, oldValue) {
console.log("isHot被修改了", newValue, oldValue);
},
});
1.2.3 深度侦听
- Vue中的watch默认不侦听对象内部的改变(一层)。
- 配置deep:true 可以侦听对象内部值的改变(多层)。
注意:
- Vue自身可以检测对象内部值的改变,但Vue提供的watch默认不可以
- 使用watch时根据数据的具体解构,决定是否采用深度侦听
watch: {
isHot: {
deep: true,
immediate: true,
handler(newValue, oldValue) {
console.log("isHot被修改了", newValue, oldValue);
},
},
},
1.2.4 侦听的简写形式
watch: {
// 简写
isHot(newValue, oldValue) {
console.log("isHot被修改了", newValue, oldValue);
},
},
// 简写
vm.$watch("isHot", function (newValue, oldValue) {
console.log("isHot被修改了", newValue, oldValue);
});
注意:简写的条件是在不需要设置deep和immediate的情况下
1.2.5 watch对比computed
computed 和 watch 之间的区别:
- computed能完成的功能,watch都可以完成
- watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作
两个重要的小原则:
- 所有被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象
- 所有不被Vue管理的函数(定时器的回调函数、ajax的回调函数等),最好写成箭头函数,这样this的指向才是vm 或 组件实例对象
二、样式绑定
2.1 class样式绑定
写法::class="xxx",xxx可以是字符串、对象、数组
1. 字符串写法适用于:类名不确定,要动态获取
2. 对象写法适用于:要绑定多个样式,个数不确定,名字也不确定
3. 数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用
<style>
.basic {
height: 200px;
width: 200px;
border: 1px solid black;
}
.skyblue {
background-color: skyblue;
}
.red {
background-color: red;
}
.yangshi1 {
background-color: skyblue;
}
.yangshi2 {
font-size: 40px;
}
.yangshi3 {
color: #fff;
}
</style>
</head>
<body>
<div class="root">
<!-- 绑定class样式 -- 字符串写法 -->
<div class="basic" :class="mood" @click="changeColor">{{name}}</div>
<br /><br />
<!-- 绑定class样式 -- 数组写法 -->
<div class="basic" :class="classArr">{{name}}</div>
<br /><br />
<!-- 绑定class样式 -- 对象写法 -->
<div class="basic" :class="classObj">{{name}}</div>
<br /><br />
</div>
</body>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el: ".root",
data: {
name: "测试案例",
mood: "skyblue",
classArr: ["yangshi1", "yangshi2", "yangshi3"],
classObj: {
yangshi1: false,
yangshi2: true,
},
},
methods: {
changeColor() {
this.mood = "red";
},
},
});
</script>
2.2 style样式绑定
1. 对象写法,:style="{fontSize: xxx}",其中xxx是动态值
2. 数组写法,:style="[a,b]",其中a、b是样式对象
<div class="root">
<!-- 绑定style样式 -- 对象写法 -->
<div class="basic" :style="styleObj">{{name}}</div>
<br /><br />
<!-- 绑定style样式 -- 数组写法 -->
<div class="basic" :style="styleArr">{{name}}</div>
</div>
</body>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el: ".root",
data: {
styleObj: {
fontSize: "40px",
color: "red",
},
styleObj2: {
backgroundColor: "orange",
},
styleArr: [
{
fontSize: "40px",
color: "#fff",
},
{
backgroundColor: "red",
},
],
},
});
</script>
三、条件渲染
3.1 v-if
写法:
- v-if = '表达式'
- v-else-if = '表达式'
- v-else = '表达式'
适用于:切换频率较低的场景
特点:不展示的DOM元素直接被移除
注意:v-if 可以和v-else-if、v-else一起使用,但要求解构不能被打断
3.2 v-show
写法:v-show='表达式'
适用于:切换频率较高的场景
特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
注意:使用 v-if 的时候,元素可能无法获取到,而使用 v-show 一定可以获取到
3.3 简单案例练习
<div class="root">
<h2>当前n的值: {{n}}</h2>
<button @click="n++">点击n+1</button>
<!-- v-if、v-else-if、v-else做条件渲染 -->
<div v-if="true">v-if当条件为true</div>
<div v-if="1 === 1">v-if当条件为true</div>
<div v-if="n === 1">v-if当n为1时显示</div>
<div v-else-if="n === 2">v-else-if当n为2时显示</div>
<div v-else-if="n === 3">v-else-if当n为3时显示</div>
<div v-else>v-else当n不为1,2,3时显示</div>
<!-- v-if与template的配合使用 -->
<template v-if=" n === 1">
<h2>姓名</h2>
<h2>性别</h2>
<h2>地址</h2>
</template>
<!-- v-show做条件渲染 -->
<div v-show="true">v-show条件渲染,true</div>
<div v-show="1 === 1">v-show条件渲染,true</div>
</div>
</body>
<script>
Vue.config.productionTip = false;
new Vue({
el: ".root",
data: {
n: 0,
},
});
</script>