二、指令的概念和分类
1、什么vue指令
vue指令是一种以v-开头的特殊性属性,每一种指令它都写在元素的开始部分,每一种指令都有着自己的具体的功能,功能涉及到内容渲染、条件判断、列表渲染、表单内容的收集、事件绑定等等。
2、vue指令的分类
-
内容渲染指令:v-text、v-html
-
条件判断指令:v-if、v-elseif、v-else、v-show
-
事件绑定指令:v-on
-
属性绑定指令:v-bind
-
列表渲染指令:v-for
-
双向绑定指令:v-model
-
其他指令:v-slot、v-once、v-cloak
三、内容渲染指令
在vue中如果要进行内容渲染,一共三种方式
-
通过插值表达式进行内容渲染
-
通过v-text进行内容渲染:其实它的作用就相当于innerText,它有一个缺点会覆盖标签文本内容
-
通过v-html进行内容渲染:其实它的作用就相当于innerHTML,他会解析HTML5的标签的
-
缺点1:会覆盖标签之间的内容
-
缺点2:会造成XSS网络攻击,给黑客攻击网站带来了隐患
<template> <div> <div>姓名:{{name}}</div> <div v-text="englishName">英文名</div> 网址:<span v-html="url"></span> 头像:<div v-html="headerImg"></div> </div></template><script>export default { data(){ return{ name:'翟吉喆', englishName:'Giles', url:'<a href="http://www.zhaijizhe.cn/first">个人主页</a>', headerImg:'<img src="https://woniuimage.oss-cn-hangzhou.aliyuncs.com/woniuimage/teacher/20220222.png">' } }}</script>
四、vue-devtools工具的使用
vue-devtools是一款基于chrome浏览器的扩展插件,用于vue的调试的,使用它可以让我们在vue调试过程带来巨大的便利
安装vue-devtools的步骤
-
全局安装vue-devtools
npm i -g vue-devtools
-
安装完之后,查看全局安装是否已经完成
npm list -g
通过查看然后找到全局安装的路径C:\Users\giles\AppData\Roaming\npm\node_modules\vue-devtools\vender
-
打开开发者设置
浏览器设置>可扩展程序,将右上角的打开开发者模式开关按钮打开
-
加载已经解压的扩展程序
-
调试和使用
五、条件判断指令
根据条件的真假进行渲染
分为如下两种
-
v-if系列:实际上是在构建虚拟DOM的时候根据条件是否成立而后才创建真实DOM元素,如果条件不成立则要删除元素,如果频繁进行显示与删除会带来巨大的性能消耗
-
v-show:当条件成立则显示,如果条件为false,则是通过对css样式的控制来隐藏元素
v-if和v-show的区别
-
语法不同,v-if的切换频繁的时候不建议使用,因为它的创建和删除所带来性能开销较大,v-show是通过隐藏元素来实现显示或隐藏的,一般情况下,尽量建议大家使用v-show
-
v-if和v-elseif和v-else更多的是完成逻辑方面的判断
六、事件绑定指令
在vue中使用v-on这个指令来进行事件的绑定
案例:计数器的操作
1、基本使用的语法
<template>
<div>
<h1>{{num}}</h1>
<button v-on:click="num++">+</button>
<button @click="num--">-</button>
<hr>
<h2>{{num}}</h2>
<!-- 在template模板中如果要调用的是无参数的函数可以写小括号,也可以不写括号都可以 -->
<button @click="increment">+</button>
<button @click="decryment()">-</button>
</div>
</template>
<script>
/*
* 计数器的实现思路
1、首先在data定义一个变量num
2、在template模板中使用插值表达式来进行渲染
3、在指定元素上使用v-on:事件类型=""方式来进行事件的绑定
可以使用@click这种简写的方式来对事件进行绑定
*/
export default {
//在data函数定义的数据都是响应式数据(只要数据发生变化,页面也会自动发生变化)
data(){
return{
//定义在data中的数据可以作为VueComponent实例的成员
num:0
}
},
//methods这个选项中,主要完成事件处理函数的编写,以及自定义函数编写
methods:{
//methods选项中的函数的语法:函数名(){}
increment(){
//如果要在methods选项中的函数中去访问data中的定义的数据,不能直接使用名称获取
this.num++
console.log(`num的数据是:${this.num}`);
},
decryment(){
console.log('##################');
}
}
}
</script>
<style>
</style>
2、事件传值
<template> <div> <h2>{{num}}</h2> <button @click="increment(2)">+2</button> <button @click="decrement" data-step='3'>-3</button> <button @click="incrementN($event,4)" max-val='50'>+4</button> </div></template><script>export default { data(){ return{ num:0 } }, methods:{ increment(step){ this.num+=step }, decrement(e){ this.num-=~~e.target.getAttribute('data-step') }, incrementN(e,step){ if(this.num<~~e.target.getAttribute('max-val')){ this.num+=step }else{ window.alert('数据超过50') } } }}</script><style></style>
3、事件修饰符
2.1、阻止事件冒泡
在vue中阻止事件冒泡,有三种方法
-
使用原生js的方式: e.stopPropagation()
<template> <div class="parent" @click="handleParent"> <div class="child" @click="handleChild"></div> </div></template><script>export default { methods: { handleParent(e) { console.log("handleParent....."); }, handleChild(e) { console.log("handleChild....."); e.stopPropagation() }, },};</script><style lang="scss">.parent { position: absolute; width: 150px; height: 150px; border-radius: 50%; background-color: orange; .child { position: absolute; width: 80px; height: 80px; border-radius: 50%; background-color: springgreen; left: 50%; top: 50%; transform: translate(-50%, -50%); }}</style>
-
.stop事件修饰符的方式来进行阻止
<div class="parent" @click="handleParent"> <div class="child" @click.stop="handleChild"></div></div>
-
.self事件修饰符的方式来进行阻止
<template> <div class="parent" @click.self="handleParent"> <div class="child" @click="handleChild"></div> </div>
2.2、阻止默认行为
阻止默认行为有两种方式
-
通过原生js的方式来进行阻止:e.preventDefault()
-
通过prevent事件修饰符的方式进行阻止
<a href="http://www.woniuxy.com" @click.prevent="go">蜗牛学苑</a>
七、属性绑定指令
1、v-bind的基础使用
属性绑定的指令v-bind这个指令也有简写形式:
<template> <div> <div> <img v-bind:src="imgUrl" alt=""> </div> <div> <button @click="changePic">换图</button> </div> <hr> <!-- v-bind的简写形式是: --> <a :href="networkUrl">{{school}}</a> <br> <button @click="changeSchool">更换</button> </div></template><script>export default { data(){ return{ imgUrl:'https://img1.baidu.com/it/u=3009731526,373851691&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500', networkUrl:'http://www.woniuxy.com', school:'蜗牛学苑' } }, methods:{ changePic(){ this.imgUrl="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Flmg.jj20.com%2Fup%2Fallimg%2F1114%2F121420113514%2F201214113514-6-1200.jpg&refer=http%3A%2F%2Flmg.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1671179801&t=595266893ba6bb495fa1d43e213ae8b7" }, changeSchool(){ this.school='蜗牛学院', this.networkUrl="http://old.woniuxy.com" } }}</script><style> img{ width: 250px; }</style>
2、vue组件引入assets文件夹中的图片
由于该文件夹下的图片是被编译的,所有如果要加载使用三种方式
-
base64方式:建议图片大小不要超过10k
-
import导入方式
-
require方式导入
<template>
<div>
<img :src="picUrl" alt="" />
<img :src="logoUrl" alt="">
<img :src="starUrl" alt="">
</div>
</template>
<script>
import logo from './assets/logo.png'
export default {
data() {
return {
picUrl:"data:image/jpeg;base64,UklGRtQuAABXRUJQV",//该地址不全
logoUrl:logo,
starUrl:require('./assets/women.jpg')
};
},
};
</script>
八、数据变更检测
vue是具有响应式的操作,当数据变化之后,页面会自动更新,但是vue2针对如下几种情况,数据变化,页面不能更新
1、针对对象
如果对对象新增属性、删除属性数据变化,不能带来页面的变化
1)针对与新增属性,可以使用5种方式进行数据变更,具体如下
-
this.$set()
-
Vue.set()
-
ES6的扩展运算符
-
Object.assign()
-
this.,$forceUpdate()
<template> <div> <div>{{teacher}}</div> <button @click="addAttrByObj">新增属性</button> </div> </template><script>import Vue from 'vue'export default { data(){ return{ teacher:{ name:'Giles' } } }, methods:{ addAttrByObj(){ //1、this.$set(this.teacher,'age',38) //2、Vue.set(this.teacher,'age',38) //3、ES6的对象的扩展运算符 // this.teacher={ // ...this.teacher, // age:38 // } //4、Object.assign() //this.teacher=Object.assign({},this.teacher,{age:38}) //5、使用vue实例中的$forceUpdate() this.teacher.age=38 this.$forceUpdate() } }}</script>
2)如果删除一个对象中的属性,也是检测不到的,解决办法如下
/* 删除对象中的属性,实现自动变更检测的方式如下 方式1:使用$forceUpdate()来实现 delete this.teacher.job this.$forceUpdate() */ //this.$delete(this.teacher,'job') Vue.delete(this.teacher,'job')
2、针对数组
operAry1(){ /* this.names[4]="Jack" this.$forceUpdate() */ //this.$set(this.names,4,"Dollr") Vue.set(this.names,4,"Dollr") }, clearAry(){ //this.names.length=0 //this.names=[] this.names.splice(0) }
九、样式操作
1、class类样式绑定
1)字符串语法
<template>
<div>
<div class="box" :class="cs" @click="operClsStyle"></div>
</div>
</template>
<script>
export default {
data(){
return{
cs:''
}
},
methods:{
operClsStyle(){
this.cs="c1"
}
}
}
</script>
<style>
.box{
width: 100px;
height: 100px;
border: 1px solid #000;
border-radius: 50%;
}
.c1{
background-color: orange;
}
</style>
2)数组语法
<template> <div> <div class="box" :class="csAry" @click="m1" @dblclick="m2" @mouseout="m3">🐌</div> </div></template><script>export default { data(){ return{ csAry:[] } }, methods:{ m1(){ this.csAry.push('c1') }, m2(){ this.csAry.push('c2') }, m3(){ this.csAry.push('c3') } }}</script><style> .box{ width: 100px; height: 100px; border: 1px solid #000; border-radius: 50%; transition: 3s; text-align: center; line-height: 100px; } .c1{ background: linear-gradient(red,tomato,orange,yellow); } .c2{ box-shadow: 10px 10px 10px gray; } .c3{ transform: rotate(360deg); }</style>
3)对象语法
<template> <div> <div :class="clsObj" @click="m1" @dblclick="m2" @mouseout="m3"></div> </div></template><script>import Vue from 'vue'export default { data(){ return{ clsObj:{ box:true } } }, methods:{ m1(){ this.$set(this.clsObj,'c1',true) }, m2(){ Vue.set(this.clsObj,'c2',true) }, m3(){ this.clsObj={ ...this.clsObj, c3:true } } }}</script><style> .box{ width: 100px; height: 100px; border: 1px solid #000; border-radius: 50%; transition: 3s; text-align: center; line-height: 100px; } .c1{ background: linear-gradient(red,tomato,orange,yellow); } .c2{ box-shadow: 10px 10px 10px gray; } .c3{ transform: rotate(360deg); }</style>
2、style样式绑定
1)对象语法
<template> <div> <div class="box" v-bind:style="{backgroundColor:activeColor}" @click="changeBgColor"></div> </div></template><script>export default { data(){ return{ activeColor:'red' } }, methods:{ changeBgColor(){ this.activeColor='springgreen' } }}</script><style> .box{ width: 100px; height: 100px; border:1px solid #000; border-radius: 50%; }</style>
2)数组语法
<template> <div :style="styleAry" @click="addStyleToAry"></div></template><script>export default { data(){ return{ styleAry:[{ width:'100px', height:'100px', border:'1px dashed #ccc', borderRadius:'50%' }] } }, methods:{ addStyleToAry(){ this.styleAry.push({ backgroundColor:'#987879' }) } }}</script><style></style>
十、列表渲染指令
在vue中提供了v-for指令用来渲染列表的
1、基本使用
语法
在列表项的开始标签上编写
<ul>
<li v-for="项变量 in 列表">{{项变量}}</li>
</ul>
案例:完成省份的动态渲染
<template>
<div>
<ul>
<!--
v-for用来动态的渲染列表的指令
-->
<li v-for="item in proviceList" :key="item">{{item}}</li>
</ul>
</div>
</template>
<script>
export default {
data(){
return{
proviceList:['西藏','宁夏','陕西','北京','天津','重庆','四川']
}
}
}
</script>
案例2:渲染学生列表
<template>
<div>
<table>
<thead>
<tr>
<th>序号</th>
<th>学号</th>
<th>姓名</th>
<th>年龄</th>
<th>电话</th>
<th>地址</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<!--
v-for的语法
v-for="(项变量,当前项所在的下标位置) in 集合"
下标位置是从0开始的
-->
<tr v-for="(item,index) in students" :key="index">
<td>{{index+1}}</td>
<td>{{item.sid}}</td>
<td>{{item.sname}}</td>
<td>{{item.age}}</td>
<td>{{item.telephone}}</td>
<td>{{item.address}}</td>
<td>
<button>查看</button><button>删除</button>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
data(){
return{
students:[
{
sid:'1001',
sname:'刘备',
age:33,
telephone:'13324567890',
address:'凤城一路'
},
{
sid:'1002',
sname:'关羽',
age:33,
telephone:'13324567890',
address:'凤城一路'
},
{
sid:'1003',
sname:'张飞',
age:33,
telephone:'13324567890',
address:'凤城一路'
},
{
sid:'1004',
sname:'赵云',
age:33,
telephone:'13324567890',
address:'凤城一路'
},
{
sid:'1005',
sname:'马超',
age:32,
telephone:'13324567890',
address:'凤城一路'
}
]
}
}
}
</script>
<style>
table{
border-collapse: collapse;
}
thead tr{
background-color: #ccc;
}
td,th{
border: 1px solid #000;
padding: 10px;
text-align: center;
}
</style>
2、v-for嵌套
<ol>
<li v-for="(item,index) in stars" :key="index">
<h3>{{item.name}}</h3>
<ul>
<li v-for="(sitem,sindex) in item.sings" :key="sindex">
{{sitem.name}}
</li>
</ul>
</li>
</ol>
stars:[
{
id:'1001',
name:'李荣浩',
sings:[
{
sid:'s1001',
name:'李白'
},
{
sid:'s1002',
name:'王妃'
}
]
},
{
id:'1002',
name:'张学友',
sings:[
{
sid:'s2001',
name:'吻别'
},
{
sid:'s2002',
name:'最真心的朋友'
}
]
}
]
十一、双向绑定指令
1、vue中操作DOM
操作DOM的步骤
-
在指定的DOM元素上添加ref属性
<div class="box" @click="changeBgc" ref="boxEle"></div>
-
在methods的相关方法中使用this.$refs.ref属性值获取DOM元素
export default { methods:{ changeBgc(){ this.$refs.boxEle.style.backgroundColor="skyblue" this.$refs.boxEle.innerHTML="🐌" this.$refs.boxEle.style.textAlign="center" this.$refs.boxEle.style.lineHeight="100px" } }}
2、MVVM模式
MVVM是由三部分组成
-
view:用户数据展示的
-
Model:用于完成逻辑操作
-
ViewModel:是中间桥梁,它实现联系View和Model的
一旦数据发生变化,视图会自动发生变化,由Data Bindings来完成的,使用到了Vue响应式原理,底层实现:使用劫持(对象:Object.defineProperty+数据:通过对数据中常用方法的重写来完成)+发布订阅模式
如果一旦view视图发生变化也ViewModel通过DOM Listeners监听也会自定检测到视图变化,也会通知Model中相应数据变化
3、v-model
使用v-model完成表单数据的收集,能够将表单控件和data的数据一一对应起来,如果数据变化后表单项中的内容,如果表单项内容改变了也会驱动data数据的变化
<template>
<div>
<h1>注册</h1>
<div>
<label for="name">姓名:</label>
<input id="name" type="text" v-model="user.name" />
</div>
<div>
<label for="sex">性别</label>
<input type="radio" name="gender" value="1" v-model="user.gender">男
<input type="radio" name="gender" value="2" v-model="user.gender">女
</div>
<div>
<label for="sex">省份:</label>
<select v-model="user.provice">
<option value="1">北京</option>
<option value="2">上海</option>
<option value="3">天津</option>
</select>
</div>
<div>
<label for="hobby">爱好</label>
<input type="checkbox" value="1" v-model="user.hobby">听音乐
<input type="checkbox" value="2" v-model="user.hobby">打篮球
<input type="checkbox" value="3" v-model="user.hobby">踢足球
<input type="checkbox" value="4" v-model="user.hobby">打乒乓
<input type="checkbox" value="5" v-model="user.hobby">打游戏
</div>
<div>
<button @click="register">注册</button>
</div>
</div>
</template>
<script>
export default {
data() {
return {
user: {
name: "",
gender:1,
provice:2,
hobby:[]
},
};
},
methods:{
register(){
console.log(this.user);
}
}
};
</script>
4、修饰符
4.1、lazy
在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步 (除了上述输入法组合文字时)。你可以添加 lazy 修饰符,从而转为在 change 事件_之后_进行同步:
<input v-model.lazy="name"/>
4.2、number
如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符:
<input v-model.number="age" type="number">
这通常很有用,因为即使在 type="number" 时,HTML 输入元素的值也总会返回字符串。如果这个值无法被 parseFloat() 解析,则会返回原始的值
4.3、trim
如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符:
<input v-model.trim="msg">
5、实现v-model
<template> <div> <input type="text" v-bind:value="msg" ref="msgInputEle" @input="getMsgInput"> </div></template><script>export default { data(){ return{ msg:'' } }, methods:{ getMsgInput(){ this.msg=this.$refs.msgInputEle.value } }}</script><style></style>