课程地址:【2021最新Vue从基础到实例高级_vue2_vuecli脚手架博客案例】 https://www.bilibili.com/video/BV1pz4y1S7bC/?share_source=copy_web&vd_source=b1cb921b73fe3808550eaf2224d1c155
目录
2 Vue基础 上
2.0 补充知识
2.0.1 Vue实例的作用范围
2.0.2 template标签
2.1 条件渲染
2.1.1 v-if
1 v-if使用
2 v-else使用
3 v-else-if
4 变量控制
5 练习
2.1.2 v-show
2.2 列表渲染
2.3 模板语法
2.3.1 v-text指令
2.3.2 v-html指令
2.3.3 v-bind指令
2.4 事件处理
2.4.1 v-on指令
2.4.2 事件处理方法
2.4.3 内联处理器中的方法
2.4.4 事件修饰符
1 stop
2 prevent
2.4.5 按键修饰符
2.4.0 案例-轮播
2.5 表单输入绑定
2.5.1 v-model指令
2.5.2 v-model简写
2.5.3 表单组件
1 单行文本
2 多行文本
3 复选框
4 多个复选框
5 单选按钮
6 下拉框
2.5.4 修饰符
2.6 class 与 style绑定
2.6.1 style绑定
2.6.2 class绑定
2.7 案例
2.7.1 高亮显示案例
2.7.2 评论模块的增与删
1 样式
2 功能分析
3 逻辑实现
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的条件判断)。
补充:Date对象
new Date().getDay() 获取当前时间是周几。
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指令。
v-if和v-for都是指令。
v-就是指令的前缀。
效果
两个用法的效果是一样的。
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
指令可以用于响应式地更新 HTML attribute。
使用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指定的地址。
如果没有满足,那么不会跳转到预定的地址。
奇怪,不给form的action属性赋值,点击提交按钮也不会提交。
感觉直接用点击事件处理,点击事件处理方法里加判断就行。
p17没看明白。
其他的修饰符就不介绍了。
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绑定比较少。
class设置不会覆盖,只会追加,比如out样式再加newOut样式,会有2个样式,不会出现只有newOut样式的情况。
点击“切换样式”按钮时,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,事件处理,列表渲染,模板语法。
快速生成多个带class的div。.box{}*4,生成4个class为box的div。
让三个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="绑定的事件名"