02 Vue基础
一、插值语法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>插值语法</title>
<script src="./js/vue.js"></script>
</head>
<body>
<h1>插值语法</h1>
<div id="app">
<h1>我的名字是:{{name}}</h1>
<h2>我的年龄是:{{age}}</h2>
<h3>我的爱好是:{{hobby}}</h3>
<h4>显示对象:{{obj}}</h4>
<p>{{url}}</p> 默认情况,原封不动显示,如果能直接渲染成标签,说明存在漏洞 xss攻击
</div>
</body>
<script>
var vm =new Vue({
el:'#app',
data:{
name:'meng',
age:19,
hobby:['篮球','足球','乒乓球'],
obj:{wife:'迪丽热巴',addr:'上海'},
url:'<a href="http://www.baidu.com"></a>'
}
})
</script>
</html>
因为Vue是双向绑定的,可以在前端修改属性,也可以在后端修改
二、指令
1、文本指令
指令 | 解释 |
---|---|
v-html | 让HTML渲染成页面 |
v-text | 标签内容显示js变量对应的值 |
v-show | 放1个布尔值:为真 标签就显示;为假 标签就不显示(隐藏) |
v-if | 放1个布尔值:为真 标签就显示;为假 标签就不显示(真正删除) |
v-show与 v-if的区别:
v-show:标签还在,只是不显示了(display: none)
v-if:直接操作DOM,删除/插入 标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文本指令</title>
<script src="./js/vue.js"></script>
</head>
<body>
<h1>文本指令</h1>
<div id="app">
<h3>就想显示成标签</h3>
<p>{{url}} </p>
指令写在标签内,指令对应的变量,直接写就可以了,不需要再用 {{}} 包裹了
<br>
1、v-html:把字符串,渲染成标签
<div v-html="url"></div>
<br>
2、v-text:把变量内容,渲染到标签中
<p><span>{{hello}}</span></p>
<p><span v-text="hello"></span></p>
<br>
3、v-show:一个标签是否显示,用变量可以,用true或false也可以, 其实是display: none;并不是真正的把dom删除了
<div v-show="b">
我是一个div
<p>我的div</p>
<p>我的div</p>
<p>我的div</p>
</div>
<br>
4、v-if:真正的删除,效率低
<div v-if="b1">
我是第二个个div
<p>我是第二个个div</p>
<p>我是第二个个div</p>
<p>我是第二个个div</p>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
hello: 'hello world',
b:true,
b1:true,
url: '<a href="http://www.baidu.com">点我看美女</a>'
}
})
</script>
</html>
2、事件指令
指令 | 解释 |
---|---|
v-on | 触发事件(不推荐) |
@ | 触发事件(推荐) |
@[event] | 触发event事件(可以是其他任意事件) |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件指令</title>
<script src="./js/vue.js"></script>
</head>
<body>
<h1>事件指令</h1>
<div id="app">
v-on表示事件指令,click表示单击,老语法,不用了
<p><button v-on:click="handleClick">按钮</button></p>
<br>
新语法,以后都用这种: @click='函数名'
<p><button @click="handleClick2">按钮二</button></p>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {},
methods: {
handleClick() {
alert('我被点了')
},
handleClick2() {
alert("按钮2被点击了")
}
}
})
</script>
</html>
3、属性指令
指令 | 解释 |
---|---|
v-bind | 直接写js的变量或语法(不推荐) |
: | 直接写js的变量或语法(推荐) |
v-bind:class=’js变量’可以缩写成::class=’js变量’
# 只要是标签的属性,都可以使用属性指令动态绑定
# v-bind:属性名=属性值
# :属性名=属性值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div class="app">
<h1>只要是标签的属性,都可以使用属性指令动态绑定</h1>
// 通过v-bind:name来绑定属性
<span id="id_span" v-bind:name="name">我是span</span>
<hr>
<span id="id_span2" :name="name">我是span222</span>
<hr>
// 通过:语法绑定网址,不使用:会直接显示字符串
<a :href="url">点我看美女</a>
<hr>
// 通过:语法绑定图片地址,不使用:会不显示
<img :src="src" alt="">
</div>
</body>
<script>
var vm=new Vue({
el:'.app',
data:{
name:'meng',
url:'http://www.baidu.com',
src:'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fhbimg.huabanimg.com%2Ff8f343e8f16c55ee489da60bfca7cd0ceb01bfd0a98a-ixSNbV_fw658&refer=http%3A%2F%2Fhbimg.huabanimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1647048281&t=acb541b86473f0b910fae0ee787228f2'
}
})
</script>
</html>
三、Style 和 Class
数据的绑定
style和class都能绑定字符串,数组,对象
语法
:属性名=js变量/js语法
- :class=’js变量、字符串、js数组’
class:三目运算符、数组、对象{red: true}
- :style=’js变量、字符串、js数组’
style:三目运算符、数组[{backgreound: ‘red’},]、对象{background: ‘red’
Class
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../js/vue.js"></script>
<style>
.red {
background-color: red;
}
.green {
background-color: green;
}
.size {
font-size: 60px;
}
</style>
</head>
<body>
<div class="app">
<button @click="handClick">点我变色</button>
<button @click="handClick2">点我字体变大</button>
<div :class="divClass">
<p>我会变色</p>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data: {
// class 属性,绑定字符串
// divClass:'red',
// class 属性,绑定数组----这个用的多
divClass: ['red',] // vm.divClass.pop():删除最后1个元素 并返回
// class属性,绑定对象
// divClass:{'red':true,'size':false}
},
methods: {
handClick() {
this.divClass = 'green' // 变色的点击事件
},
handClick2() {
this.divClass.push('size') // 字体变大的点击事件
// this.divClass['size']=true // 绑定对象的点击事件
}
}
})
</script>
</html>
Style
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div class="app">
<div :style="styleStr">
<p>我是style</p>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data: {
//style绑定字符串
// styleStr:'background-color: red;font-size: 40px'
// style绑定数组
// styleStr:[{'background-color':'green'},{'font-size': '40px'}]
// style绑定对象
// styleStr:{'background-color':'yellow','font-size': '80px'}
styleStr: {backgroundColor: 'yellow', fontSize: '80px'} // 驼峰会自动转换
}
})
</script>
</html>
四、条件渲染
指令 | 解释 |
---|---|
v-if | 相当于: if |
v-else | 相当于:else |
v-else-if | 相当于:else if |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div class="app">
<h1>您的成绩是:</h1>
<h2 v-if="score>=90&&score<100">优秀</h2>
<h2 v-else-if="score>=80&&score<90">良好</h2>
<h2 v-else-if="score>=60&&score<80">及格</h2>
<h2 v-else>不及格</h2>
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data: {
score:99
}
})
</script>
</html>
五、列表渲染
1、v-for:遍历数组(列表)、对象(字典)、数字和展示图书
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div class="app">
<button @click="handleClick">刷新购物车</button>
<table border="1">
<tr>
<td>顺序</td>
<td>图书名字</td>
<td>价格</td>
<td>出版社</td>
</tr>
<!-- // 在标签上循环,index是索引,从1开始-->
<!-- # book是循环到的对象,index是数组的索引-->
<tr v-for="(book,index) in book_list">
<td>{{index+1}}</td>
<td>{{book.name}}</td>
<td>{{book.price}}</td>
<td>{{book.publish}}</td>
</tr>
</table>
<hr>
<h2>循环对象</h2>
<!-- # value是字典的value值,可以是字典的key值,注意是跟正常的相反,如果只取一个值,就是value值-->
<p v-for="(value,key) in person">{{key}}是:{{value}}</p>
<hr>
<h2>循环数字</h2>
<!-- # 从1开始到5-->
<p v-for="i in 5">循环到第{{ i}}次了</p>
<hr>
<h2>循环字符串</h2>
<!-- 单个字符循环打印-->
<p v-for="i in 'asfdasdsdaf'">{{i}}</p>
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data: {
book_list: [], // 一开始是没有数据的
person: {name: '彭于晏', age: 34, height: 169}
},
methods: {
handleClick() {
this.book_list = [{name: '小王子', price: 100, publish: '北京出版社'},
{name: '西游记', price: 12, publish: '北京出版社'},
{name: '三国演义', price: 55, publish: '南京出版社'},
{name: '封神榜', price: 99, publish: '上海出版社'},
]
}
}
})
</script>
</html>
注意!在Vue
中:
- 数组的
index
和value
是反的 - 对象的
key
和value
也是反的
2、key值 的解释
vue中使用的是虚拟DOM,会和原生的DOM进行比较,然后进行数据的更新,提高数据的刷新速度(虚拟DOM用了diff算法)
在v-for循环数组、对象时,建议在控件/组件/标签写1个key属性,属性值唯一
页面更新之后,会加速DOM的替换(渲染)
:key="变量"
3、数组更新与检测
可以检测到变动的数组操作:
push:最后位置添加
pop:最后位置删除
shift:第一个位置删除
unshift:第一个位置添加
splice:切片
sort:排序
reverse:反转
检测不到变动的数组操作:
filter():过滤
concat():追加另一个数组
slice():
map():
原因:
作者重写了相关方法(只重写了一部分方法,但是还有另一部分没有重写)
4、问题:有的时候,数组(对象)变了,但是页面没变
# 在写vue时,会发生数组发生改变,但是页面没有改?
# 原因是:
作者重写了相关方法(只重写了一部分方法,但是还有另一部分没有重写)
解决:
// 方法1:通过 索引值 更新数组(数据会更新,但是页面不会发生改变)
vm.arrayList[0]
"Alan"
vm.arrayList[0]='Darker'
"Darker"
// 方法2:通过 Vue.set(对象, index/key, value) 更新数组(数据会更新,页面也会发生改变) # 推荐
Vue.set(vm.arrayList, 0, 'Darker') # Vue.se(vm.key,索引,要修改的数据)
六、事件处理
事件 | 解释 |
---|---|
input | 当输入框进行输入的时候 触发的事件 |
change | 当元素的值发生改变时 触发的事件 |
blur | 当输入框失去焦点的时候 触发的事件 |
change 和 blur 最本质的区别:
如果输入框为空,失去焦点后,change不会触发,但是blur会触发
1、过滤案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div class="app">
<input type="text" v-model="myText" @input="handledInput">
<p v-for="data in newDataList">{{data}}</p>
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data: {
myText: '',
dataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'], // 管向后搜索的,删除不匹配的
newDataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'], // 管回退的数据
},
methods: {
handledInput() {
// 筛选用第一个
this.newDataList = this.dataList.filter(item => {
// item.indexOf(this.myText):输入框中输入的字符串在筛选元素中的索引
return item.indexOf(this.myText) > -1 // 返回索引大于1的元素:>-1 就表示包含在其中
// indexOf的使用:判断子字符串在该字符串的那个位置,不在返回 -1
})
},
}
})
</script>
</html>
过滤案例总结
# 数组如何过滤
数组.filter(function (item){
return true/false # 如果return了true当前item保留,否则不保留
})
# es6的箭头函数,处理this指向的问题
数组.filter(item=>{
return true/false # 如果return了true当前item保留,否则不保留
})
# indexOf:字符串的方法
字符串.indexOf(子字符串),如果子字符串在字符串中,返回索引,如果不在返回 -1,如果大于-1说明,子字符串在字符串中
2、事件修饰符
事件修饰符 | 解释 |
---|---|
.stop | 只处理自己的事件,父控件冒泡的事件不处理(阻止事件冒泡) |
.self | 只处理自己的事件,子控件冒泡的事件不处理 |
.prevent | 阻止a链接的跳转 |
.once | 事件只会触发一次(适用于抽奖页面) |
使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生
用
v-on:click.prevent.self
会阻止所有的点击
而v-on:click.self.prevent
只会阻止对元素自身的点击
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div class="app">
<!-- 只处理自己的事件,冒泡上来的事件不处理-->
<ul @click.self="handleUl">
<li @click.stop="handleLi1">li1,加了stop后,阻止了事件冒泡,事件不往上传递了</li>
<li @click="handleLi2">li2</li>
</ul>
<hr>
<a href="http://www.baidu.com" @click.prevent="handleA">点我看美女</a>
<hr>
<button @click.once="buttonClick">点我秒杀</button>
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data: {},
methods: {
handleLi1() {
console.log('li1被点击了')
},
handleLi2() {
console.log('li2被点击了')
},
handleUl() {
console.log('ul被点击了')
},
handleA(){
console.log('a被点击了')
window.location='http://www.jd.com' // 手动跳转
},
buttonClick(){
console.log('button被点击了')
}
}
})
</script>
</html>
3、按键修饰符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div class="app">
<!-- <input type="text" @keyup="handleKeyUp($event)">-->
<input type="text" @keyup.enter="handleKeyUp">
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data: {},
methods: {
handleKeyUp() { // 只要enter建弹起,就触发
console.log('enter点了')
}
}
})
</script>
</html>
七、据双向绑定
1、v-model的使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div class="app">
用户名:<input type="text" v-model="username">
密码:<input type="password" v-model="password">
<hr>
<p>您输入的用户名为:{{username}}</p>
<p>您输入的密码为:{{password}}</p>
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data: {
username:'',
password:'',
}
})
</script>
</html>