课程地址:【2021最新Vue从基础到实例高级_vue2_vuecli脚手架博客案例】 https://www.bilibili.com/video/BV1pz4y1S7bC/?share_source=copy_web&vd_source=b1cb921b73fe3808550eaf2224d1c155
目录
2 Vue基础 上
介绍 — Vue.js
2.0 补充知识
2.0.1 Vue实例的作用范围
举例:
<body>
<div id="app1">
<h1>{{ title }}</h1>
</div>
<div id="app2">
<em>{{ title }} </em>
</div>
</body>
</html>
<script>
let arr1 = new Vue({
el: '#app1',
data: {
title: 'Vue2学习'
}
})
</script>
结果
说明id为app2对应的div,不支持模板语法。
怎么让他可以支持呢?再实例化一个Vue对象,绑定app2。
这样就行了。
结论:
Vue对象的作用范围是他绑定的div范围。(我自己总结的,感觉这句话不好,词不达意)。
2.0.2 template标签
在<template>元素上使用v-if条件渲染分组。
template不会直接显示,只会作为一个标签,包裹其他元素。
案例。
要么显示今天是周几,要么显示今天天气怎么样。
代码如下。
<div class="outOut" v-if="true">
<div>今天是周1</div>
<div>今天是周2</div>
<div>今天是周3</div>
</div>
<div class="outOut" v-else>
<div>今天是晴天</div>
<div>今天是阴天</div>
</div>
结果
②外面还包了一层①。不想要①,层次太多了。
解决途径:使用template标签。
tips:template标签的类名不需要,写了也没用。
结果
template不显示。起到显示和隐藏的分组功能,最终不渲染到DOM体中。
2.1 条件渲染
介绍 — Vue.js
任何的程序语言都是有条件与循环的。Vue属于js的一部分。
2.1.1 v-if
1 v-if使用
v-if使用。
注意
- v-if直接放到DOM体里。
- v-if的值是 true 或 false.
- v-if可以嵌套v-if。
2 v-else使用
v-else使用。
只执行v-if或v-else。
注意:v-if和v-else需连在一起使用(空格,空行没问题),否则报错。(想象一下js的if和else语句中间掺杂其他代码,也是会报错的。)
<body>
<div class="out">
<h1 v-if="true">{{ title }}</h1>
<h1 v-else>{{ title + ': 今天又学习了'}}</h1>
</div>
</body>
</html>
<script>
new Vue({
el: '.out',
data: {
title: 'Vue2学习'
}
})
</script>
3 v-else-if
<div class="out">
<h1 v-if="false">{{ title }}</h1>
<h1 v-else-if="true">{{ title + ': 今天又学习了吗'}}</h1>
<h1 v-else>{{ title + ': 今天又学习了'}}</h1>
</div>
结果
4 变量控制
用一个变量为v-if/v-else-if赋值。直接v-if='isShow',然后isShow是个boolean类型。
5 练习
小tips:输入div{今天是周$}*8,生成以下。
要显示周三,怎么处理。
<body>
<div class="out">
<h1 v-if="isShow">{{ title }}</h1>
<h1 v-else-if="true">{{ title + ': 今天又学习了吗'}}</h1>
<h1 v-else>{{ title + ': 今天又学习了'}}</h1>
<div v-if="day === 1">今天是周1</div>
<div v-else-if="day === 2">今天是周2</div>
<div v-else-if="day === 3">今天是周3</div>
<div v-else-if="day === 4">今天是周4</div>
<div v-else-if="day === 5">今天是周5</div>
<div v-else-if="day === 6">今天是周6</div>
<div v-else-if="day === 7">今天是周7</div>
<div v-else>格式错误</div>
</div>
</body>
</html>
<script>
new Vue({
el: '.out',
data: {
title: 'Vue2学习',
isShow: true,
day: 3
}
})
</script>
结果
只显示周三。
(这里up用的JS条件判断来解释html的条件判断)。
2.1.2 v-show
v-if,所控制的对象要么渲染,要么在DOM体不存在。
v-show,所控制的对象实际存在,v-show实际控制元素的显示与否,对应元素的style的display为none。
v-show适合做一些按钮的切换、轮播器的切换。显示和隐藏用css,性能会好些。如果用v-if,相当于每次切换,DOM体都要重新渲染一次,性能上会大打折扣。
2.2 列表渲染
列表渲染v-for
效果
数组和对象,难看。
可以单独访问数组的元素,和对象的属性值。
<h2>{{ arr[0]}}</h2>
<h2>{{ obj.name}}</h2>
其中,对象也可以用数组访问元素的形式。obj.name是对象自己的访问形式。
<h2>{{ obj['name']}}</h2>
结果
没有问题。
但是希望能够只显示数组的元素,不显示中括号,可以使用v-for。
<div v-for="(item, index) in arr">
{{ item + ',' }}
</div>
效果
对象也是同理
<div v-for="(item, index) in obj">
{{ item + ',' }}
</div>
效果
2.3 模板语法
2.3.1 v-text指令
data渲染到页面上,除了使用模板语法{{xxx}}的方式,还可以使用v-text指令。
效果
两个用法的效果是一样的。
2.3.2 v-html指令
对于字符串中有html标签的情况,使用 模板语法 和 v-text指令 都不能正常显示。
结果
bilibili应该是斜体,且em标签不应该展示出来。
使用v-html指令
<body>
<div id="app">
<h1>{{ title}}</h1>
<h1 v-text="title"></h1>
<h2>{{ job }}</h2>
<h2 v-text="job"></h2>
<h2 v-html="job"></h2>
</div>
</body>
效果
还可以给字符串添加样式
<script>
let arr1 = new Vue({
el: '#app',
data: {
title: 'Vue2学习',
job: '<em style="font-size: 50px">bilibili</em>大学'
}
})
</script>
效果
这跟jQuery差不多(不看了,没看到有用jQuery的)。
2.3.3 v-bind指令
举例
<body>
<div id="app">
<!-- title表示鼠标移上去显示的内容 -->
<h3 title="软件大道">软件大道</h3>
</div>
</body>
效果
鼠标移到“软件大道”上,会显示软件大道。(但是截不出图)
使用v-bind指令。
使用v-bind指令,绑定h3标签的title属性。
<body>
<div id="app">
<!-- title表示鼠标移上去显示的内容 -->
<h3 title="软件大道" v-bind:title="address">软件大道</h3>
</div>
</body>
除了title,不同标签还有其他很多属性。这里就不显示了。
v-bind的缩写
v-bind 可以缩写为 (空) 。
案例
<img :src="picLink" alt="">
效果
2.4 事件处理
2.4.1 v-on指令
v-on指令,就是事件指令。比如js的onClick等事件。
希望点击文字可以切换内容。
举例
给h1标签,绑定点击事件,事件处理函数里会改变h1标题的显示内容。
<body>
<div id="app">
<h1 v-text="title" v-on:click="changeText"></h1>
</div>
</body>
</html>
<script>
let arr1 = new Vue({
el: '#app',
data: {
title: 'Vue2学习',
address: '雨花台图书馆'
},
methods: {
changeText() {
this.title = '雨花台区图书馆'
}
}
})
</script>
效果
初始会显示
点击这行文本,显示其他内容。
v-on: 缩写为 @(注意这里连冒号都要省略)
<h1 v-text="title" @click="changeText"></h1>
效果还是一样的。
为轮播图做准备的案例。
<body>
<div id="app">
<!-- 一共有3张照片 -->
<button @click="subtract">-</button>
<button @click="add">+</button>
<h1>{{ number}}</h1>
<img :src="'img/vue' + number + '.jpg'" alt="">
</div>
</body>
</html>
<script>
let arr1 = new Vue({
el: '#app',
data: {
title: 'Vue2学习',
number: 0,
prcLink: 'img/vue0.jpg'
},
methods: {
changeText() {
this.title = '雨花台区图书馆'
},
add() {
this.number++;
if (this.number > 2) {
this.number = 0;
}
},
subtract() {
this.number--;
if (this.number < 0) {
this.number = 2;
}
}
}
})
</script>
2.4.2 事件处理方法
事件处理方法的参数是原生的事件event。
2.4.3 内联处理器中的方法
在html中使用标签时,直接给他的事件处理方法传递一个参数。
这样对应的事件处理方法的参数就是html中传递的参数。
vue2官网文档的知识。
在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event
把它传入方法。
2.4.4 事件修饰符
在事件处理程序中调用 event.preventDefault()
或 event.stopPropagation()
是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。
为了解决这个问题,Vue.js 为 v-on
提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。
.stop
.prevent
.capture
.self
.once
.passive
1 stop
阻止单击事件的继续传播(阻止事件冒泡)。
冒泡事件:如果有一个div,里面还有一个div,且两个div都绑定了点击事件。那么点击里面的div,会触发里面div的点击事件,同时也会触发外面div的点击事件。这就是事件冒泡。场景:多个广告嵌套,点击里面的广告,可能也会触发外面广告的跳转。应该阻止跳转到外部广告,因此可以用stop修饰符。
使用,见上述代码片段。
2 prevent
阻止默认事件。
比如阻止提交按钮点击后的跳转动作。
案例
点击提交按钮后,不会直接提交。
先去执行提交方法,如果满足onSubmit方法,那么会跳转href指定的地址。
如果没有满足,那么不会跳转到预定的地址。
其他的修饰符就不介绍了。
2.4.5 按键修饰符
@keyup.enter=“事件处理方法名”
按下回车键。场景:没有搜索按钮的提交表单场景,按下回车提交表单。
其他还有tab、esc、left键等。
2.4.0 案例-轮播
实现一个轮播图效果。
要等进群拿资料再做这个。
2.5 表单输入绑定
准备一个form表单。
2.5.1 v-model指令
v-model,数据双向绑定。让输入框的内容和data数据保持同步。
使用v-bind绑定数据,单向绑定。
<body>
<div id="app">
<form action="">
<input type="text" :value="val">
<h1>{{ val}}</h1>
</form>
</div>
</body>
</html>
<script>
let arr1 = new Vue({
el: '#app',
data: {
val: '123'
}
})
</script>
效果
改变input框内的内容,input绑定的val值不会发生变化。
v-bind,实现data中的数据控制input框内的内容。
这里,up用v-bind和input绑定点击事件的两种方式合用,来实现数据的双向绑定,即data中的数据变化,可以引起input框的内容的同步变化;input框内容的变化,引起data中的数据的同步变化。
这里就不记笔记了,直接看最终的v-model实现。
使用v-model实现数据的双向绑定。
<form action="">
<input type="text" v-model:value="val">
<h1>{{ val}}</h1>
</form>
效果
2.5.2 v-model简写
如果v-model绑定的是标签的value属性,那么v-model:value='变量名',可以简写为v-model='变量名',即 :value被省略掉了。
案例。
<form action="">
<input type="text" v-model="val">
<h1>{{ val}}</h1>
</form>
2.5.3 表单组件
1 单行文本
标签:input,type属性:text
2 多行文本
标签:input,type属性:textarea
3 复选框
复选框,标签:input, type: checkbox。
是否同意用户协议。
<body>
<div id="app">
<form action="">
<input type="text" v-model="val">
<h1>{{ val}}</h1>
<hr>
<input type="checkbox" v-model="checked">是否同意用户协议
<h1>{{ checked}}</h1>
</form>
</div>
</body>
</html>
<script>
let arr1 = new Vue({
el: '#app',
data: {
val: '123',
checked: false
}
})
</script>
小tips:点击文字也可以让多选框被选中。
步骤1:给input加个id;
步骤2:给需要处理的文本外面包裹一个label标签;
步骤3:label的for属性值与步骤1加个id名一致。
<input type="checkbox" v-model="checked" id="myChecked"><label for="myChecked">是否同意用户协议</label>
方法2:
直接在原来多选框元素的外层包裹一个label标签。
<label>
<input type="checkbox" v-model="checked">是否同意用户协议
</label>
效果与方法1是一样的。
最终效果
默认是个false,且多选框未选择。
当选择多选框时,下面的值(多选框的value属性值)为false
4 多个复选框
内容多的复选框,数据用一个数组来保存。
案例。
<body>
<div id="app">
<form action="">
南京:
<label><input type="checkbox" value="yuhuatai" v-model="checkArr">雨花台区</label>
<label><input type="checkbox" value="jiangning" v-model="checkArr">江宁区</label>
<label><input type="checkbox" value="jianye" v-model="checkArr">建邺区</label>
<h1>{{ checkArr }}</h1>
</form>
</div>
</body>
</html>
<script>
let arr1 = new Vue({
el: '#app',
data: {
checkArr: ['yuhuatai'],
}
})
</script>
解释:
效果
初始显示
用户选择其他地区时显示
5 单选按钮
单选按钮,标签:input,type属性:radio。就不演示了。
6 下拉框
标签:select。
单选下拉框。
案例
<body>
<div id="app">
<form action="">
<select v-model="selected">
<option value="xuanwuhu">玄武湖</option>
<option value="hongshanzoo">红山动物园</option>
<option value="tangshan">汤山风景区</option>
</select>
<h1>{{ selected}} </h1>
</form>
</div>
</body>
</html>
<script>
let arr1 = new Vue({
el: '#app',
data: {
selected: ''
}
})
</script>
效果
初始什么都没有
点开下拉框,选择玄武湖
多选下拉框。在组件里介绍。
2.5.4 修饰符
修饰符有很多,.trim比较重要。
如果要自动过滤用户输入的首尾空白字符,可以给 v-model
添加 trim
修饰符。
这里就不演示了。
2.6 class 与 style绑定
适用于选中区域高亮的情况。
2.6.1 style绑定
行内样式style。
回忆下正常的行内样式书写方式。
<div style="width: 100px; height: 200px; background-color: red"></div>
实现style绑定。
可以发现,正常的行内样式写法,与style绑定的行内样式写法还是有一定差别的。要在理解的基础上记住。
其他还有数组格式等,这里就不介绍了。
2.6.2 class绑定
一般用class绑定的多一些,style绑定比较少。
点击“切换样式”按钮时,div样式变化,背景色由蓝色变为粉色。
<body>
<div id="app">
<button @click="changeClass">切换样式</button>
<div :class="{'out': true, 'newOut': isShow}"></div>
</div>
</body>
</html>
<script>
let arr1 = new Vue({
el: '#app',
data: {
isShow: false
},
methods: {
changeClass() {
this.isShow = !this.isShow;
console.log(this.isShow);
}
}
})
</script>
<style>
#app {
.out {
width: 200px;
height: 300px;
background-color: skyblue;
&.newOut {
background-color: plum;
}
}
}
</style>
效果
点击按钮
注意:
class命名,如果class用短横线连接的方式命名,
此时,绑定class方式的写法有2种
1、要绑定的class类名改为大驼峰式写法
2、改用单引号''括起来
注意:
① 左边的out类,加不加单引号都可以。
② 方式1newOut写法不能加单引号,方式2new-out写法必须加单引号。
总结:一般就是用上面的写法,当然也有其他的写法(对象语法,数组语法),这里没有必要去掌握。
2.7 案例
两个案例的并集覆盖了2.1-2.6的知识点。目前来看掌握情况还是可以的。难点在下一部分。
2.7.1 高亮显示案例
学完以上知识,现在做一个小案例。
涉及动态绑定class,事件处理,列表渲染,模板语法。
让三个div块在鼠标点击的时候高亮显示。
代码
<body>
<div id="app">
<div class="box" :class="{active: num===index}" v-for="(item, index) in listArr" @click="clickBox(index)">{{
item}}</div>
</div>
</body>
</html>
<script>
let arr1 = new Vue({
el: '#app',
data: {
listArr: [
"玄武湖",
"鸡鸣寺",
"紫金山"
],
num: 0
},
methods: {
clickBox(e) {
console.log(e);
this.num = e;
}
}
})
</script>
<style>
.box {
width: 200px;
height: 30px;
background-color: #ccc;
margin-bottom: 10px;
&.active {
background-color: orange;
}
}
</style>
效果
判断条件就是让记录点击的num与静态的index进行判断,相等的话就绑定高亮的样式。
2.7.2 评论模块的增与删
做一个评论模块。
老师不讲样式,我来自己实现下。
1 样式
我自己实现的。
1 阴影实现的不对(懒得改了,看up的)
2 尺寸不对(也没有高保图)
3 颜色不对(没有高保图)
我觉得还是不错的,给自己点赞。
我的代码
<body>
<div id="app">
<!-- 输入部分 -->
<div class="inputComment">
<div class="inputCommentPart">
<input type="text" class="inputCommentInput">
</div>
<div class="sendCommentPart">评论
</div>
</div>
<!-- 展示部分 -->
<div class="showComment">
<div class="comment" v-for="(item, index) in commentList">
{{ item }}
</div>
</div>
<!-- 统计部分 -->
<div class="totals">
<div v-if="num > 0" class="commentTotals">
共{{num}}条评论
</div>
<div v-else class="noData">
暂无评论
</div>
</div>
</div>
</body>
</html>
<script>
let arr1 = new Vue({
el: '#app',
data: {
commentList: [
'这是一条评论',
'这也是一条评论'
],
num: 2
}
})
</script>
<style>
#app {
width: 500px;
height: 250px;
background-color: #fff;
margin: 50px auto;
padding: 0 20px;
box-shadow: 10px 10px 10px 0 rgba(0, 0, 0, 0.09);
box-shadow: -10px -10px 10px 0 rgba(0, 0, 0, 0.09);
box-sizing: border-box;
/* 涉及外边距塌陷,可以去看3、盒子模型 */
overflow: hidden;
.inputComment {
width: 400px;
height: 50px;
margin: 20px auto;
display: flex;
.inputCommentPart {
width: 320px;
.inputCommentInput {
background-color: #ccc;
width: 320px;
height: 50px;
border: 0px;
padding: 0;
}
}
.sendCommentPart {
flex: 1;
background-color: green;
color: #fff;
font-size: 20px;
line-height: 50px;
text-align: center;
}
}
.showComment {
border-top: 2px solid #ccc;
.comment {
color: #444;
font-size: 18px;
padding: 10px;
border-bottom: 2px solid #ccc;
}
}
.totals {
color: #444;
font-size: 12px;
margin: 20px auto;
text-align: center;
}
}
</style>
看老师的。
阴影。四处发阴影,x和y偏移量设置为0。
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
还漏了一个动态效果。鼠标移到评论上的时候,显示删除按钮。
实现
html没什么好说的,就一个div块。
样式
其他的样式差的不是很大,就不改了。
2 功能分析
我自己做哈
- 输入评论,点击评论按钮,可以展示到下面的评论列表中;
- 当没有评论时,最下面显示“暂无评论”;
- 点击评论右边的×,可以删除该条评论;
- 不可提交空内容。
以上就是我想到的。
3 逻辑实现
我的实现
感觉做的还可以,其实没想象的那么难。
贴个代码。
<body>
<div id="app">
<!-- 输入部分 -->
<div class="inputComment">
<div class="inputCommentPart">
<input type="text" class="inputCommentInput" v-model="commentInputting"
@keyup.enter="addComment">{{commentInputting}}
</div>
<div class="sendCommentPart" @click="addComment">评论
</div>
</div>
<!-- 展示部分 -->
<div class="showComment">
<div class="comment" v-for="(item, index) in commentList">
{{ item }}
<div class="close" @click="deleteComment(index)">×
</div>
</div>
</div>
<!-- 统计部分 -->
<div class="totals">
<div v-if="commentList.length > 0" class="commentTotals">
共{{commentList.length}}条评论
</div>
<div v-else class="noData">
暂无评论
</div>
</div>
</div>
</body>
</html>
<script>
let arr1 = new Vue({
el: '#app',
data: {
commentList: [
],
commentInputting: ''
},
methods: {
addComment() {
console.log(this.commentInputting);
if (this.commentInputting) {
this.commentList.unshift(this.commentInputting);
this.commentInputting = '';
}
},
deleteComment(index) {
this.commentList.splice(index, 1);
}
}
})
</script>
看看老师的
老师的跟我的一致,不用看了。
用到了v-model数据双向绑定(表单输入绑定)、列表渲染、条件渲染、模板语法、事件处理。(就class绑定没有涉及)。
总结:(不是很熟的知识点)
1、数组任意位置删除元素,splice
2、数组在前面增加元素,unshift
3、回车触发事件,@keyup.enter="绑定的事件名"