Vue基础
目录
一 属性指令
指令 | 释义 |
---|---|
v-bind | 直接写js的变量或语法(不推荐) |
: | 直接写js的变量或语法(推荐) |
# 标签上 name id class src href ,height 属性
如果这样,name='xx' 就写死了,我们想动态的绑定变量,变量变化,属性的值也变化
# v-bind:属性名='变量'
# 简写成: :属性名='变量'
1.1 属性指令使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>属性指令</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<button @click="handleClick">点击换张图片</button>
<br>
<img v-bind:src="url" alt="">
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
url: 'https://img2.baidu.com/it/u=567357414,4240886412&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1685898000&t=854107cd66ee6c95173f80697a9f2d81',
},
methods: {
handleClick() {
this.url = 'https://img1.baidu.com/it/u=1960110688,1786190632&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1685898000&t=390682365e6fad9eb79f9068634fa5c2'
}
}
})
</script>
</html>
1.2 换图片小案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>点击隔1秒换一张图片</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<button @click="handleClick">点击开始换图片</button>
<br>
<img :src="url" alt="" @click="handleStop" width="300px" height="300px">
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
url: 'https://img2.baidu.com/it/u=2457727747,1989489688&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1685984400&t=47ad1216f7caa3492c0f310b84b42fcb',
// 图片 数组,放了很多图片
img_list: [
'https://img2.baidu.com/it/u=2693017976,393446383&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=666',
'https://img0.baidu.com/it/u=4027894415,1836497789&fm=253&fmt=auto&app=138&f=JPEG?w=499&h=312',
'https://img2.baidu.com/it/u=1170290536,689675658&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500',
'https://img2.baidu.com/it/u=5226661,719513336&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500',
'https://img0.baidu.com/it/u=2714594659,3978796526&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500',
'https://img0.baidu.com/it/u=2170515335,2885793162&fm=253&fmt=auto&app=138&f=JPEG?w=750&h=468',
'https://img0.baidu.com/it/u=3240504477,531143179&fm=253&fmt=auto&app=120&f=JPEG?w=1422&h=800',
'https://img1.baidu.com/it/u=1572218129,3212523576&fm=253&fmt=auto&app=138&f=JPEG?w=816&h=459',
'https://img0.baidu.com/it/u=1875601625,1015447822&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500',
'https://img0.baidu.com/it/u=1597528499,1951634846&fm=253&fmt=auto&app=138&f=JPEG?w=320&h=510',
'https://img0.baidu.com/it/u=2024676831,1388119201&fm=253&fmt=auto&app=138&f=JPEG?w=750&h=468',
],
// 为了定时器,先定义一个变量t,为了取消定时器时使用
t: null
},
methods: {
handleClick() {
var _this = this
// 定时器---> 每隔 某个事件 做一件事
// setInterval(匿名函数, 毫秒数)
this.t = setInterval(function () {
// url 随机从列表中取值,赋值给url
// Math.random() 生成0--1之间的小数
// _this.img_list.length: 列表长度
// Math.floor 向下取整
// 能返回一个数组大小以内的数字
var res = Math.floor((Math.random() * _this.img_list.length))
_this.url = _this.img_list[res] // 数组[索引]
console.log(_this.url)
}, 1000)
},
// 点击图片就停下
handleStop() {
// 停止定时器
clearInterval(this.t)
this.t = null
},
}
})
</script>
</html>
二 style和class
2.1 数据的绑定
语法::属性名='js变量/js语法'
-
:class='js变量、字符串、js数组'
class:三目运算符、数组、对象 -
:style='js变量、字符串、js数组'
style:三目运算符、数组[{backgreound: 'red'},]、对象
# style 和 class 也是属性,可以使用属性指令 :class= :style=
# 但是他们比较特殊,单独再讲
2.2 class 的使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>class 的使用</title>
<script src="./js/vue.js"></script>
<style>
.size {
font-size: 80px;
}
.red {
background-color: red;
}
.yellow {
background-color: yellow;
}
</style>
</head>
<body>
<div id="app">
<h1>class 的使用:字符串、数组、对象</h1>
<div class="size red">我是div</div>
<h2>1.class字符串变量</h2>
<button @click="handleClick1">点我变样式1</button>
<br>
<div :class="class_str">
我是div1
</div>
<hr>
<h2>2.class数组变量</h2>
<button @click="handleClick2">点我变样式2</button>
<br>
<div :class="class_arr">
我是div2
</div>
<hr>
<h2>3.class对象变量</h2>
<button @click="handleClick3">点我变样式3</button>
<br>
<div :class="class_obj">
我是div3
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
// class 推荐使用 数组方式
// class 绑定的变量,类型可以是 字符串,数组,对象
// 字符串
class_str: 'red', // 换样式:vm.class_str = 'size red'
// 数组
class_arr: ['size'], // 给该变量,追加值,class变化,页面会发生变化:vm.class_arr.push('yellow')
// 对象
class_obj: {size: true, red: false}, // 对象的用法,必须先提前设置,后期通过修改true或false控制类
// this.class_obj.red = true
},
methods: {
handleClick1() {
this.class_str = 'size yellow'
},
handleClick2() {
this.class_arr.push('red')
},
handleClick3() {
// 往对象中放之前不存在的值
// this.class_obj.yellow = true // 直接放,没有响应式,没有监听到你的数据变化
// 放对象中没有的值,也有响应式,可以使用Vue.set
Vue.set(this.class_obj, 'yellow', true) // 这样才有响应式,有了数据监听
},
}
})
</script>
</html>
2.3 style 的使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>style 的使用</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<h1>style 的使用:字符串、数组、对象</h1>
<div style="font-size: 80px; background-color: green">
0 我是div
</div>
<h2>1.style字符串变量</h2>
<button @click="handleClick1">点我变样式1</button>
<br>
<div :style="style_str">
我是div1
</div>
<hr>
<h2>2.style数组变量</h2>
<button @click="handleClick2">点我变样式2</button>
<br>
<div :style="style_arr">
我是div2
</div>
<hr>
<h2>3.style对象变量</h2>
<button @click="handleClick3">点我变样式3</button>
<br>
<div :style="style_obj">
我是div3
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
// style 推荐使用 对象形式
// style 绑定的变量,类型可以是 字符串,数组,对象
// 字符串
style_str: 'font-size: 80px; background-color: green', // 换样式:vm.style_str='background-color: red'
// 数组
style_arr: [{'background-color': 'red'}], // 给该变量追加值,style变化,页面会发生变化:vm.style_arr.push({'font-size': '80px'})
// 对象
// style_obj: {'font-size': '60px', 'background-color': 'red'},
// style_obj: {'font-size': '60px'},
// 省略key值的引号后,要变成驼峰形式
style_obj: {fontSize: '60px', backgroundColor: 'green'}
},
methods: {
handleClick1() {
this.style_str = 'font-size: 80px'
},
handleClick2() {
this.style_arr.push({'font-size': '80px'})
},
handleClick3() {
// 放对象中的值
// this.style_obj.background-color = 'green'
// 往对象中放之前不存在的值
// this.style_obj.background-color = 'red' // 直接放,没有响应式,没有监听到你的数据变化 // this.class_obj.yellow = true // 直接放,没有响应式,没有监听到你的数据变化
// 放对象中没有的值,想有响应式,可以使用Vue.set
// Vue.set(this.style_obj, 'background-color', 'red') // 这样才有响应式,有了数据监听
Vue.set(this.style_obj, 'backgroundColor', 'red') // 这样才有响应式,有了数据监听
},
}
})
</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>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<div v-if="score>=90">优秀</div>
<div v-else-if="score>=80&&score<90">良好</div>
<div v-else-if="score>=60&&score<80">及格</div>
<div v-else>不及格</div>
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
// 现在的数据是写死的,后期我们可以从数据库中读取
score: 98
},
methods: {}
})
</script>
</html>
四 列表渲染
# 循环渲染一些数据,比如购物车的数据
# v-for:循环字符串,数组,数字,对象
# 有购物车数据,循环显示在页面中
4.1 v-for 显示购物车
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-for 列表渲染</title>
<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css"
integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1 class="text-center">购物车</h1>
<div class="pull-right">
<button class="btn btn-info" @click="handleClick">加载购物车</button>
</div>
<table class="table table-striped">
<thead>
<tr>
<th>id号</th>
<th>商品名称</th>
<th>商品价格</th>
<th>商品数量</th>
</tr>
</thead>
<tbody>
<tr v-for="good in good_list">
<th scope="row">{{good.id}}</th>
<td>{{good.name}}</td>
<td>{{good.price}}</td>
<td>{{good.count}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
good_list: []
},
methods: {
handleClick() {
this.good_list = [
{'id': 1, 'name': '小汽车', 'count': 2, 'price': 100000},
{'id': 2, 'name': '脸盆', 'count': 5, 'price': 23},
{'id': 3, 'name': '方便面', 'count': 19, 'price': 2},
{'id': 4, 'name': '钢笔', 'count': 5, 'price': 7},
]
}
}
})
</script>
</html>
4.2 v-for循环其它类型
# 数字,字符串,数组,对象
# 看到别人写v-for时,在标签上都会加一个 key 属性,目的是为了提高虚拟dom的替换效率
<el-carousel-item v-for="item in 4" :key="item">
# key 的值必须唯一,如果不唯一就报错
###### 以后如果数据变了,页面没有发生变化#####
就是没有监控到你的变化,需要用Vue.set设置一下
Vue.set(对象, key, value)
Vue.set(数组, 索引, 值)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-for循环其它类型</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<h1>1. 循环数字</h1>
<h2>1.1 循环数字单独只有值</h2>
<ul>
<li v-for="i in number">{{i}}</li>
</ul>
<h2>1.2 循环数字,值、索引</h2>
<ul>
<li v-for="(value, index) in number">值:{{value}}-----> 索引:{{index}}</li>
</ul>
<h1>2. 循环字符串</h1>
<h2>2.1 循环字符串一个参数</h2>
<ul>
<li v-for="s in str">{{s}}</li>
</ul>
<h2>2.2 循环字符串两个参数</h2>
<ul>
<li v-for="(value, index) in str">字符串:{{value}} ------> 索引:{{index}}</li>
</ul>
<h1>3. 循环数组</h1>
<h2>3.1 循环数组一个参数</h2>
<ul>
<li v-for="a in arr">{{a}}</li>
</ul>
<h2>3.2 循环数组两个参数</h2>
<ul>
<li v-for="(value, index) in arr">值:{{value}} ------> 索引:{{index}}</li>
</ul>
<h1>4. 循环对象</h1>
<h2>4.1 循环数组一个参数</h2>
<ul>
<li v-for="o in obj">{{o}}</li>
</ul>
<h2>4.2 循环数组两个参数</h2>
<ul>
<li v-for="(value, index) in obj">值:{{value}} ------> key:{{index}}</li>
</ul>
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
number: 10,
str: 'lqz is handsome',
arr: [3, 4, 2, 66, 55],
obj: {name: 'lqz', age: 19, gender: '男'}
},
methods: {
}
})
</script>
</html>
注意!在Vue中:
- 数组的index和value是反的
- 对象的key和value也是反的
4.3 key值 的解释
vue中使用的是虚拟DOM,会和原生的DOM进行比较,然后进行数据的更新,提高数据的刷新速度(虚拟DOM用了diff算法)
- 在v-for循环数组、对象时,建议在控件/组件/标签写1个key属性,属性值唯一
- 页面更新之后,会加速DOM的替换(渲染)
- :key="变量"
4.4 数组更新与检测
可以检测到变动的数组操作
- push:最后位置添加
- pop:最后位置删除
- shift:第一个位置删除
- unshift:第一个位置添加
- splice:切片
- sort:排序
- reverse:反转
检测不到变动的数组操作
- filter():过滤
- concat():追加另一个数组
- slice():
- map():
原因:
作者重写了相关方法(只重写了一部分方法,但是还有另一部分没有重写)
解决方法
// 方法1:通过 索引值 更新数组(数据会更新,但是页面不会发生改变)
vm.arrayList[0]
"Alan"
vm.arrayList[0]='Darker'
"Darker"
// 方法2:通过 Vue.set(对象, index/key, value) 更新数组(数据会更新,页面也会发生改变)
Vue.set(vm.arrayList, 0, 'Darker')
五 事件处理
# 事件指令
-click:点击事件
# input标签的事件
-input:只要输入内容,就会触发
-change:只要输入框发生变化,就会触发
-blur:只要失去焦点,就会触发
具体使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>input 标签的三个事件</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<h1>1. input事件:只要输入内容,就会触发</h1>
<div>
<input type="text" @input="handleInput" v-model="username1"> ---> {{username1}}
</div>
<h1>2. change事件:只要输入框发生变化,就会触发</h1>
<div>
<input type="text" @change="handleChange" v-model="username2"> ---> {{username2}}
</div>
<h1>3. blur事件:只要失去焦点,就会触发</h1>
<div>
<input type="text" @blur="handleBlur" v-model="username3"> ---> {{username3}}
</div>
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
username1: 'lqz',
username2: '',
username3: '',
},
methods: {
handleInput() {
console.log(this.username1)
},
handleChange(){
console.log('我执行了')
},
handleBlur(){
console.log('失去焦点了')
}
}
})
</script>
</html>
六 数据双向绑定
v-model的使用
# 数据双向绑定---> 只有input标签---> v-model 做双向数据绑定(页面变化,数据值变化,但是页面上能够接收到数据值的只有input框)
# 咱们之前写的,其实都是数据的单向绑定
修改js的值,页面变了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>数据双向绑定</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<h1>单向数据绑定,咱们不用</h1>
<div>数据赋值给一个变量,变量的赋值发生变化,会导致页面发生变化</div>
<div>用户名:<input type="text" :value="username1"></div>
<div>密码:<input type="password" :value="password1"></div>
<!-- 登录按钮绑定点击事件,后面直接把数据post方式提交到后端-->
<div>
<button @click="handleSubmit1">登录</button>
</div>
<h1>数据双向绑定</h1>
<div>v-model的使用:页面发生了变化,变量的值也会发生变化</div>
<div>用户名:<input type="text" v-model="username"></div>
<div>密码:<input type="password" v-model="password"></div>
<!-- 登录按钮绑定点击事件,后面直接把数据post方式提交到后端-->
<div>
<button @click="handleSubmit">登录</button>
</div>
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
username1: 'lqz',
password1: '123',
username: 'lqz11',
password: '12345',
},
methods: {
handleSubmit1() {
// this.username1 = 'kkk'
// this.password1 = '111'
console.log(this.username1)
console.log(this.password1)
},
handleSubmit() {
console.log(this.username)
console.log(this.password)
}
}
})
</script>
</html>
七 过滤案例
7.1 补充
1 数组的过滤
2 判断一个子字符串,是否在另一个字符串中
indexOf返回子字符串在母字符串的索引位置
3.过滤出,数组中有at的字符串
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>补充</title>
<script src="./js/vue.js"></script>
</head>
<body>
</body>
<script>
// 1 数组的过滤
var arr = ['a', 'at', 'atom', 'atomic', 'be', 'beyond', 'cs', 'csrf']
// 数组.filer(匿名函数,接受一个参数,函数必须返回true或false,如果返回true,表示这个值保留)
var new_arr = arr.filter(function (item) {
// item就是循环数组的一个个值
console.log(item)
if (item.length > 3) {
return true
} else {
return false
}
})
// 保留返回值是true的数组值,是由4个
console.log(new_arr) // (4) ['atom', 'atomic', 'beyond', 'csrf']
// 2 判断一个子字符串,是否在另一个字符串中
var s = 'is'
var s1 = 'lqz is handsome'
// indexOf返回子字符串在母字符串的索引位置
var res = s1.indexOf(s)
console.log(res) // 4
// 如果大于等于0,说明s在s1中
// 3.过滤出,数组中有at的字符串
var arr = ['a', 'at', 'atom', 'atomic', 'be', 'beyond', 'cs', 'csrf']
var search = 'at'
var new_arr = arr.filter(function (item) {
if (item.indexOf(search) >= 0) {
return true
} else { // else可以不写return None也是false
return false
}
})
console.log(new_arr) // (3) ['at', 'atom', 'atomic']
</script>
</html>
7.2 过滤案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>过滤案例</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="search" @input="handleInput">
<hr>
<ul>
<li v-for="item in newdataList">{{item}}</li>
</ul>
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
search: '',
dataList: ['a', 'at', 'atom', 'atomic', 'be', 'beyond', 'cs', 'csrf'],
newdataList: ['a', 'at', 'atom', 'atomic', 'be', 'beyond', 'cs', 'csrf'],
},
methods: {
// 方式一
// handleInput() {
// console.log(this.search)
// // 根据用户输入的search,对数组进行过滤,剩下只有包含输入文字的字符串
// var _this = this
// // dataList这个数组一直不会变化,只改变新的数组
// this.newdataList = this.dataList.filter(function (item) {
// if (item.indexOf(_this.search) >= 0) {
// return true
// } else {
// return false
// }
// })
// },
// 简写
// handleInput() {
// console.log(this.search)
// // 根据用户输入的search,对数组进行过滤,剩下只有包含输入文字的字符串
// var _this = this
// // dataList这个数组一直不会变化,只改变新的数组
// this.newdataList = this.dataList.filter(function (item) {
// return item.indexOf(_this.search) >= 0
// })
// },
// 使用箭头函数,简写
handleInput() {
this.newdataList = this.dataList.filter(item => item.indexOf(this.search) >= 0)
}
},
})
</script>
</html>
补充
# 补充1:定时任务和延迟任务,js中如何实现
setTimeout(function(){},3000) # 3s后执行匿名函数
var t=setInterval(function(){},3000) # 每隔3s执行匿名函数
clearInterval(t) # 停止定时任务
t=null
1 定时切换图片
2 倒计时效果
3 定时向后端发请求