《基础篇第2章:vue2基础》包含Vue2知识点、个人总结的使用注意点及碰到的问题总结

本文主要是介绍《基础篇第2章:vue2基础》包含Vue2知识点、个人总结的使用注意点及碰到的问题总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述

文章目录

  • 第2章:vue2基础 - 指令
    • 2.1如何使用vue
    • 2.2vue模板语法
    • 2.3文本渲染 (都是针对标签属性)
      • 2.3.1 v-text
      • 2.3.2 v-once
      • 2.3.3 v-html
    • 2.4数据绑定
    • 2.5el和data两种写法
    • 2.6MVVM模型
    • 2.7数据代理
      • 2.7.1回顾Object.defineProperty()
      • 2.7.2何为数据代理
      • 2.7.3vue中的数据代理
    • 2.8事件处理
      • 2.8.1事件的基本使用
      • 2.8.2 $event 对象
      • 2.8.3事件的修饰符
      • 2.8.4键盘事件(键值修饰符)
    • 2.9条件渲染
    • 2.10列表渲染
      • 2.10.1 v-for
      • 2.10.2 key 属性(非常重要)
      • 2.10.3 取值范围
      • 2.10.4列表过滤
      • 2.10.5列表排序
      • 2.10.6 Vue监测“对象”数据改变的原理
      • 2.10.7 Vue.set()或者vm.$set()动态新增标签
      • 2.10.8Vue监测“数组”数据改变的原理
      • 2.10.9总结vue数据监测
    • 2.11 表单输入绑定
      • 2.11.1 文本 text
      • 2.11.2 复选框
      • 2.11.3 单选框
      • 2.11.4选择列表
      • 2.11.5修饰符
    • 2.12计算属性与监听属性
      • 2.12.1计算属性computed
      • 2.12.2(简写)计算属性
      • 2.12.3计算属性-天气案例
      • 2.12.4监听属性watch
      • 2.12.5监听属性watch-深度监听
      • 2.12.6监听属性watch-(简写)深度监听
      • 2.12.7计算属性和监视属性区别
    • 2.13绑定样式
      • 2.13.1绑定class
      • 2.13.2绑定style
    • 2.14自定义过滤器
    • 2.15内置指令
      • 2.15.1 v-cloak指令
      • 2.15.2 v-pre指令
    • 2.16.自定义指令
      • 2.16.1基本使用
        • 1)定义
        • 2)使用
      • 2.16.2钩子函数
      • 2.16.3实例图片懒加载
        • 1)样式
        • 2)自定义v-img指令
        • 3)模拟数据
        • 4)使用
        • 5)效果
  • 本人其他相关文章链接

第2章:vue2基础 - 指令

2.1如何使用vue

如何使用Vue:
1、引入Vue的核心JS文件
2、准备Dom结构
3、实例化组件
通过el属性,挂载元素,绑定id为app的html元素
通过data属性,定义数据,可以在html代码段中显示的数据
4、获取数据
数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值

2.2vue模板语法

在这里插入图片描述

<div id="app"><h1>插值语法</h1><h1>{{name}}-{{address}}</h1><hr><h1>指令语法</h1><a v-bind:href="url">点我跳转百度</a><a :href="url"></a>
</div>

2.3文本渲染 (都是针对标签属性)

2.3.1 v-text

在这里插入图片描述

注意点1:v-text=’msg’会拿msg的值替换标签体的值,换句话说如果设置了v-text标签且无论msg是否为空,那么标签体的内容“你好”就失效了,不会显示

比如data中msg值为Hello World,那么页面会显示Hello World,如果msg=’ ’值为空,那么h3整个标签都不会显示,更不会显示标签体内容“你好”
<h3 v-text=’msg’>你好</h3>

在 html 中插入数据,跟{{}}功能一致:
在这里插入图片描述

2.3.2 v-once

注意点1:切记不要弄混了文本渲染v-once和事件修饰符的.once
文本渲染v-once:指页面只渲染一次
事件修饰符的.once:指的是方法只调用一次有效
在这里插入图片描述

2.3.3 v-html

在这里插入图片描述

注意点1(重点关注):使用v-html存在安全隐患,比如下面图片举例说明,str2是一个黄色钓鱼网址链接,如果使用v-html,那么会解析标签内容结构到页面上变成一个链接,如果用户点击了该链接,那么恶意网站就能获取用户登录cookie(cookie包含了你的用户名密码),那么恶意网站就会做坏事了,比如盗号、恶意转账盗钱等。所以为了避免安全隐患,请谨慎使用v-html标签,如果你确定代码部分是安全的,不会有乱七八糟的东西,那么使用v-html标签也没事。而v-text就不会解析html元素,就不会把str2变成链接地址,这样因为跳转不了,恶意软件也就无法获取用户cookie 了,也就做到了避免安全隐患。
在这里插入图片描述

注意点2:把文本内容进行解析,生成 html 结构并渲染。
在这里插入图片描述
在这里插入图片描述

2.4数据绑定

v-bind 指令可以绑定元素的属性,动态给属性赋值。比如: v-bind:class、
v-bind:style、 v-bind:href 形式。
注意点1:v-bind标签不仅可以传属性值,还可以传方法

v-bind:是单项绑定,下图中黄线存在,粉线不存在
注意点2:总结:v-bind单向绑定 v-model双向绑定
在这里插入图片描述

v-model只能用于表单元素,换句话说只作用于有value属性的标签(表单元素)
在这里插入图片描述

在这里插入图片描述

2.5el和data两种写法

在这里插入图片描述

el两种方法
在这里插入图片描述

data两种写法
在这里插入图片描述

说明点1:el两种用哪个都可以,但是data两种方式分情况,后续使用组件,data使用方式必须使用“函数式”,不然会报错。

