初识Vue(2)


活动地址: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 指令进行绑定

样式绑定有三种写法应对三种不同的情况:数组写法、对象写法、字符串写法

  1. 数组写法

    • 适合用于 当需要绑定的样式类名和个数都不确定、需要动态指定时

    • data() {
          return {
              name:"Careeby",
              text_mood_Arr:["text_bold","text_green","text_shadow"],
          }
      },
      
  2. 对象写法

    • 适合用于 当需要绑定的样式类名和个数都确定、需要动态决定用不用时

    • data() {
          return {
              name:"Careeby",
              text_mood_obj:{
                  text_bold:false,
                  text_green:false
              }
          }
      }
      
  3. 字符串写法

    • 适合用于 当需要绑定的样式类名不确定、需要动态指定时

    • data() {
          return {
              name:"Careeby",
              box_mood:"box",
          }
      },
      
2、行内样式的绑定使用

行内样式的绑定分成两种写法 对象写法、数组写法

其原理通过对象进行样式的绑定

  1. 对象写法

    data() {
        return {
            name:"Careeby",
            style_Obj:{
                fontSize:"20px",
                fontSize:"20px",
            }
        }
    },
    
  2. 数组写法

    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指令做条件渲染

语法:

  1. v-if=“表达式”
  2. v-else-if-“表达式”
  3. 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:

  1. 若虚拟DOM中的内容没有差异,直接使用【旧虚拟DOM】中的真实DOM
  2. 若发现两者的内容发生了差异、则会生成的新的虚拟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()方法实现监视
  1. 只要能够被检测到的数据,都会赋予一个get()和set()方法 数组除外
  2. 然后如果被检测到的数据发生改变 会立即调用该数据的set()方法,对页面中做出响应式的变化

注意:Vue的实例化完成后,对象之后添加的属性,Vue都会默认不做响应式处理

也就是说后面添加的数据 没有 get()与set(),没有set()怎么能响应布局呢、

2、如何给后添加的属性提供响应式处理?
  1. 通过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>&nbsp;&nbsp;&nbsp;&nbsp;
    <input type="radio" id="nv" name="sex" value="女" v-model="userInfo.sex"> 
    <label for="nv"></label><br><br>
	 <!-- 爱好 -->
    <label>爱好:</label>&nbsp;
    <input type="checkbox" value="learn" v-model="userInfo.hobby">学习&nbsp;
    <input type="checkbox" value="play" v-model="userInfo.hobby">玩耍&nbsp;
    <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 属性 进行绑定

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值