Vue.js学习笔记 01、Vue基本语法篇(下)
6、模板中使用条件判断(三元运算符与v-if)
两种方式:①三元运算符。②v-if
三元运算符—应用在筛选样式中
<head>
...
<style>
.one {
color: red;
}
.two {
color: blue;
}
</style>
</head>
<body>
<div id="app"></div>
</body>
<script src="https://unpkg.com/vue@next"></script>
<script>
const app = Vue.createApp({
data() {
return {
message: 'cls'
}
},
//配合:绑定指定的样式到class中
template: `
<span :class="message=='cl'?'one':'two'" >666</span>
`
}).mount("#app");
</script>
v-if应用—多种情况来判断
通过v-if
编写多条标签,根据是否符合条件来进行显示指定的标签,这样的话可以有更多的选择性:
<style>
.one {
color: red;
}
.two {
color: green;
}
.three {
color: orange;
}
</style>
<body>
<div id="app"></div>
</body>
<script src="https://unpkg.com/vue@next"></script>
<script>
const app = Vue.createApp({
data() {
return {
message: '技术胖'
}
},
//根据v-if来判断该标签是否显示
template: `
<h2 v-if="message=='jspang.com'" class="one" > {{message}} </h2>
<h2 v-if="message=='技术胖'" class="two"> {{message}} </h2>
<h2 v-if="message=='bilibili'" class="three"> {{message}} </h2>
`
}).mount("#app");
</script>
7、三大函数属性(methods、computed、watch)
7.1、计算属性computed(以及与methdos区别)
计算属性的特性是:当计算属性依赖的内容发生变更时,才会重新执行计算。
必备条件:必须要返回一个值,在页面渲染的同时就会执行里边的业务逻辑。
两者区别:
- 方法methods:只要页面重新渲染,就会重新执行方法。
- 计算属性computed: 当计算属性依赖的内容发生变更时,才会重新执行计算。
问题引出
当我们将一个方法函数写在methods中,一旦数据重新渲染就会重新执行methods中的所有方法!!!
后果:按理说对于methods方法全都重新执行是好事,数据能够进行实时刷新嘛,不过对于想要返回指定时间戳的函数同样也会跟随该机制重新计算得到新的时间戳!
<script src="https://unpkg.com/vue@next"></script>
<script>
const vm = Vue.createApp({
data() {
return {
message: '技术胖'
}
},
methods: {
getTotal() {
return Date.now()
}
},
template: `
<h2>{{message}}</h2>
<h2> {{getTotal}}</h2>
`
}).mount("#app");
</script>
我们刷新data对象中的message属性,就会带动methods中的方法重新执行:
避免上述时间戳重新获取:在
computed
对象属性中编写函数方法
计算属性computed
: 当计算属性依赖的内容发生变更时,才会重新执行计算。(不再是data对象中数据刷新就会执行一遍methods方法)
<script src="https://unpkg.com/vue@next"></script>
<script>
const vm = Vue.createApp({
data() {
return {
message: '技术胖'
}
},
//1、计算属性computed:与methods写法相同
computed: {
getTotal() {
return Date.now()
}
},
//2、执行computed计算属性中的方法不需要带有()
template: `
<h2>{{message}}</h2>
<h2> {{getTotal}}</h2>
`
}).mount("#app");
</script>
实际小例子:
<body>
<div id="app"></div>
</body>
<script src="https://unpkg.com/vue@next"></script>
<script>
const vm = Vue.createApp({
data() {
return {
price: 10,
count: 5
}
},
//将一些需要计算的函数放在计算属性computed属性里
//计算属性会帮助我们完成模板的自动更新
computed: {
total() {
return this.price * this.count
}
},
methods: {
addCount() {
this.count++;
}
},
template: `
<h2>total:{{total}}</h2>
<button @click="addCount">再买一个</button>
`
}).mount("#app");
</script>
7.2、侦听器/监听器(watch属性、与computed区别)
watch属性使用
watch
侦听器的作用就是侦听一个data中的值的变化,变化后可以写一个方法,让其进行一些操作(业务逻辑的编写)。
特征:
- watch属性(对象):内部编写函数,函数名对应要监听的属性。
- 函数包含两个参数:当监听的属性发生变化时触发,参数一是更改后的值,参数二为更改前的值。
示例:
<body>
<div id="app"></div>
</body>
<script src="https://unpkg.com/vue@next"></script>
<script>
const vm = Vue.createApp({
data() {
return {
price: 10,
count: 0
}
},
methods: {
addCount() {
this.count++;
}
},
//监听器属性watch
watch: {
//函数名对应的监听的指定data对象的值(这里指):count
//可以传入两个参数,参数一:现在值,参数二:变化前的值
count(current, prev) {
console.log('watch changed')
console.log('现在的值:', current)
console.log('变化前的值:', prev)
}
},
template: `
<h2>count:{{count}}</h2>
<button @click="addCount">再买一个</button>
`
}).mount("#app");
</script>
与computed属性区别
computed
:其中的函数必须要返回一个值,而且在页面渲染的同时就会执行里边的业务逻辑,也就是会先执行一遍你写的业务逻辑。
watch
:只有发生变化时才会执行,也就是说值没有变化,它是不执行里边业务逻辑的。
三者函数使用优先级
现在总结一下method、watch和computed三者如果都能实现相同的功能,它们之间的取舍和使用优先级。
computed
和method
都能实现的功能,建议使用computed
,因为有缓存,不用渲染页面就刷新。- computed中的函数必须有返回值!
computed
和watch
都能实现的功能,建议使用computed
,因为更加简洁。- watch属性中写的函数,其函数名为监控的属性!
建议最好使用computed
来实现一些计算的功能,对于其他属性更新变化时不会重新触发时间戳函数需要使用computed,否则每次都会更新其他数据时就会执行一遍methods里的方法。
最重要的就是能够理解这三者的区别:
methods
:可以写任意函数,一旦data对象中的数据更新就会全部执行一遍。computed
:函数必须有返回值,只有与函数中相关联的属性才会去执行指定函数。watch
:编写的函数名可以执行想要监控的属性,来进行一些监控操作等等。
9、v-show(控制dom元素是否清除,本质就是添加style=“display: none;”)
9.1、实际使用
用法:v-show
,传入一个布尔值。
true
:表示不对dom元素进行任何操作。false
:表示为改dom元素设置style="display: none;"
效果,直接就是清除该dom元素。
示例:
<body>
<div id="app"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
show: true,
}
},
//v-show:用于设置dom元素的显示与否,传入布尔值
//通过data对象中的show布尔值来进行控制dom元素的显示与不显示
template: `
<h2 v-show="show">JSPang.com</h2>
`
})
const vm = app.mount("#app")
</script>
9.2、v-show与v-if区别
v-if
:更加灵活,可以增加多个判断,比如v-else-iif
和else
,而v-show
不具备这样的灵活性。
- 效果:设置true为应用该dom元素,为false表示不应用该dom元素。
v-show
:
- 效果:设置为true不对该元素有任何影响,false就为该元素添加
style="display: none;"
,页面中不显示该dom元素。
推荐使用:如果显示和隐藏的状态切换比较频繁,并且没有什么多余复杂的业务逻辑,建议使用v-show
,因为他不会一直渲染你的页面DOM元素,这或多或少对性能和稳定性有点提升。反之可以使用v-if
。
10、v-for循环
10.1、遍历数组示例
遍历数组
<body>
<div id="app"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
listArray: ['谢大脚', '刘英', '晓红']
}
},
//遍历数组可获得值与索引(参数一、参数二)
template: `
<ul>
<li v-for="(item,index) in listArray">[{{index}}]{{item}}</li>
</ul>
`
})
const vm = app.mount("#app")
</script>
10.2、提升性能(循环中的key)
vue
中在进行列表渲染的时候,会默认遵守就地复用策略
- 复用策略:当在进行列表渲染的时候,vue会直接对已有的标签进行复用,不会将所有的标签全部重新删除和创建,只会重新渲染数据,然后再创建新的元素直到数据渲染完。(简而言之就是不会重新删除与创建标签,但是会将数据全部重新渲染)
为了提高循环时性能,在数组其中一项变化后,整个数组不进行全部重新渲染,Vue提供了绑定key
值的使用方法,目的就是增加渲染性能,避免重复渲染。
- 效果:不会去改变原有的元素和数据,而是创建新的元素然后把新的数据渲染进去。(简而言之仅仅会渲染新的数据或修改的数据)
对于key的值设置:不建议使用索引index
为key值,但此时又为了保持唯一性,所以这里使用了index+item
进行绑定key值。
<ul>
<li v-for="(item,index) in listArray" :key="index+item">
[{{index}}]{{item}}
</li>
</ul>
10.3、for循环遍历对象
v-for="(value,key,index) in listObject"
:可接收三个参数分别为值、键以及索引。
示例:
<body>
<div id="app"></div>
</body>
<script src="https://unpkg.com/vue@next"></script>
<script>
const app = Vue.createApp({
data() {
return {
//......
listObject: {
GirlOne: '谢大脚',
GirlTwo: '刘英',
GirlThree: '晓红'
}
}
},
//遍历对象
//v-for="(value,key,index) in listObject" => 参数1:值 参数2:键 参数三:键值对的索引位置
template: `
<ul>
<li v-for="(value,key,index) in listObject" :key="index+key">
[{{index}}]{{value}}-{{key}}
</li>
</ul>
`
})
const vm = app.mount("#app")
</script>
10.4、v-for注意点
10.4.1、允许循环数字
<li v-for="val in 100" :key="val">
{{val}}
</li>
10.4.2、v-for中如何使用v-if(两者不能嵌套在一个标签,引出template标签)
在v-for
中使用判断:不能直接在v-for的标签中使用v-if,这样是没有任何效果的。
简而言之:v-for与v-if不能同时在一个标签中使用!!!
第一种解决方案:在需要遍历的外部添加一个div标签,真正遍历在内部的li标签里(该标签里可以拿到外部标签遍历的值)
不推荐使用!!!有很大的弊端。
第二种解决方案:使用template
标签,就是将原本外层的div改成vue里的<template>
标签,就能够实现完美解决v-for
与v-if
的嵌套使用!
<body>
<div id="app"></div>
</body>
<script src="https://unpkg.com/vue@next"></script>
<script>
const app = Vue.createApp({
data() {
return {
listArray: ['谢大脚', '刘英', '晓红']
}
},
//使用template标签,该标签在vue中起到了虚拟标签的作用,最终该template不会显示出现
//效果:弥补了方案一中冗余嵌套的标签!!!
template: `
<ul>
<template v-for="(item,index) in listArray" :key="index+item">
<li v-if="item != '谢大脚'">
[{{index}}]{{item}}
</li>
</template>
</ul>
`
})
const vm = app.mount("#app")
</script>
11、绑定事件详解
11.1、方法和参数
11.1.1、绑定事件的两种形式(函数、表达式)
方式一:绑定事件函数
methods: {
addCountClick() {
this.count++;
},
},
template: `
<div>目前已点佳丽数量{{count}}.</div>
<button @click="addCountClick">增加一位佳丽</button>
`
方式二:表达式形式
//表达式形式(直接在表达式中书写js代码):@click="count++"
template: `
<div>目前已点佳丽数量{{count}}.</div>
<button @click="count++">增加一位佳丽</button>
`
11.1.2、在函数中获取event事件对象(无参与有参)
无参:直接拿到event对象
event.target使用
事件中的event
对象,实际测试event.target对象,使用target对象来统一处理相同的操作
<body>
<div id="app"></div>
</body>
<script src="https://unpkg.com/vue@next"></script>
<script>
const app = Vue.createApp({
data() {
return {
dataArr: ['cl', 'liner', 'linlin']
}
},
methods: {
//通过event.target获取源冒泡对象
delBtn(event) {
console.log(event.target);//dom对象
console.log(event.target.innerText);//dom对象
//删除指定元素通过标签中的id
this.dataArr.splice(event.target.innerText[2], 1);
}
},
//直接通过ul标签进行冒泡捕捉单击事件
template: `
<ul @click="delBtn" >
<li v-for='(val,item) in dataArr' :key='val+item'>
{{val}}
<button>删除{{item}}</button>
</li>
</ul>
`
});
const vm = app.mount("#app")
</script>
若是有一个或多个时,需要传入实参$event才会能获取到
函数多参数时如何获取event对象?
若是函数只有一个参数,将其设置为event
你就能够拿到对应的事件对象,但是若是有多个参数就需要你在调用时将$event
作为实参传入!
11.1.3、一个事件调用多个方法
下面演示点击事件绑定两个方法:直接在事件后面调用多个函数使用,
隔开
<body>
<div id="app"></div>
</body>
<script src="https://unpkg.com/vue@next"></script>
<script>
const app = Vue.createApp({
methods: {
handleBtnClick1() {
alert(1)
},
handleBtnClick2() {
alert(2)
},
},
//若是想让一个事件执行两个方法:直接在
template: `
<button @click="handleBtnClick1(),handleBtnClick2()">增加一位佳丽</button>
`
});
const vm = app.mount("#app")
</script>
11.2、六种事件修饰符
Vue
中的事件修饰符,分别是stop
,prevent
,capture
,self
,once
和passive
。
-
stop
:停止冒泡,如@click.stop=" addCountClick()"。 -
self
:只有点击自己内部内容才会生效,对于内部成对标签出现,都不属于自己的,属于是子元素。-
//第一个div中添加了self修饰符,但是由于内部全部都是div元素所以无论点哪里都不会生效(若是你设置外边框线很粗,点它的边框也是会生效的) template:` <div @click.self="handleBtnClick1"> <div>目前已点佳丽数量{{count}}.</div> <button @click=" addCountClick()">增加一位佳丽</button> </div> ` //此时我们为第一个div元素内部添加一段文字,我们点击该文字就会生效了!!! template:` <div @click.self="handleBtnClick1"> 我是最外层的DIV文字 <div>目前已点佳丽数量{{count}}.</div> <button @click=" addCountClick()">增加一位佳丽</button> </div> `
-
-
prevent
:阻止默然行为的修饰符,这个以前讲过,例如阻止form
表单的默认提交行为。 -
capture
:冒泡顺序发生改变,原本冒泡顺序是由内到外,改变之后就变为由外到内。 -
once
:事件只执行一次。 -
passive
:解决滚动时性能的修饰符。
可供测试模板:
<body>
<div id="app"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
count: 0
}
},
methods: {
addCountClick() {
this.count++;
alert(0)
},
handleBtnClick1() {
alert(1)
},
},
template: `
<div @click:capture="handleBtnClick1">
我是最外层的DIV文字
<div>目前已点佳丽数量{{count}}.</div>
<button @click=" addCountClick()">增加一位佳丽</button>
</div>
`
})
const vm = app.mount("#app")
</script>
11.3、键盘与鼠标修饰符
按键修饰符和
鼠标修饰符:使用使用特定的某个按键时才会用到
11.3.1、键盘修饰符(演示键盘事件以及单一按键事件)
keydown事件
<body>
<div id="app"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {}
},
methods: {
handleKeyDown() {
console.log('keydow....')
}
},
//keydown事件:能够响应键盘输入
template: `
<div>
<input @keydown="handleKeyDown"/>
</div>
`
})
const vm = app.mount("#app")
</script>
单个按键修饰符
单个按键修饰符:顾名思义,就是指定键盘上某个特殊的按键时才会响应事件方法。
各种单个按键修饰符提供如下
- e·nter 、tab、delete、esc、up 、down、left、right
11.3.2、鼠标修饰符(单个按键触发函数)
鼠标修饰符:按下鼠标上的某个键时,才会响应指定的函数方法。
- 最常用:
left
、right
、middle
<body>
<div id="app"></div>
</body>
<script src="https://unpkg.com/vue@next"></script>
<script>
const app = Vue.createApp({
data() {
return {}
},
methods: {
handleClick() {
alert('right click!')
}
},
//keydown事件:能够响应键盘输入
template: `
<div @click.right="handleClick">changluya</div>
`
})
const vm = app.mount("#app")
</script>
12、表单与数据绑定(双向数据绑定,使用v-model)
Vue3中表单和数据绑定的一些方法
双向数据绑定:data中的变量改变时,绑定的数据会跟随变化,此为一项修改;当通过页面修改数据,data中的变量也随之改变,这就是另一项修改。两个彼此依存改变。
12.1、input、textarea,checkbox,radio的双向绑定
input与textarea标签双向绑定:两者都是输入内容
v-model
:将输入的值传入到指定的data对象属性中
<body>
<div id="app"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
//model(数据)
message: ''
}
},
//view(模板)
//input、textarea标签:绑定v-model:监听输入的值传入到message中
template: `
<p>{{message}}</p>
<input type="text" v-model='message'>
<div><textarea v-model="message" /></div>
`
})
const vm = app.mount("#app")
</script>
checkbox:复选框(单个存储布尔值,多个存储value值)
若是只有一个选项:data中准备一个布尔值,选中表示为true,取消勾选为false。
data() {
return {
checked: false,
}
},
//view(模板)
//input、textarea标签:绑定v-model:监听输入的值传入到message中
template: `
<div>{{checked}}<input type="checkbox" v-model="checked" /></div>
`
若是有多个选项:data中准备一个空数组[],选中就会将value值push到绑定的元素中。
data() {
return {
girls: []
}
},
//view(模板)
//input、textarea标签:绑定v-model:监听输入的值传入到message中
template: `
<div>
{{girls}}
大脚<input type="checkbox" v-model="girls" value="大脚" />
刘英<input type="checkbox" v-model="girls" value="刘英" />
晓红<input type="checkbox" v-model="girls" value="晓红" />
</div>
`
radio:单选(存储到字符串中)
data() {
return {
//字符串来接收
girl: '',
}
},
template: `
<div>
{{girl}}
大脚<input type="radio" v-model="girl" value="大脚" />
刘英<input type="radio" v-model="girl" value="刘英" />
晓红<input type="radio" v-model="girl" value="晓红" />
</div>
`
解决单个checkbox返回布尔值情况(配合checkbox里的true-value和false-value)
使用的原因?为了解决多选框checkbox只有一个时返回true或false的问题,我们要的是真正对应多选框中的值而不是是否勾选的布尔值!
目的:通过使用v-model配合true-value和false-value来达到返回value到绑定的属性汇中去!
示例:
<body>
<div id="app"></div>
</body>
<script src="https://unpkg.com/vue@next"></script>
<script>
const app = Vue.createApp({
data() {
return {
name: '',
}
},
//checkbox多选框若是只有一个选项时,勾选与非勾选返回的是布尔值true或false
//如何让绑定的属性获取到值呢?通过添加两个修饰符true-value与false-value,设置指定的值之后就会根据是否勾选返回真正val到绑定的属性中去
template: `
<div>{{name}}
<input type="checkbox" v-model="name"
true-value="changlu"
false-value="liner"
/>
</div>
`
})
const vm = app.mount("#app")
</script>
12.2、v-model的修饰符(lazy、number、trim)
lazy修饰符
之前配合v-model进行双向绑定之后,输入任何内容的时候,插值表达式会跟着改变。
需求:就是我输入内容时并不立马显示,而是输入框失去焦点之后再显示,此时就可以使用到lazy修饰符了。
lazy
修饰符(懒更新修饰符):双向绑定的值并不会立即修改,只有当输入框失去焦点之后再进行改变值!
<body>
<div id="app"></div>
</body>
<script src="https://unpkg.com/vue@next"></script>
<script>
const app = Vue.createApp({
data() {
return {
message: '',
}
},
//为v-model设置lazy修饰符,实现输入框失去焦点之后才会更新数据
template: `
<div>
{{message}}<input v-model.lazy="message" />
</div>
`
})
const vm = app.mount("#app")
</script>
效果:不使用懒加载时我们是一输入就会进行数据更新,而使用了懒加载在失去焦点时才会进行更新。
number修饰符
当我们在input输入好内容之后,我们得到得到的value默认都是字符串,若是输入数字同样也是字符串。
需求:当我们输入非数字就是字符串,输入数字为number类型。
number
:此时我们就可以使用number修饰符了,你输入的值只要是数字,就变成了number类型,输入的是字母,它还会是字符串类型。
<body>
<div id="app"></div>
</body>
<script src="https://unpkg.com/vue@next"></script>
<script>
const app = Vue.createApp({
data() {
return {
message: '',
}
},
//为v-model设置lazy修饰符,实现输入框失去焦点之后才会更新数据
template: `
<div>
{{typeof message}}<input v-model.number="message" />
</div>
`
})
const vm = app.mount("#app")
</script>
trim修饰符:过滤掉左右两边的空格
不使用trim
修饰符时:输入空格正常也是会传入到data指定属性中
使用trim
修饰符后:绑定的data属性不会去接收空格
<body>
<div id="app"></div>
</body>
<script src="https://unpkg.com/vue@next"></script>
<script>
const app = Vue.createApp({
data() {
return {
message: '',
}
},
watch: {
message(cur) {
console.log(cur);
}
},
//为v-model后新增.trim修饰符
template: `
<div>
{{message}}<input v-model.trim="message" />
</div>
`
})
const vm = app.mount("#app")
</script>
我们最后使用拼接测试是否帮我们将左右两边的空格都过滤掉了:vm.$data.message+456
,最终确认确实是将左右两边的空格清楚了!!!
思考
1、关于删除事件直接删除一行
vue是数据驱动的,不直接操作dom元素,你要把dom元素想像成一个对象,然后对这个对象进行增加删除操作,vue会自动更新视图。
思路:一旦data对象中的listArray数组中删除了某个元素,在v-for中就会重新渲染该元素!!!
<body>
<div id="app"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
listArray: ['谢大脚', '刘英', '晓红']
}
},
methods: {
del(num) {
//直接对原数组操控即可达到渲染目的
this.listArray.splice(num, 1);
}
},
//遍历数组可获得值与索引(参数一、参数二)
template: `
<ul>
<li v-for="(item,index) in listArray" >[{{index}}]{{item}}
<button @click='del(index)'>删除</button>
</li>
</ul>
`
})
const vm = app.mount("#app")
</script>
- 点赞
- 收藏
- 关注作者
评论(0)