目录
1.计算属性computed
computed中文意思是计算属性,作用是基于其依赖的响应式数据动态返回一个计算结果。与方法(methods)不同的是,计算属性是基于它们的响应式依赖自动缓存的。
计算属性的特点:
-
侧重在【算】,核心是:计算出来的值。
-
靠
return
来输出计算的结果。 -
不能异步计算。
代码创建:src/components/目录下创建一个app.vue文件
代码意思解释:
data 选项中的 firstName 和 lastName 两个响应式数据。
computed 选项中的 fullName 计算属性。
fullName 计算属性返回 firstName 和 lastName 的拼接结果。
在模板中使用 {{ fullName }} 输出计算结果当 firstName 或 lastName 变化时,fullName 会自动重新计算并返回最新的值,而不需要手动调用方法。
<template>
<div>{{ fullName }}</div>
</template>
<script>
export default {
data() {
return {
firstName: "张",
lastName: "三",
};
},
computed: {
fullName() {
return this.firstName + " " + this.lastName;
},
},
};
</script>
运行结果:
2. 监听属性watch
watch 是 Vue 中的一个选项,用于监听响应式对象的变化。它的作用是:当监听的对象变化时,触发对应的回调函数。
watch的特点:
-
侧重在【监视】,核心是:
xxx
变了,我要做???
事。 -
无需
return
,靠内部逻辑去完成要做的事。 -
能开启异步任务。
创建文件watch.html文件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>watch</title>
<!-- 引入Vue -->
<script type="text/javascript" src="/js/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器-->
<div id="demo">
姓 : <input type="text" v-model="firstName" /><br>
名 : <input type="text" v-model="lastName" /><br>
全名: <span>{{fullName}}</span>
</div>
</body>
<script type="text/javascript">
//阻止 vue 在启动时生成生产提示。
Vue.config.productionTip = false;
new Vue({
el: "#demo",
data: {
firstName: "He",
lastName: "ZhiWei",
fullName: '',
},
watch: {
firstName: { //监听firstName,要加冒号。
immediate: true,
handler(value) {
this.fullName = value.slice(0, 1).toUpperCase() + value.slice(1) + "-" + this.lastName
}
},
lastName(value) {
this.fullName = this.firstName.slice(0, 1).toUpperCase() + this.firstName.slice(1) + "-" + value
}
}
})
</script>
</html>
3. computed与watch比较
computed
和watch
之间的区别与联系:
-
computed
能完成的功能,watch
都可以完成,且通常computed
的写法会更简便。例如:姓名案例,
computed
、watch
都能完成,但computed
写起来,更简单。 -
watch
能完成的功能,computed
不一定能完成。例如:还做姓名案例,但要求:名改完
1
秒钟后,全名再变。
4. 条件渲染
4.1 v-show
v-show 是 Vue 中的一个指令,用于根据表达式的真假值,切换元素的 display CSS 属性来显示或隐藏元素
v-show特点:
-
语法:
v-show="表达式"
。 -
适用于:切换频率较高的场景。
-
特点:不展示的
DOM
元素依然在,仅仅是使用样式隐藏掉了,不破坏DOM
结构。
代码创建:src/components/目录下创建一个app.vue文件
<template>
<div>
<h1 v-show="ok">hello</h1>
</div>
</template>
<script>
export default {
data() {
return {
ok: true,
};
},
};
</script>
运行结果显示
这里,h1 元素默认是显示的,因为 ok 的初始值是 true。如果我们将 ok 改为 false,h1 会立即隐藏:
4.2 v-if
v-if 是 Vue 中的一个指令,用于根据表达式的值的真假条件渲染或销毁元素。
-
语法:
<h1 v-if="seen">Hello!</h1>
-
适用于:切换频率较低的场景。
-
特点:不展示的
DOM
元素直接被移除。注意点:
-
v-if
可以和:v-else-if
、v-else
一起使用,但要求结构不能被“打断”。 -
如果使 用
v-if
,可能会出现无法获取元素的问题。
-
与 v-show 比较,v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
代码举例 :
<template>
<div>
<h1 v-if="ok">Hello!现在在测试v-if</h1>
</div>
</template>
<script>
export default {
data() {
return {
ok: false,
};
},
};
</script>
代码运行显示:
这里,h1 元素默认是显示的,因为 ok 的初始值是 true,网页中就会显示Hello!现在在测试v-if。如果我们将 ok 改为 false,h1 会立即隐藏:
5. 列表渲染
5.1 v-for
指令
v-for 是 Vue 中的一个指令,用于渲染一个列表数据。它以 “item in items” 的语法遍历 items 数组并对数组中的每个元素执行某些操作。
-
指令:
v-for
。 -
作用:用于遍历数据(遍历渲染),生成多个结构。
-
语法:
v-for="(item,index) in xxx" :key="????"
。
通俗理解:想生成多个谁,就在谁身上加
v-for
,别忘了写key
。
key
的使用原则(同react
):有唯一值就用唯一值(身份证号、手机号、学号......),没有就用索引值。
5.2 详聊 v-for
遍历数组
<ul>
<li v-for="(item,index) in arr" :key="index"> {{item}} </li>
</ul>
遍历对象
<li v-for="(value,key,index) in car" :key="index">
{{value}} - {{key}} - {{index}}
</li>
遍历字符串
<li v-for="(char,index) in str" :key="index">
{{char}} - {{index}}
</li>
遍历指定次数
<li v-for="(number,index) in 10" :key="index">
{{number}} - {{index}}
</li>
v-for
很健壮,遍历如下内容都不会报错
<h1 v-for="(a,b) in null">娃哈哈</h1>
<h1 v-for="(a,b) in undefined">哇哈哈</h1>
<h1 v-for="(a,b) in '' ">娃哈哈</h1>
<h1 v-for="(a,b) in true ">娃哈哈</h1>
5.3 人员案例
4. 数据代理
数据代理是 Vue 中的一个概念。它是指 Vue 实例代理了其 data 对象下所有的属性,使得访问 this.数据属性 等同于访问 this.$data.数据属性。也就是说,我们可以直接在 Vue 实例上访问 data 中定义的属性,而不需要 this.$data. 属性名 这样的写法。
-
具体实现方式:
-
Vue
收集到数据后,会将所有层级的属性,全都改为getter
、setter
的形式,随后放在_data
中。 -
当
_data
中的数据放生变化时,对应的setter
会执行,在setter
中会:①修改数据、②更新界面。
-
代码举例:一句话概括数据代理就是,通过一个对象(obj1),代理对另一个对象(obj2)中属性(c)的操作(读/改),就是数据代理。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>1.何为数据代理</title>
</head>
<body>
<script type="text/javascript" >
// 通过一个对象(obj1),代理对另一个对象(obj2)中属性(c)的操作(读/改),就是数据代理
let obj1 = {a:1,b:2}
let obj2 = {c:3}
Object.defineProperty(obj1,'c',{
get(){
return obj2.c
},
set(value){
obj2.c = value
}
})
</script>
</body>
</html>
5.数据劫持
5.1 何为数据劫持
-
概念:捕获对象属性变化的一种手段,前端的响应式框架通常都会对数据进行劫持,这样当数据发生变化时,可以自动更新相关的视图或执行其他逻辑。
5.2Vue中的数据劫持
具体实现方式:
-
Vue
收集到数据后,会将所有层级的属性,全都改为getter
、setter
的形式,随后放在_data
中。 -
当
_data
中的数据放生变化时,对应的setter
会执行,在setter
中会:①修改数据、②更新界面。
数据劫持代码实现
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>2.Vue中的数据劫持</title>
<!-- 引入Vue -->
<script type="text/javascript" src="../../js/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器-->
<div id="demo">
<h2>{{school}}坐落于:{{address}}</h2>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#demo',
data: {
school: '翻斗小学',
address: '胜利路翻斗花园',
n: 1,
a: {
b: {
c: {
d: 1
}
}
}
}
})
console.log(vm)
</script>
</body>
</html>
运行截图
6 总结_数据代理 _数据劫持
-
数据代理(简单,
vm
身上的那点事):-
目的:让程序员更加方便的读取、修改到
_data
中属性。 -
原理:
Object.defineProperty
。 -
体现:
vm
身上有_data
里的所有属性,且有每一个属性,都有自己的proxyGetter
、proxySetter
。
-
当修改
vm
上的属性时,该属性对应的proxySetter
就会调用,去修改_data
中对应的属性。 -
当读取
vm
上的属性时,该属性对应的proxyGetter
就会调用,去读取_data
中对应的属性。
-
-
数据劫持(
_data
里的那点事):-
目的:为了实现响应式(什么是响应式?—— 数据变页面自动更新),有了数据劫持,就可以捕获到数据的改变,进而重新解析模板,更新界面。
-
原理:
Object.defineProperty
。 -
体现:
_data
身上的每一个属性不直接给值,都变为:reactiveSetter
、reactiveGetter
形式。
-
当修改
_data
上的属性时,该属性对应的reactiveSetter
就会调用。且在reactiveSetter
中Vue会:维护数据、更新页面。 -
当读取
_data
上的属性时,该属性对应的reactiveGetter
就会调用,返回对应的值
-