活动地址:CSDN21天学习挑战赛
文章目录
1、属性监控
属性监视通过vm中的watch配置实现,该配置依旧接收对象形式的数据
接收到的key值为需要监视的属性名,通常来自data/computed/method中
注意:
1、只有被监视的属性发生变化时,回调函数才会自动调用进行相关操作
2、被监视的属性必须存在,才能进行监视
3、监视属性有两种实现方法
- 第一种便是在Vm中直接配置watch属性
- 第二种在Vue管理器外面通过vm.$watch(value,function) 进行配置
方法一:实现监视属性
代码演示:
const vm=new Vue({
el:"#root",
data(){return {isHot:true}},
methods: {click(){this.isHot=!this.isHot}},
computed:{_isHot(){return this.isHot ? "炎热" : "凉爽"}},
watch: {
_isHot:{
immediate:true,
handler(newValue,oldValue){
console.log(newValue,oldValue);
}
}
}
})
这是第一种配置方法通过 watch属性监视了 computed中的 _isHot 方法
一旦 _isHot 发生改变 便会立即调用 属性监视的回调方法 handler
注意 handler 方法时系统指定的方法名 不可对其改变,该方法接收两个参数
第一个参数是被监视的属性变化后的值
第二给参数是被监视的属性变化钱的值
immediate:该属性是用于是否让是 handler 方法初始化也就是页面加载时是否调用,默认为false 不进行调用
方法二:实现监视属性
const vm=new Vue({
el:"#root",
data(){return {isHot:true}},
methods: {click(){this.isHot=!this.isHot}},
computed:{_isHot(){return this.isHot ? "炎热" : "凉爽"}}
})
vm.$watch("_isHot",{
immediate:true,
handler(newValue,oldValue){
console.log(newValue,oldValue)
}
})
内容扩展:深度监视
深度监视通过Vue中的watch配置属性中的被监视的属性说配置的deeps属性实现
vm.$watch("_isHot",{
deep:true,
immediate:true,
handler(newValue,oldValue){
console.log(newValue,oldValue)
}
})
Vue中的watch属性默认不监测对象中内部属性的改变(一层)
为监视对象配置 deep:true 之后便可以监测对象内部的属性改变(多层)
注意:
1、Vue 自身可以检测到对象中的内部属性是否发生改变,但是watch是默认不可以实现的
2、使用watch时需要根据数据的具体结构,决定是否采取深度检测
watch: {
// 监视 指定数据 深层次的数据变化
"number":{
deep:true,
handler(nweValue,oldVlaue){
alert("数据中某个属的值发生了改变")
}
}
}
属性监视的简写
注意:如果想要实现属性监视的简写 必须确定监视属性中没有配置项
例如 deep / immediate
其简写规则 与Computed 一直
atch: {
// 简写形式
a(newValue,oldValue){
console.log("属性发生变化");
},
// 完整形式
b:{
handler(newValue,oldValue){
console.log("数据B发生了变化")
}
}
}
2、watch 和 computed 的差异
1、computed计算属性能够完成,watch侦听属性都能够完成
2、watch能完成的功能computed却未必能够完成
例如:watch 可以进行异步操作,而computed却无法执行
两个重要原则
1、被Vue所管理的函数最好写成普通函数,而不是箭头函数,否则会改变this的指向
2、所有不被Vue所管理的函数,最好写成箭头函数
例如:定时器的回调函数,ajax的回调函数,最好采用箭头函数
因为你写成普通函数的话 是通过Window对象调用的function,因此this的指向必定为window,而箭头函数没有this的指向所以会向外找实例对象,直到找到vm这个实例对象
3、样式绑定
1、内嵌样式的绑定使用
样式的通过 v-bind:class=“” / :class 指令进行绑定
样式绑定有三种写法应对三种不同的情况:数组写法、对象写法、字符串写法
-
数组写法
-
适合用于 当需要绑定的样式类名和个数都不确定、需要动态指定时
-
data() { return { name:"Careeby", text_mood_Arr:["text_bold","text_green","text_shadow"], } },
-
-
对象写法
-
适合用于 当需要绑定的样式类名和个数都确定、需要动态决定用不用时
-
data() { return { name:"Careeby", text_mood_obj:{ text_bold:false, text_green:false } } }
-
-
字符串写法
-
适合用于 当需要绑定的样式类名不确定、需要动态指定时
-
data() { return { name:"Careeby", box_mood:"box", } },
-
2、行内样式的绑定使用
行内样式的绑定分成两种写法 对象写法、数组写法
其原理通过对象进行样式的绑定
-
对象写法
data() { return { name:"Careeby", style_Obj:{ fontSize:"20px", fontSize:"20px", } } },
-
数组写法
data() { return { name:"Careeby", style_Arr:[ { fontSize:"20px", }, { fontSize:"20px", } ] } },
注意:数组写法中也的元素也需要时对象形式的
绑定行内样式的key值需要注意单个字母可以正常使用
多个字母需要大驼峰命名才可以使用,这都时Vue中帮助你配置好的key值,你也可以直接使用原始的key值加上一个双引号里面正常输入属性名即可,这属于JS中的一个基本功
举例:
// 这是配置好的key值使用方法
style:{
fontSize:"20px"
textShadow:"20px 20px 5px"
}
// 这是原始的使用写法
style:{
"font-size":"20px"
"text-shadow":"20px 20px 5px"
}
4、条件渲染
可以实现条件渲染的指令有两种:v-if / v-show
1、使用v-if指令做条件渲染
语法:
- v-if=“表达式”
- v-else-if-“表达式”
- v-eles=“表达式”
适合用于切换频率比较低的场景
特点:不展示的DOM元素直接删除
注意:使用v-if、v-eles-if、else时,必须一起使用、并且结构不能够被打断、可以配合 template 标签一起使用,保证整体结构不被打乱
2、使用v-show指令做条件渲染
写法:v-show=“表达式”
适用于切换频率比较低的场景
特点:不展示的DOM元素未被删除、而是display属性变成了 none
5、列表渲染
列表渲染通过v-for=“表达式” 指令进行执行,表达式为 for of循环或者for in循环,会根据循环次数添加对应的 li 列表标签
v-for指令可以遍历 数组、对象、字符串、指定次数
1、列表渲染的基础使用
语法:
// 遍历对象 <ul> <li v-for="(person,index) of persons" v-bind:key="index"> {{person.name}}--{{person.age}} </li> </ul>
注意:
通过v-for生成的形参可以直接在行内使用
每一行绑定的key值必须要时唯一值
2、key的使用原理(重点)
1、虚拟DOM中Key的作用
原理:
key是虚拟DOM对象中唯一标识,
当数据发生变化时,Vue会根据【最新数据】生成虚拟DOM,
随后Vue将进行diff算法。将【新虚拟DOM】和【旧虚拟DOM】进行比较
2、比较规则如下
新虚拟DOM找到了旧虚拟DOM相同的key:
- 若虚拟DOM中的内容没有差异,直接使用【旧虚拟DOM】中的真实DOM
- 若发现两者的内容发生了差异、则会生成的新的虚拟DOM,随后替换掉页面中之前的真实DOM,并进行渲染
新虚拟DOM未找到旧的虚拟DOM 也会重新生成一个新的真实DOM
3、用 index 作为key可能会发生的问题
1、若对数据进行逆序添加、逆序删除等破坏顺序的操作
可能会生成一些新的没有必要的真实DOM、严重影响顺序
2、如果结构中还包含输入类的DOM例如input
则可能会产生一些错误的DOM更新、导致界面出现问题
4、开发中如何选择正确的KEY ?
1、最好使用每一条数据的唯一标识作为key。比如:id、手机号、身份证号码、学号等唯一值
2、如果数据不存在逆序添加、逆序删除、等破坏顺序的操作、并且数据仅仅只用于展示,便可以使用index作为key
6、列表过滤和列表排序实践
1、知识回顾
1、JS数组中的Sort排序
默认不传入参数时,将会把每个元素变成字符串,然后比较每一位的第一个参数值
这导致参数为Number时参数大于等于10 则会出现不可避免的误差
arr=[3,10,2,5] arr.sort() console.log(arr) >> [10,2,3,5]
但是莫得关系,在sort()方法中存在一个比较函数 他接收两个形参
两个形参会随机的在数组中抽取,直到排序完成
而这个比较方法也比较讲究 他是根据你的返回值来判定是否要将两个参数调换位置
如果 Value1-Value2>0 , 代表Value1>Value2,则会将Value1放置后面,
如果 Value1-Value2<0,代表Value2<Value1,则会将Value2放置前面
最后形成一个升序排序
arr=[3,10,2,5] arr.sort((a,b)=>{ return a-b })
如果 Value2-Value1>0 , 代表Value2大于Value1,则会将Value1放置后面,
如果 Value2-Value1<0,代表Value2小于Value1,则会将Value2放置前面
最后形成一个降序排序
arr=[3,10,2,5] arr.sort((a,b)=>{ return a-b })
2、JS数组中的filter过滤
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
注意: filter() 不会对空数组进行检测。
注意: filter() 不会改变原始数组。
该方法基本使用 可以只传入一个形参,该形参的用途就是循环储存数组中的子元素
arr=[3,10,2,5] const arr2=arr.filter((value)=>{ if(value>4){ return value } })
它内部的返回方法可以为一个具体子元素、还可以为一个Boolean值,true为有值返回否则无值返回
2、列表过滤
列表过滤可以通过两种方案实现 :watch监视属性、computed计算属性
watch实现
watch: {
str:{
immediate:true,
handler(newValue){
// 需要过滤的数组时 persons,但是不能操作原数组,所以真正操作的数组为 personsArr
// 需要过滤的条件为 : str
this.personsArr=this.persons.filter((value)=>{
return value.name.indexOf(this.str)!=-1
})
}
}
}
computed实现
computed:{
nameSelect(){
arr=this.persons.filter((person)=>{
return person.name.indexOf(this.str)!==-1
})
return arr
}
}
3、列表排序
通过computed是实现
computed:{
nameSelect(){
// 这一步是将符合条件的 数据筛选出来
const arr=this.persons.filter((person)=>{
return person.name.indexOf(this.str)!==-1
})
// 定义排序
// 0-原顺序 1-升序 2-降序
// 第二个值减去第一个值为 降序
if(this.type!== 0){
arr.sort((a,b)=>{
return this.type===1 ? a.age-b.age:b.age-a.age
})
}
return arr
}
}
7、Vue原生监测数据原理
1、Vue会监视data中深层次的数据
它监测的原理为内部配置了一个递归代码,通过不断向下查找 直到找不到可以赋值的属性为止,这里的赋值是指的Setter和Getter
2、Vue是如何监视对象中的数据变化的?
1、通过 setter()和getter()方法实现监视
- 只要能够被检测到的数据,都会赋予一个get()和set()方法 数组除外
- 然后如果被检测到的数据发生改变 会立即调用该数据的set()方法,对页面中做出响应式的变化
注意:Vue的实例化完成后,对象之后添加的属性,Vue都会默认不做响应式处理
也就是说后面添加的数据 没有 get()与set(),没有set()怎么能响应布局呢、
2、如何给后添加的属性提供响应式处理?
- 通过Vue中所提供的set API即可 该api 有两种写法
一种是Vue上所提供的原生API Vue.$set()
一种是实例化Vue对象时所做的数据代理的方法 vm.$set()
该方法接收三个参数:
参数1:指定需要向data中的哪个对象添加属性
参数2:需要添加的属性名
参数3:需要添加的属性值
注意:被添加的属性不能是vm/vm.data的根数据
代码示例
// 第一种方案
Vue.set(vm.Student,"sex","男")
// 第二种方案
vm.$set(this.Student,'sex',"男")
3、Vue是如何监视数组中的数据变化的
原理就是通过包装数组更新元素的方法实现的,本质上他只做了两件事情
1、调用原生的数组方法,对数组的内容做出操作
2、重新解析模板,进而更新页面做出响应式处理
注意:如果想要操作数组从而改变data中的数据,一定要通过被包装过的方法实现,如果直接使用数组的索引进行操作是肯定不行的
被Vue包装的API如下
push():向数组的最后添加一个子元素
pop():移除数组中的最后一个子元素
unShift():向数组的最前面添加一个子元素
Shift():移除数组中的第一个子元素
splice():替换掉数组中的指定元素
sort():为数组中的元素排序
reverse():反转整个数组
或者使用 Vue.set() / vm.$set() API
8、收集表单数据
代码演示:
<div id="root">
<form @submit.prevent="demo">
<!-- 基本账号信息 -->
<label for="demo">账号:</label>
<input type="text" name="" id="demo" v-model.trim="userInfo.Account"><br><br>
<label for="pwd">密码:</label>
<input type="password" name="" id="pwd" v-model.trim="userInfo.Password"><br><br>
<label for="age">年龄:</label>
<input type="number" name="" id="age" v-model.number="userInfo.age"><br><br>
<!-- 性别 -->
<label >性别:</label>
<input type="radio" id="nan" name="sex" value="男" v-model="userInfo.sex">
<label for="nan"> 男</label>
<input type="radio" id="nv" name="sex" value="女" v-model="userInfo.sex">
<label for="nv">女</label><br><br>
<!-- 爱好 -->
<label>爱好:</label>
<input type="checkbox" value="learn" v-model="userInfo.hobby">学习
<input type="checkbox" value="play" v-model="userInfo.hobby">玩耍
<input type="checkbox" value="sleep" v-model="userInfo.hobby">睡觉 <br><br>
<!-- 所属学院 -->
<label for="school">所属学院:</label>
<select name="" id="school" v-model="userInfo.school">
<option value="">请选择你的学院</option>
<option value="信息工程学院">信息工程学院</option>
<option value="建筑工程学院">建筑工程学院</option>
<option value="旅游商贸学院">旅游商贸学院</option>
<option value="测绘地理学院">测绘地理学院</option>
</select> <br><br>
<!-- 其他 -->
<label for="">其他信息:</label><br>
<textarea placeholder="说些什么吧!" v-model.lazy="userInfo.other"></textarea><br><br>
<!-- 同意用户协议 -->
<input type="checkbox" name="" id="user" v-model="userInfo.user">
<label for="user"> 已阅读并同意<a href="" >《用户协议》</a></label>
<br><br>
<button style="width:205px;height: 30px;" >提交表单</button>
</form>
</div>
// 通过 Vue收集表单数据
<script>
const vm=new Vue({
el:"#root",
data() {
return {
userInfo:{
Account:"",
Password:"",
age:"",
sex:"男",
hobby:[],
school:"",
other:"",//其他信息
user:"",
}
}
},
methods: {
demo(){
json=JSON.stringify(this.userInfo)
// 将JS类型的数据 转换成 JSON格式
js=JSON.parse(json)
// 将JSON格式数据 转换成JS格式
console.log(this.userInfo);
console.log(json);
console.log(js);
}
},
})
</script>
收集表单数据总结:
v-model 收集的是value值 用户输入的就是 value
v-model 收集是value值 但是value值需要自己配置,否则空值
1、v-model 默认收集checked的布尔值,勾选为true 否则为true
2、就算给该标签配置了value值 但是vm实例对象中的初始值不为数组,那么收集的的数据还是true或false
3、如果在data中收集该标签的初始值为一个数组,那么就是收集一个value组成的数组
v-model的三个修饰符
1、v-model.lazy=“”
当Vue在收集用户录入的信息时,使用该修饰符,就能使用户的焦点离开输入框时再收集数据
2、v-model.number=“”
将用户输入的数据转换成 number类型 ,通常配合 使用
3、v-model.trim=“”
删除用户输入的内容中的前后空格符号
lable标签的配合使用
<lable for="Account">账号</lable>
<input type="text" id=Account/>
这样配合使用在用户点击文字时 将焦点移动到响应的 input 文本框中
其中通过 lable标签中的for 属性 与input标签中 id 属性 进行绑定