想利用暑假时间好好学习一下vue,会记录每一天的学习内容。
今天是学习vue的第2
天!
起起伏伏乃人生常态,继续加油~
学习内容
- 1. v-bind 使用
- 简单使用v-bind
- v-bind语法糖
- v-bind动态绑定class对象语法
- v-bind动态绑定class数组语法
- v-bind绑定style
- 2.计算属性
- 计算属性基本使用
- 计算属性的getter和setter
- 计算属性的缓存
- computed与methods的对比
- 3. v-on事件监听
- v-on的基本使用
- v-on参数
- v-on修饰符
- 4. v-if、v-else-if、v-else
- 5. 登陆切换小案例
- input复用问题
- 6. v-show
- v-if和v-show对比
1. v-bind 使用
- 前面我们学习的指令主要是:将值插入到我们
模版的内容
当中 - 但是,除了内容需要动态决定之外,某些
属性
我们也希望动态来绑定- 比如动态绑定
a
元素的href
属性 - 比如动态绑定
img
元素的src
属性
- 比如动态绑定
- 这时,我们可以使用
v-bind
指令- 作用:
动态绑定属性
- 缩写:
:
- 作用:
v-bind用于动态地绑定一个或多个 attribute,或一个组件 prop 到表达式。
简单使用v-bind
给哪个属性动态绑定值,就在它前面加上v-bind
,加了v-bind
才会把该属性的值当成一个变量,在vue
实例中找对应的变量值
v-bind语法糖
缩写::
<!-- 语法糖写法 -->
<img :src="imgURL" alt="" srcset="">
<a :href="aHref">百度</a>
v-bind动态绑定class对象语法
有下面这些用法:
- 直接通过
{}
绑定一个类
<!-- isActive是个布尔值 -->
<h2 :class="{active: isActive}">{{message}}</h2>
- 也可以绑定多个类
<h2 :class="{active: isActive, line: isLine}">{{message}}</h2>
- 可以跟普通的类同时存在,并不冲突
<!-- 若isActive和isLine为true,则h2有title,active,line三个类 -->
<h2 class="title" :class="{active: isActive, line: isLine}">{{message}}</h2>
- 如果
{}
中内容过多,可以放在一个methods
或computed
中
<h2 :class="getClasses()">{{message}}</h2>
data: {
isActive: true,
isLine: true
},
methods: {
getClasses: function() {
// 注意this!
return {active: this.isActive, line: this.isLine}
}
}
v-bind动态绑定class数组语法
- 绑定,非动态类
<h2 :class="['active']">{{message}}</h2>
加了引号会被当成字符串解析,本质上等同于:
<h2 class="active" >{{message}}</h2>
- 绑定动态类
<h2 :class="[active]">{{message}}</h2>
data: {
active: 'red'
}
不加引号,被当成变量处理,则可在vue
实例中动态修改类
- 同样可跟普通类同时存在,过于复杂可放在
methods
或computed
中
v-bind绑定style
我们可以利用v-bind:style
来绑定一些CSS内联样式
有两种语法:
- 对象语法:(掌握)
<h2 :style="{key(属性名): value(属性值)}">{{message}}</h2>
<!-- 注意-->
<!-- 50px必须加单引号,如果不加单引号,会被当成变量处理,会去vue实例中寻找这个变量 -->
<!-- 但50px不是动态可修改的值,意义不大 -->
<h2 :style="{fontSize: '50px'}">{{message}}</h2>
<!-- 注意加单位-->
<h2 :style="{fontSize: finalSize + 'px', color: finalColor}">{{message}}</h2>
data: {
message: 'hello vue',
finalSize: 100,
finalColor: 'red'
},
- 数组语法:(了解)
数组中多个值之间用,
分隔即可
<h2 :style="[styleObjectA, styleObjectB]"></div>
data: {
styleObjectA: {fontSize: '100px'}
styleObjectB: {color: 'red'}
}
2.计算属性
- 在模版中,可以直接通过插值语法显示一些
data
中的数据,但是某些情况下可能需要对数据进行一些转换后再显示,或者需要将多个数据结合起来显示- 比如有
firstName
和lastName
两个变量,需要显示完整的名称fullName
- 如果多个地方都需要显示
fullName
,就要写多遍{{firstName}} {{lastName}}
- 可以将其换成
计算属性
,写在vue
实例的computed
选项中
- 比如有
计算属性基本使用
<!-- 计算属性不需要加小括号 -->
<h2>{{fullName}}</h2>
data: {
firstName: 'poem',
lastName: 'AI',
},
computed: {
fullName: function () {
return this.firstName + " " + this.lastName
}
},
methods: {
// 与上面的计算属性fullName一个效果
getFullName: function() {
return this.firstName + " " + this.lastName
}
}
<div id="app">
<h2>总价格:{{totalPrice}}</h2>
</div>
data: {
books:[
{name: 'book1', price: 100},
{name: 'book2', price: 120},
{name: 'book3', price: 150},
]
},
computed: {
totalPrice: function () {
let result = 0;
for(let i in this.books) {
result += this.books[i].price
}
return result;
}
},
计算属性的getter和setter
每个计算属性都包含一个getter
和一个setter
(完整写法),在上面的例子中,我们只是使用getter
来读取。某些情况下,也可以提供一个setter
方法(不常用)
computed: {
// 是已省略过的写法
fullName: function() {
return this.firstName + " " + this.lastName
}
fullName: {
// 但也可以写set方法
set: function(newValue) {
console.log("----调用了fullName的set")
// get方法中的firstName和lastName也会想应该改变
const name = newValue.split(" "); // 分割firstName和lastName
this.firstName = name[0];
this.lastName = name[1];
},
// 一般只有get方法,所以省略为上面的写法
get: function () {
console.log("----调用了fullName的get")
return this.firstName + " " + this.lastName;
}
}
}
计算属性的缓存
methods
和computed
看起来都可以实现我们的功能,为什么要多一个计算属性呢?
原因:计算属性会进行缓存,如果进行多次使用,计算属性只会调用一次
computed与methods的对比
<!-- 通过computed -->
<h2>{{fullName}}</h2>
<h2>{{fullName}}</h2>
<h2>{{fullName}}</h2>
<h2>{{fullName}}</h2>
<!-- 通过定义methods -->
<h2>{{getFullName()}}</h2>
<h2>{{getFullName()}}</h2>
<h2>{{getFullName()}}</h2>
<h2>{{getFullName()}}</h2>
methods: {
getFullName: function () {
console.log('getFullName');
return this.firstName + " " + this.lastName
}
},
computed: {
fullName: function () {
console.log('fullName');
return this.firstName + " " + this.lastName
}
}
可以看到控制台中,methods
调用了4次,computed
只调用了1次
3. v-on事件监听
在vue
中监听事件,使用v-on
指令
v-on
:
- 作用:绑定事件监听器
- 缩写:
@
- 参数:
event
v-on的基本使用
v-on参数
通过methods
中定义方法,以供@click
调用时,需要注意参数问题
- 情况1:如果该方法不需要额外参数,那么方法后的
()
可以不添加(如上例)- 但是⚠️:如果方法本身中有一个参数,那么会默认将浏览器产生的
event
时间对象作为参数传递进方法
- 但是⚠️:如果方法本身中有一个参数,那么会默认将浏览器产生的
<!-- 事件调用的方法无参数,加不加括号都ok -->
<button @click="btn1Click">按钮1</button>
<button @click="btn1Click()">按钮1</button>
<!-- 事件定义时,写函数时省略了小括号,但方法本身是需要一个参数的 -->
<!-- 此时vue会默认将浏览器产生的event事件对象作为参数传入到方法中-->
<button @click="btn2Click">按钮2</button>
methods: {
btn1Click() {
console.log("btn1Click");
},
btn2Click(event) {
console.log("btn2", event);
}
}
- 情况2:如果需要同时传入某个参数,同时需要
event
时,可以通过$event
传入事件
<!-- 方法定义时,我们需要event对象,又需要其他参数 -->
<!-- 在调用方式时,手动获取到浏览器参数的event对象:$event -->
<button @click="btn3Click(111,$event)">按钮3</button>
methods: {
btn3Click(param,event) {
console.log("btn3", param, event);
}
}
v-on修饰符
拿到event
的目的是可能进行一些事件处理
vue
提供修饰符来帮助我们更方便地处理一些事件:
.stop
:调用event.stopPropagation()
<!-- 停止冒泡 -->
<button @click.stop="btnClick">按钮</button>
.prevent
:调用event.preventDefault()
<form action="baidu">
<!-- 停止默认行为 -->
<input type="submit" value="提交" @click.prevent="submitClick">
</form>
.{keyCode | keyAlias}
<!-- 监听回车键的按下 -->
<!-- 键修饰符,键别名 -->
<input @keyup.enter="onEnter">
<!-- 键修饰符,键代码 -->
<input @keyup.13="onEnter">
.native
:监听组件根元素的原生事件
<!-- 组件中的原生事件 -->
<my-component @click.native="onClick"></my-component>
.once
:只触发一次回调
<!-- 点击回调只触发一次 -->
<button @click.once="btnClick">按钮</button>
4. v-if、v-else-if、v-else
这三个指令与if
、else if
、else
类似
简单使用
<!-- 较复杂的逻辑不建议写在这,可以写在computed里,此处为了演示-->
<h2 v-if="score>=90">优秀</h2>
<h2 v-else-if="score>=80">良好</h2>
<h2 v-else-if="score>=60">及格</h2>
<h2 v-else>不及格</h2>
v-if
:其后条件为false
时,对应的元素及其子元素不会渲染
5. 登陆切换小案例
- 用户登录时,可以切换使用用户账号登录/邮箱登录
- 类似于以下场景:
input复用问题
- 在输入框有内容的情况下,切换了类型,我们会发现文字仍然显示之前输入的内容
- 但是我们应该切换到另一个
input
元素中了,另一个input
元素中,我们并没有输入内容。为什么会出现这个问题呢?
问题解答
:
- 因为
Vue
在进行DOM渲染
时,出于性能考虑,会尽可能地复用已经存在的元素,而不是重新创建新的元素。 - 在上例中,
Vue
内部会发现原来的input
元素不再使用,就直接作为else
中的input
来使用了
解决方案
:
- 如果不希望
Vue
出现类似重复利用的问题,可以给对应的input
添加key
- 并且需要保证
key的不同
<input type="text" placeholder="用户账号" key="username">
<input type="text" placeholder="用户邮箱" key="email">
6. v-show
v-show
和v-if
用法相似,
也用于决定一个元素是否渲染
v-if和v-show对比
v-if
当条件为false
时,不会有相应的元素在DOM
中v-show
当条件为false
时,只是给元素添加了一个行内样式:display: none
(根据表达式之真假值,切换元素的display
CSS属性)
开发时如何选择?
- 当需要在显示与隐藏之间切换很频繁时,选择
v-show
- 当只有一次切换时,选择
v-if
测试:
<h2 v-show="isShow" id="show1">{{message}}</h2>
<h2 v-if="isShow" id="if1">{{message}}</h2>
data: {
message: 'hello vue',
isShow: 'true'
},
控制台切换:
可以看到后接表达式为false
时,v-show
相应的元素在DOM
中,v-if
相应的元素压根不在DOM
中