data写法函数式的普通方式:data:function () {}data:function () {
console.log('@@@',this)  //指代vue对象return{name:"尚硅谷",address:"哈尔滨",}
}
data写法函数式的简化普通方式:data() {}
data() {
console.log('@@@',this)  //指代vue对象return{name:"尚硅谷",address:"哈尔滨",}
}
data的第二种写法箭头函数式:data:()=> {}
data:()=> {console.log('@@@',this)  //指代window对象return{name:"尚硅谷",address:"哈尔滨",}
}

针对函数式,箭头函数方式this指代window对象,普通方式this指代vue对象
在这里插入图片描述
在这里插入图片描述

2.6MVVM模型

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

2.7数据代理

锚点

2.7.1回顾Object.defineProperty()

回顾Object.defineProperty()方法,该方法可动态设置属性。
defineProperty(目标对象, key, {config})

注意点1:defineProperty中如果定义使用get()和set(),那么属性value和writable:true必须注释掉,不然报错
注意点2:如果defineProperty中只定义value属性,那么控制台赋值无效,即必须设置writable:true才能对person属性实现更新

let number = 18
let person = {name:"张三",sex:"男"
}Object.defineProperty(person, "age", {value:18,
}

在这里插入图片描述
如果defineProperty()方法设置属性enumerable:true、writable:true、configurable:true就可实现跟局部定义变量属性一样的效果,可增删改

Object.defineProperty(person, "age", {value:18,enumerable:true,    //控制属性是否可以枚举(也就是是否可以遍历访问到),默认值是falsewritable:true,      //控制属性是否可以被修改,默认值是falseconfigurable:true,   //控制属性是否可以被删除,默认值是false
}

在这里插入图片描述
defineProperty()方法定义get()和set()

Object.defineProperty(person, "age", {       //当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值get() {console.log('有人读取age属性了')return number},// //当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值set(value) {console.log('有人修改age属性了')number = value}})

2.7.2何为数据代理

数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)

 let obj = {x:100}let obj2 = {y:200}Object.defineProperty(obj2, "x", {get() {return obj.x},set(value) {obj.x = value}
})

在这里插入图片描述

2.7.3vue中的数据代理

问题:数据代理干了啥?

答案:
简单说:通过Object.defineProperty()方法把data对象所有属性添加到vm(Vue原型)对象上,且为每个属性指定一个getter/setter。
复杂说:首先vue把data对象所有属性添加到命名为_data的对象中,通过Object.defineProperty()方法把_data对象所有属性添加到vm(Vue原型)对象上,并为每一个添加到vm上的属性,都指定一个getter/setter,这样vm对象就有了属性name和address,不然你想操作属性只能使用_data.name_或者data.address,这样很不方便。
在这里插入图片描述

在这里插入图片描述

2.8事件处理

2.8.1事件的基本使用

注意点1:定义事件函数时,普通函数this指代vue对象,而箭头函数中this指代Window对象。
注意点2:定义事件没参数小括号()可省略,但是用在插值表达式使用一个函数返回值就必须带小括号(),比如 全名:{{fullName()}}。
注意点3:不被vue所管理的函数那么请使用箭头函数。
在这里插入图片描述

代码:

<button v-on:click="showInfo1">点我提示信息1(不传参)</button>
<button @click="showInfo2($event, 66)">点我提示信息2(不传参)</button>var vm = new Vue({el: "#app",data: {},methods:{showInfo1(event) {console.log(event);},showInfo2(event, number) {console.log(event);  //指代事件对象console.log(number);console.log(this);  //箭头函数中指代Window对象,普通方法指代vue对象}}})

2.8.2 $event 对象

在事件处理函数中访问 DOM 原生事件 event 对象,可以使用特殊变量$event 对象传
入。

2.8.3事件的修饰符

在这里插入图片描述
在这里插入图片描述

事件修饰符举例说明:

1.默认<a>标签会跳转,想实现点击不跳转就设置@click.prevent=”事件函数”或者<a href="javascript:void(0);" >
2.阻止事件冒泡
捕获阶段:指由外往内
冒泡阶段:指由内到外
举例:2个div1,div2,都有点击事件,如果不设置事件修饰符stop,那么点击div2触发事件完成之后,还会触发div1事件,而设置stop修饰符后,不会触发冒泡阶段。

在这里插入图片描述

3.once:事件只触发一次(常用),即无论点击多少次按钮,按钮只触发一次。
4.capture:设置使用事件的捕获模式,不设置使用冒泡模式(由内向外触发事件函数);

使用事件的捕获模式 :不设置.capture,先执行showMsg(2),再执行showMsg(1),设置之后先执行showMsg(1),再执行showMsg(2)

 <div class="box1" @click.capture="showMsg(1)">div1<div class="box2" @click="showMsg(2)">div2</div>
</div>showInfo(e){console.log(e.target)
}
5.self:只有event.target是当前操作的元素时才触发事件
举例:div和button都设置事件函数,如果div标签不设置.self,那么点击button按钮会调用2次函数,且输出event.target为:<button>点我提示信息</button>,如果div标签设置了.self那么只有点击div才会触发事件且输出event.target为:<div class="demo1"><button>点我提示信息</button></div>,而只点击button只会触发button的事件且输出event.target为:<button>点我提示信息</button><div class="demo1" @click.self="showInfo"><button @click="showInfo">点我提示信息</button>
</div>
6.passive:事件的默认行为立即执行,无需等待事件回调执行完毕
举例:定一个事件会计算10W次,如果不设置.passive,那么会等事件全部结束后,滚轮才会向下移动一个位置,而设置了.passive,那么滚轮会先移动而不会去等待事件执行是否结束。

在这里插入图片描述
事件的默认行为立即执行,无需等待事件回调执行完毕

<ul @wheel.passive="demo" class="list"><li>1</li><li>2</li><li>3</li><li>4</li>
</ul>demo(){for (let i = 0; i < 100000; i++) {console.log('#')}console.log('累坏了')
}

2.8.4键盘事件(键值修饰符)

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
两个隐藏小知识点:
1.事件修饰符和串行,比如:@click.stop.once
2.对于键盘按键想实现按Ctrl+y才调用,则使用@keyup.ctrl.y=”showInfo”

2.9条件渲染

锚点
在这里插入图片描述
在这里插入图片描述

注意点1:使用v-if和v-else-if和v-else时中间不可以中断,否则无效,比如:
在这里插入图片描述
注意点2:

假设我有3个<h2>标签想实现条件渲染,有3种方式可以实现并说明不同优缺点
方式1:<h2>标签加条件,缺点:太重复了

在这里插入图片描述

方式2:3个<h2>标签外绑定div条件控制,缺点:div也得知晓并设置样式,否则<h2>有样式而被div包裹后样式没了,即会改变结构

在这里插入图片描述

方式3(推荐):使用<template>标签,元素加载解析时会自动去掉<template>标签只保留<h2>标签,即不会改变结构,注意:<template>标签中只可以使用v-if,不能使用v-show,否则报错

在这里插入图片描述

2.10列表渲染

锚点

2.10.1 v-for

<li v-for="item in items">{{item.name}}</li>
列表渲染v-for可以把一组值进行列表渲染,语法形式: item  in items,items 是源数据数组并且 item 是数组元素迭代的别名。在 v-for 块中,对父作用域属性的完全访问权限。v-for 还支持一个可选的第二个参数为当前项的索引。v-for也可以遍历对象,可以指定三个形参:形式: v-for="(value, key, index) in object"value: 对象的值key: 对象的键index: 遍历的索引

在这里插入图片描述

2.10.2 key 属性(非常重要)

用 v-for 渲染列表时, 使用 key 属性给每个指定一个唯一的 ID 表示,那么可以在
下次数据渲染时,提高渲染速度。

<li v-for="item in items" :key="item.id">{{item.name}}</li>

注意:在 v-for 中:key非常重要,推荐每次都写:key
在这里插入图片描述

在这里插入图片描述

举例说明:默认存在3个标签且有值,有一个按钮效果是在最上面新增一行标签,此时会容易发生问题
点击按钮前:
在这里插入图片描述
点击按钮后:
在这里插入图片描述
结果:顺序乱了?详细原因如下图,对比相同就复用,对比不同就重新生成DOM
在这里插入图片描述

注意点1:默认不写:key时,解析DOM会自动加上数组index
注意点2::key最好绑定数据唯一标识,身份证、手机号、库表id等,这样无论在数组什么位置插入,哪怕是数组开头或者数组结尾,都不会影响结构。
注意点3:虚拟DOM存在于内存中,而用户操作的页面标签属于真实DOM

2.10.3 取值范围

v-for 也可以指定整数,用来重复多次使用模板。

<li v-for="i in 5">第 {{i}} 次</li>

2.10.4列表过滤

举例:针对

  • 内容进行过滤,根据用户输入筛选内容,要求使用computed和watch两种方式实现
    在这里插入图片描述

注意点1:列表过滤使用.filter(),它和自定义过滤器不是同一个东西。
列表过滤器.filter()用在方法中,而自定义过滤器用在插值表达式和 v-bind 表达式中。
注意点2:.filter会生成新数据,不会修改原数据结构。
注意点3:如果computed和watch两种方式都可以实现,推荐优先使用计算属性computed

方式一:computed

<div id="root"><h2>人员列表</h2><input type="text" placeholder="请输入名字" v-model="keyWord"><ul><li v-for="(p,index) of filPerons" :key="index">{{p.name}}-{{p.age}}-{{p.sex}}</li></ul></div>new Vue({el:'#root',data:{keyWord:'',persons:[{id:'001',name:'马冬梅',age:19,sex:'女'},{id:'002',name:'周冬雨',age:20,sex:'女'},{id:'003',name:'周杰伦',age:21,sex:'男'},{id:'004',name:'温兆伦',age:22,sex:'男'}]},computed:{filPerons(){return this.persons.filter((p)=>{return p.name.indexOf(this.keyWord) !== -1})}}}) 

方式二:watch

new Vue({el:'#root',data:{keyWord:'',persons:[{id:'001',name:'马冬梅',age:19,sex:'女'},{id:'002',name:'周冬雨',age:20,sex:'女'},{id:'003',name:'周杰伦',age:21,sex:'男'},{id:'004',name:'温兆伦',age:22,sex:'男'}],filPerons:[]},watch:{keyWord:{immediate:true,handler(val){this.filPerons = this.persons.filter((p)=>{return p.name.indexOf(val) !== -1})}}}})

2.10.5列表排序

注意点1:列表排序使用.sort()方法,其中sort(参数1,参数2)有两个参数,参数2-参数1为降序,参数1-参数2为升序,具体查看。
https://blog.csdn.net/weixin_46665162/article/details/112966823
注意点2:会引起自身数据的改变。
举例:对列表过滤的数据进行升降序
注意点3:.sort()方法会更改原数据结构,比如更改原数组顺序
在这里插入图片描述

<div id="root"><h2>人员列表</h2><input type="text" placeholder="请输入名字" v-model="keyWord"><button @click="sortType = 2">年龄升序</button><button @click="sortType = 1">年龄降序</button><button @click="sortType = 0">原顺序</button><ul><li v-for="(p,index) of filPerons" :key="p.id">{{p.name}}-{{p.age}}-{{p.sex}}<input type="text"></li></ul></div>new Vue({el:'#root',data:{keyWord:'',sortType:0, //0原顺序 1降序 2升序persons:[{id:'001',name:'马冬梅',age:30,sex:'女'},{id:'002',name:'周冬雨',age:31,sex:'女'},{id:'003',name:'周杰伦',age:18,sex:'男'},{id:'004',name:'温兆伦',age:19,sex:'男'}]},computed:{filPerons(){const arr = this.persons.filter((p)=>{return p.name.indexOf(this.keyWord) !== -1})//判断一下是否需要排序if(this.sortType){arr.sort((p1,p2)=>{return this.sortType === 1 ? p2.age-p1.age : p1.age-p2.age})}return arr}}}) 

2.10.6 Vue监测“对象”数据改变的原理

注意点1:vue监测数据原理就是,给每个data属性添加get()和 set()方法,即data属性改变 =》调用set() =》 重新渲染页面值改变。

注意点2:加载流程:
1)加载data属性,加工封装get()和 set()方法
2)vue._data=data,这样控制台点开vue实例就会看到一堆属性及方法了

举例:模拟data对象属性值改变了,页面值也跟着改变,即实现vue监测数据改变效果

let data = {name:'尚硅谷',address:'北京',}//第1步:创建一个监视的实例对象,用于监视data中属性的变化const obs = new Observer(data)		console.log(obs)	//第2步:准备一个vm实例对象let vm = {}vm._data = data = obs//第3步:定义观察者函数function Observer(obj){//汇总对象中所有的属性形成一个数组const keys = Object.keys(obj)//遍历keys.forEach((k)=>{Object.defineProperty(this,k,{  //this指代观察者对象,而不是vue实例get(){return obj[k]},set(val){console.log(`${k}被改了,我要去解析模板,生成虚拟DOM.....我要开始忙了`)obj[k] = val}})})}

2.10.7 Vue.set()或者vm.$set()动态新增标签

锚点
Vue.set()和vm.$set() =》 相同效果。
主要讲解Vue.set()方法是什么?
在这里插入图片描述

注意点 1:Vue.set()方法有局限性,不能给vue实例或者data的直接属性进行添加,只能作用于data下面的某个属性对象。

举例:比如动态添加“校长属性”,即动态给data属性下面的school对象添加“校长属性”
在这里插入图片描述

<body><!-- 准备好一个容器--><div id="root"><h1>学校信息</h1><h2>学校名称:{{school.name}}</h2><h2>学校地址:{{school.address}}</h2><h2>校长是:{{school.leader}}</h2><hr/><h1>学生信息</h1><button @click="addSex">添加一个性别属性,默认值是男</button><h2>姓名:{{student.name}}</h2><h2 v-if="student.sex">性别:{{student.sex}}</h2><h2>年龄:真实{{student.age.rAge}},对外{{student.age.sAge}}</h2><h2>朋友们</h2><ul><li v-for="(f,index) in student.friends" :key="index">{{f.name}}--{{f.age}}</li></ul></div></body><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。const vm = new Vue({el:'#root',data:{school:{name:'尚硅谷',address:'北京',},student:{name:'tom',age:{rAge:40,sAge:29,},friends:[{name:'jerry',age:35},{name:'tony',age:36}]}},methods: {addSex(){// Vue.set(this.student,'sex','男')this.$set(this.student,'sex','男')}}})</script>

2.10.8Vue监测“数组”数据改变的原理

问题1:vue实例对象针对数组元素并没有提供类似get和set方法,为啥也会实现页面响应式监听?

在这里插入图片描述
答案:因为vue对数组的部分基本方法进行了二次封装,在继承方法的使用效果同时,也进行了响应式更新DOM。
在这里插入图片描述

举例:爱好列表
在这里插入图片描述

<div id="root"><h2>爱好</h2><ul><li v-for="(h,index) in student.hobby" :key="index">{{h}}</li></ul>
</div>const vm = new Vue({el:'#root',data:{student:{hobby:['抽烟','喝酒','烫头']}}})

2.10.9总结vue数据监测

在这里插入图片描述

在这里插入图片描述

问题:什么叫数据劫持?

定义:指的是在访问或者修改对象的某个属性时,通过一段代码拦截这个行为,进行额外的操作或者修改返回结果。比如:拦截data各属性,添加额外的get和set方法到vue实例的_data对象中。

2.11 表单输入绑定

锚点
用 v-model 指令在表单控件元素上创建双向数据绑定。它会根据控件类型自动选取
正确的方法来更新元素。
在这里插入图片描述
在这里插入图片描述

小技巧:

1.针对input输入框想实现点击名字,光标自动定位到输入框,label设置for属性和input设置id属性即可

<label for="account">账号:</label>
<input type="text" id="account" v-model.trim="userInfo.account"> <br/><br/>

2.针对radio想实现二选一,需要设置相同name属性值,同时配置value值
3.针对radio或者select标签想实现“默认选中”,不用设置checked,只需要设置data中属性值即可
4.表单提交方式

方式1:button绑定事件
<button @click=”xx”></button>
--------------------------------------------------------------------------------------------
方式2:<form>标签设置<form @submit.prevent="demo">

5.阻止表单提交后刷新页面操作,使用事件修饰符.prevent
6.form表单提交中如何一口气获取全部数据打印输出?

方式1:定义对象接收全部参数
new Vue({el:'#root',data:{userInfo:{account:'',password:'',age:18,sex:'female',hobby:[],city:'beijing',other:'',agree:''}}console.log(JSON.stringify(this.userInfo))
--------------------------------------------------------------------------------------------
方式2:使用this._data,虽说this._data除了属性还有get和set方法,但是打印的时候不会输出这些,并不影响。
console.log(JSON.stringify(this._data))

7.针对年龄标签,防止输入字母,或者防止默认是数字但重新输入后传值为字符串,需同时设置type="number"和v-model.number

<input type="number" v-model.number="userInfo.age">

8.针对checkbox注意点1,考虑是否需要配置input标签的value值,比如:如果是爱好等多选就需要设置;如果是是否同意协议等check标签就不需要设置
9.针对checkbox注意点2,data属性值默认设置字符串和数组效果时不一样的

2.11.1 文本 text

2.11.2 复选框

单个使用时 v-model 是逻辑值: true 和 false,多个一起使用需要指定 value 值,
选中结果绑定 v-model 的数组。

2.11.3 单选框

2.11.4选择列表

2.11.5修饰符

在这里插入图片描述

2.12计算属性与监听属性

2.12.1计算属性computed

在这里插入图片描述

注意点1:只要data任意值发生改变,vue肯定会重新解析模板。比如{{fullName()}},插值表达式使用fullName()函数,那么当vue重新解析模板时,就会重新执行一遍fullName()函数,因为data任意值改变了,vue也不知道fullName()函数中是否引用了data中改变的属性,所以会选择直接重新执行一遍fullName()函数。
注意点2:默认提供了缓存机制,实际上计算属性就是调用了fullName的get()方法,get什么时候调用?1.初次读取fullName时 2.所依赖的数据发生变化时。
注意点3:既然fullName是个对象,那我插值表达式可以使用{{fullName.get()}}?
答案:不能这样使用,只有data配置和methods配置可以调用,计算配置不能这么调用,会报错fullName中get()方法不存在。
注意点4:methods定义的方法,在插值表达式使用要加(),{{fullName()}},如果是计算属性中监听的属性,则写成{{fullName}}

举例:计算“全名”标签,由“姓-名”构成
在这里插入图片描述
思路:
方式1:用插值表达式拼,(缺点:万一对字符串进行分割、转换大小写、截取长度等等操作显得表达式太长,不易解读)
全名:{{firstName}}-{{lastName}}



方式2:定义函数写在methods配置中(缺点:不提供缓存,有几个fullName()调用就会执行几次)
全名: {{fullName()}}
全名: {{fullName()}}

方式3:定义计算属性(推荐使用,有缓存),代吗如下↓

全名:<span>{{fullName}}</span> <br/><br/>computed:{fullName:{//get有什么作用?当有人读取fullName时,get就会被调用,且返回值就作为fullName的值//get什么时候调用?1.初次读取fullName时。2.所依赖的数据发生变化时。get(){console.log('get被调用了')// console.log(this) //此处的this是vmreturn this.firstName + '-' + this.lastName},//set什么时候调用? 当fullName被修改时。set(value){console.log('set',value)const arr = value.split('-')this.firstName = arr[0]this.lastName = arr[1]}}}

2.12.2(简写)计算属性

注意点1:计算属性只有在没有set方法时才能使用简写
注意点2:

问题:插值表达式中使用data配置、methods配置和计算配置时,区分何时带()?何时不能带()?

答案:
针对data配置都不带()
针对methods配置有形参带(),没有形参()可省略
针对计算配置也不带(),带()会报错

全名:<span>{{fullName}}</span> <br/><br/>computed:{//完整写法fullName:{get(){console.log('get被调用了')return this.firstName + '-' + this.lastName},set(value){console.log('set',value)const arr = value.split('-')this.firstName = arr[0]this.lastName = arr[1]}} //简写fullName(){console.log('get被调用了')return this.firstName + '-' + this.lastName}}

2.12.3计算属性-天气案例

该案例为了讲述1个坑,1个技巧

案例说明:今天天气很【炎热/凉爽】,点击按钮进行切换
源代码如下:
在这里插入图片描述
在这里插入图片描述

<div id="root"><h2>今天天气很{{info}}</h2><!-- 绑定事件的时候:@xxx="yyy" yyy可以写一些简单的语句 --><!-- <button @click="isHot = !isHot">切换天气</button> --><button @click="changeWeather">切换天气</button>
</div>const vm = new Vue({el:'#root',data:{isHot:true,},computed:{info(){return this.isHot ? '炎热' : '凉爽'}},methods: {changeWeather(){this.isHot = !this.isHot}},})

注意点1:(1个坑指的是),假设页面显示的是“今天天气很好”,也就是页面压根没用到info属性,而代码中却定义了计算属性及方法,那么会发生的坑是,点击按钮后Vue插件显示结果没变动,但是实际控制台info结果已经改变了,也就是说因为页面没用到属性所以插件就不更新值了,但是实际info值已经改变了。
注意点2:(1个技巧指的是),假设定义方法逻辑很简单,可以直接这样写@click=“isHot = !isHot”,也是生效的。
在这里插入图片描述

在这里插入图片描述

2.12.4监听属性watch

配置watch关键字和handler()方法实现监听
在这里插入图片描述

写法1:.new Vue是配置

const vm = new Vue({
watch:{isHot:{immediate:true, //初始化时让handler调用一下//handler什么时候调用?当isHot发生改变时。handler(newValue,oldValue){console.log('isHot被修改了',newValue,oldValue)}}
}

写法2:首先保证vue实例已经创建完了,在vue实例下面,通过vm.$watch配置

vm.$watch('isHot',{immediate:true, //初始化时让handler调用一下//handler什么时候调用?当isHot发生改变时。handler(newValue,oldValue){console.log('isHot被修改了',newValue,oldValue)}})
注意点1:什么场景下使用写法1 和写法2呢?
答案:创建vue实例时已经明确知道监听什么属性时就使用写法1,而如果创建vue实例时不知道监视谁,而是后续根据用户业务行为才知道要监视谁就使用写法2注意点2:vm.$watch(参数1,参数2)有两个参数,参数2为{}配置对象,参数1表示你要监视的属性名,注意名字要加引号“引号”标识,如果直接写vm.$watch(isHot,参数2)这是错误的,会报如下错误,原因在于写法1中的isHot不会触发“读取变量”,而写法2会触发“读取变量”,所以写法2中属性名必须加“引号”。

在这里插入图片描述

2.12.5监听属性watch-深度监听

在这里插入图片描述

举例:data配置numbers对象,其中有属性a和b,我想监听numbers,只要numbers中任意属性值改变了,我就打印一条语句。

<h3>a的值是:{{numbers.a}}</h3>
<button @click="numbers.a++">点我让a+1</button>
<h3>b的值是:{{numbers.b}}</h3>
<button @click="numbers.b++">点我让b+1</button>const vm = new Vue({el:'#root',data:{numbers:{a:1,b:1}},watch:{numbers:{deep:true, //开启深度监视,监视多级结构中所有属性的变化handler(){console.log('numbers改变了')}}}
})

注意点1:默认deep为false,不进行深度监视,这样效率快
注意点2:如果如图1这么写,不配置deep=true的话,那么watch配置会让vue实例监视的是整个numbers的地址,而不是咱们想实现的监视numbers对象内部任意属性值a或者b的变化,因为如图2,watch配置会让vue实例默认监视的是“粉色框”的地址值是否改变,而不是监视“绿色框”中属性a和b的值是否改变,哪怕属性a或者b值改变了,但是numbers对象整体地址没改变,那么被watch配置的vue实例就会觉得监视值未改变,所以如果想实现深度结构监控,请设置deep=true
记住:配置watch是为了作用于vue实例怎么怎么怎么地。
在这里插入图片描述
在这里插入图片描述

2.12.6监听属性watch-(简写)深度监听

watch和 vm.$watch都有2种写法:

问题:什么情况下使用简写方式?

答案:当监听属性中只用到handler()方法,而没有其他配置(比如immediate或者deep)时,就可以使用简写方式。

watch:{//正常写法isHot:{// immediate:true, //初始化时让handler调用一下// deep:true,//深度监视handler(newValue,oldValue){console.log('isHot被修改了',newValue,oldValue)}}, //简写isHot(newValue,oldValue){console.log('isHot被修改了',newValue,oldValue,this)} 
}
-------------------------------------------------------------------------------------------------
//正常写法
vm.$watch('isHot',{immediate:true, //初始化时让handler调用一下deep:true,//深度监视handler(newValue,oldValue){console.log('isHot被修改了',newValue,oldValue)}
}) 
-------------------------------------------------------------------------------------------------
//简写
vm.$watch('isHot',function(newValue,oldValue){console.log('isHot被修改了',newValue,oldValue,this)
}) 

2.12.7计算属性和监视属性区别

举例说明:天气案例

计算属性

data:{firstName:'张',lastName:'三'},computed:{info(){return this.firstName + “-” + this.lastName}},

监视属性

data:{firstName:'张',lastName:'三',fullName:'张-三'},watch:{firstName(val){this.fullName = val + '-' + this.lastName},lastName(val){this.fullName = this.firstName + '-' + val}}

区别:

注意点1:如果计算属性computed和监视属性watch都可以实现,推荐使用计算属性,因为代码最少
注意点2:计算属性computed不能使用异步操作,比如睡一秒再执行操作等,而监视属性watch可以进行异步操作
注意点3:为了使用this指代vue对象,那么使用计算属性computed的同步操作,必须写普通函数(因为计算属性computed被vue管理),如果使用监视属性watch的异步操作等(不被vue所管理的函数)那么请使用箭头函数,
(即:
计算属性使用同步操作的普通函数,this => vue,
计算属性使用同步操作的箭头函数,this => window

监视属性使用同步操作的普通函数,this => vue,
监视属性使用同步操作的箭头函数,this => window,
监视属性使用异步操作的普通函数,this => window,
监视属性使用异步操作的箭头函数,this => vue,具体原因看下面图
)。
在这里插入图片描述

2.13绑定样式

2.13.1绑定class

在这里插入图片描述

data:{name:'尚硅谷',mood:'normal',classArr:['atguigu1','atguigu2','atguigu3'],classObj:{atguigu1:false,atguigu2:false,}
}

2.13.2绑定style

在这里插入图片描述

data:{styleObj:{fontSize: '40px',color:'red',},styleObj2:{backgroundColor:'orange'},styleArr:[{fontSize: '40px',color:'blue',},{backgroundColor:'gray'}]
}

2.14自定义过滤器

在这里插入图片描述

Vue允许自定义过滤器,可被用作一些常见的文本格式化。
过滤器可以用在两个地方:mustache 插值表达式和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。
注意点1:过滤器无形参时,默认也会把前面参数传给过滤器,举例:{{time | timeFormater}},默认会把time当作第一个参数传给timeFormater
注意点2:过滤器有形参时,前面的参数还是当作第一个参数,而形参默认当作第二个参数,举例:{{time | timeFormater(‘YYYY_MM_DD’)}},time 为形参1,'YYYY_MM_DD’为形参2
注意点3:过滤器可串行使用:{{ message | filterA | filterB }}
注意点4:过滤器并没有改变原本数据
注意点5:“ES6默认参数”机制(可用在方法中) =》举例:timeFormater方法的第二个参数str,如果有传值就用传递过来的值,如果str为空,就用默认的值YYYY年MM月DD日 HH:mm:ss

filters:{timeFormater(value,str='YYYY年MM月DD日 HH:mm:ss'){return dayjs(value).format(str)}}

注意点6:过滤器应该被添加在 JavaScript 表达式的尾部,由“管道符”指示:

<!-- in mustaches -->
{{ message | capitalize }}
<!-- in v-bind -->
<div v-bind:id="name| upperCase ">hei</div>

注意点7:使用Vue.filter定义全局过滤器,使用filters在组件内指定局部过滤器。

<div id="root"><h4>{{name | upperCase | length | test('A-','-B')}}</h4>
</div>
<script>/**** filter:过滤器* */var vm = new Vue({el: '#root',data: {name: 'hello'},filters: {upperCase: function (value) {return value.toUpperCase();},length: function (value) {return value+value.length;},//在value两边加点东西test: function (value, begin, end) {console.log(value, begin, end);return begin+value+end;}}});
</script>

在这里插入图片描述

2.15内置指令

就是介绍下vue自带的但是我们不常用到的指令

2.15.1 v-cloak指令

在这里插入图片描述

举例说明:比如网页上方有个{{name}}属性,在<div>标签下面</body>的上面写个js引入文件,如果js引入出现网络延迟,那么出现的现象是页面只显示{{name}},而没有走到实例化vue去解析页面内容,这样用户体验极差,正常效果是要么不显示name,要么解析好了直接显示name属性值。解决方案:标签设置 v-cloak特殊属性,并配合css样式display:none进行隐藏内容,默认网页元素加载时隐藏{{name}}属性所在的标签,当实例化vue完毕后会自动删除v-cloak特殊属性,从而达到显示name属性值的作用。
<head><meta charset="UTF-8" /><title>v-cloak指令</title><style>//[v-cloak]代表选中所有带v-cloak的标签[v-cloak]{display:none;}</style><!-- 引入Vue --></head><body>		<!-- 准备好一个容器--><div id="root"><h2 v-cloak>{{name}}</h2></div><script type="text/javascript" src="http://localhost:8080/resource/5s/vue.js"></script></body><script type="text/javascript">console.log(1)Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({el:'#root',data:{name:'尚硅谷'}})</script>

2.15.2 v-pre指令

在这里插入图片描述

注意点1:加了v-pre后,vue解析到红色框时,就会跳过该行了,不会去判断当前行是否有指令和插值表达式之类的。

2.16.自定义指令

除了默认设置的核心指令 (v-model 和 v-show),Vue 也允许注册自定义指令。
在这里插入图片描述

2.16.1基本使用

1)定义

注意点1:定义全局指令使用Vue.directive,定义局部指令使用directives。
注意点2:自定义指令时不需要加v-,而标签使用时需要加v-自定义指令名
注意点3:只定义指令可以用在很多地方,包括:标签属性、标签体内容、绑定事件…
注意点4:

问题:自定义函数何时被调用?

答案:
1)指令与元素成功绑定时(一上来)
2)指令所在的模板被重新解析时,比如下方图片,无论data中属性name或者属性n只要其中任意一个发生值改变,上面的红框div模板就会进行重新解析
在这里插入图片描述

注意点5:自定义指令有两个形参,形参1代表:自定义指令所在的标签,如图1,形参2:代表绑定的所有信息封装一个成对象给你,如图2,既然形参1能获取自定义指令所在的标签,那么指令用在标签属性、标签体内容、绑定事件上,就都可以实现了。
在这里插入图片描述
图1:形参1
在这里插入图片描述

图2:形参2

//自定义全局指令v-focus
Vue.directive('focus',{//当绑定元素插入到DOM调用inserted: function (el) {//元素获取焦点el.focus();}
});

使用directive定义,第一个参数为指令名,使用时加上v-前缀才能生效。inserted属性指当绑定元素插入到DOM时调用。
定义局部指令使用directives:

//定义局部指令使用directives
var app = new Vue({el:'#app',directives:{focus:{inserted: function (el) {//元素获取焦点el.focus();}}}
});
2)使用
<div id="app"><input type="text" v-focus>
</div>

2.16.2钩子函数

指令定义函数提供了几个钩子函数 (可选):

  • bind:只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
  • inserted:被绑定元素插入父节点时调用 (父节点存在即可调用,不必存在于 document 中)。
  • update:所在组件的 VNode 更新时调用,但是可能发生在其孩子的 VNode 更新之前。指令的值可能发生了改变也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 。
  • componentUpdated:所在组件的 VNode 及其孩子的 VNode 全部更新时调用。
  • unbind:只调用一次,指令与元素解绑时调用。

钩子函数的参数有4个:
1)el:当前指令绑定元素
2)binding:当前指令绑定的所有信息对象,有以下属性:

  • name:指令名,不包括 v- 前缀。
  • value:指令的绑定值,例如:v-my-directive=“1 + 1”, value 的值是 2。
  • oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
  • expression:绑定值的字符串形式。例如 v-my-directive=“1 + 1” ,expression 的值是 “1 + 1”。
  • arg:传给指令的参数。例如 v-my-directive:foo,arg 的值是 “foo”。
  • modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar, 修饰符对象 modifiers 的值是 { foo: true, bar: true }。

3)vnode:Vue 编译生成的虚拟节点
4)oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated
钩子中可用。

<div id="app"><input type="text" v-demo:arg.a.b="1+1">
</div>
<script>Vue.directive('demo',{bind: function (el,binding) {console.log(el);console.log(binding);}});var app = new Vue({el:'#app'});
</script>

在这里插入图片描述

2.16.3实例图片懒加载

谷歌图片的加载做得非常优雅,在图片未完成加载前,用随机的背景色占位,图片加载完成后才直接渲染出来,用自定义指令可以非常方便的实现这个功能。

1)样式
<style>.item, .item img{width: 200px;height: 120px;float: left;}
</style>
2)自定义v-img指令
//定义全局自定义指令v-img
Vue.directive('img',{bind: function (el,binding) {//生成随机颜色var color = parseInt(Math.random()*0xFFFFFF).toString(16);//设置当前元素的背景,提前进行占位等待图片加载el.style.background = '#'+color;//setTimeout模拟图片加载的延时情况setTimeout(function () {//创建图片对象var img = new Image();//通过binding对象获取真实的图片urlimg.src = binding.value;//将图片元素插入DOM结构el.appendChild(img);//随机延时},Math.random()*3000+500);}
});
3)模拟数据
var app = new Vue({el:'#app',data:{//定义模拟数据imgs:[{url:'img/01.jpg'},{url:'img/02.jpg'},{url:'img/03.jpg'},{url:'img/04.jpg'}]}
});
4)使用
<div id="app"><div v-img="item.url" v-for="item in imgs" class="item"></div>
</div>
5)效果

在这里插入图片描述

本人其他相关文章链接

1.《基础篇第1章:vue2简介》包含Vue2知识点、个人总结的使用注意点及碰到的问题总结

2.《基础篇第2章:vue2基础》包含Vue2知识点、个人总结的使用注意点及碰到的问题总结

3.《进阶篇第3章:vue进阶-组件》包含组件、自定义事件、插槽、路由等等扩展知识点

4.《基础篇第4章》:使用vue脚手架创建项目

5.vue2知识点:数据代理

6.vue2知识点:事件处理

7.vue2知识点:列表渲染(包含:v-for、key、取值范围、列表过滤、列表排序、vue监视对象或数组的数据改变原理、总结vue数据监测)

8.vue2知识点:计算属性与监听属性

9.vue2知识点:生命周期(包含:生命周期介绍、生命周期钩子、整体流程图详解)

10.vue2知识点:非单文件组件和单文件组件

11.vue2知识点:组件is属性

12.vue2知识点:组件模板定义

13.vue2知识点:组件的props属性、非props属性、props属性校验

14.vue2知识点:组件自定义事件

15.vue2知识点:组件插槽分发

16.vue2知识点:动态组件

17.vue2知识点:混入

18.vue2知识点:浏览器本地缓存

19.vue2知识点:全局事件总线(GlobalEventBus)

20.vue2知识点:消息订阅与发布

21.vue2知识点:nextTick语法

22.vue2知识点:Vue封装的过度与动画

23.vue2知识点:路由

24.vue2知识点:vm调用待$命令介绍

25.vue组件通信案例练习(包含:父子组件通信及平行组件通信)

26.vue表单案例练习:vue表单创建一行数据及删除数据的实现与理解

27.vue2基础组件通信案例练习:待办事项Todo-list案例练习

28.vue2基础组件通信案例练习:把案例Todo-list改写成本地缓存

29.vue2基础组件通信案例练习:把案例Todo-list改成使用自定义事件

30.vue2基础组件通信案例练习:把案例Todo-list改成使用全局事件总线

31.vue2基础组件通信案例练习:把案例Todo-list改成使用消息订阅与发布

32.vue2基础组件通信案例练习:把案例Todo-list新增编辑按钮

33.vue2基础组件通信案例练习:把案例Todo-list改成使用动画与过度

34.学习vue2遇到过的问题及个人总结

这篇关于《基础篇第2章:vue2基础》包含Vue2知识点、个人总结的使用注意点及碰到的问题总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/629680

相关文章

Java使用ANTLR4对Lua脚本语法校验详解

《Java使用ANTLR4对Lua脚本语法校验详解》ANTLR是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件,下面就跟随小编一起看看Java如何使用ANTLR4对Lua脚本... 目录什么是ANTLR?第一个例子ANTLR4 的工作流程Lua脚本语法校验准备一个Lua Gramm

Java Optional的使用技巧与最佳实践

《JavaOptional的使用技巧与最佳实践》在Java中,Optional是用于优雅处理null的容器类,其核心目标是显式提醒开发者处理空值场景,避免NullPointerExce... 目录一、Optional 的核心用途二、使用技巧与最佳实践三、常见误区与反模式四、替代方案与扩展五、总结在 Java

Android Mainline基础简介

《AndroidMainline基础简介》AndroidMainline是通过模块化更新Android核心组件的框架,可能提高安全性,本文给大家介绍AndroidMainline基础简介,感兴趣的朋... 目录关键要点什么是 android Mainline?Android Mainline 的工作原理关键

Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案

《Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案》:本文主要介绍Vue3组件中getCurrentInstance()获取App实例,但是返回nu... 目录vue3组件中getCurrentInstajavascriptnce()获取App实例,但是返回n

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析

Qt中QUndoView控件的具体使用

《Qt中QUndoView控件的具体使用》QUndoView是Qt框架中用于可视化显示QUndoStack内容的控件,本文主要介绍了Qt中QUndoView控件的具体使用,具有一定的参考价值,感兴趣的... 目录引言一、QUndoView 的用途二、工作原理三、 如何与 QUnDOStack 配合使用四、自

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

如何解决idea的Module:‘:app‘platform‘android-32‘not found.问题

《如何解决idea的Module:‘:app‘platform‘android-32‘notfound.问题》:本文主要介绍如何解决idea的Module:‘:app‘platform‘andr... 目录idea的Module:‘:app‘pwww.chinasem.cnlatform‘android-32

使用Python构建一个Hexo博客发布工具

《使用Python构建一个Hexo博客发布工具》虽然Hexo的命令行工具非常强大,但对于日常的博客撰写和发布过程,我总觉得缺少一个直观的图形界面来简化操作,下面我们就来看看如何使用Python构建一个... 目录引言Hexo博客系统简介设计需求技术选择代码实现主框架界面设计核心功能实现1. 发布文章2. 加

JS+HTML实现在线图片水印添加工具

《JS+HTML实现在线图片水印添加工具》在社交媒体和内容创作日益频繁的今天,如何保护原创内容、展示品牌身份成了一个不得不面对的问题,本文将实现一个完全基于HTML+CSS构建的现代化图片水印在线工具... 目录概述功能亮点使用方法技术解析延伸思考运行效果项目源码下载总结概述在社交媒体和内容创作日益频繁的