前端之VUE
vue介绍和基本使用
介绍
vue是一套用于构建用户界面的渐进式框架,与其它大型框架不同的是,Vue可以被设计为自底层向上逐层应用,Vue的核心库只关注视图层
渐进式框架
可以一点一点地使用它,只用一部分,也可以整个工程都使用它
官网:https://cn.vuejs.org/
文档:https://cn.vuejs.org/v2/guide/
特点
易用
通过HTML、CSS、JavaScript构建应用
灵活
不断繁荣的生态系统,可以在一个库和一套完整框架之间自如伸缩
高效
20kB min+gzip 运行大小、超快虚拟 DOM、最省心的优化
M-V-VM思想
介绍
M-V-VM就是Model-View-ViewModel的缩写,它是一种基于前端开发的架构模式,是一种事件驱动编程方式
Model
vue对象的data属性里面的数据,这里的数据要显示到页面中
View
vue中数据要显示的HTML页面,在vue中,也称之为“视图模板” (HTML+CSS)
ViewModel
vue中编写代码时的vm对象,它是vue.js的核心,负责连接 View 和 Model数据的中转,保证视图和数据的一致性,所以前面代码中,data里面的数据被显示中p标签中就是vm对象自动完成的(双向数据绑定:JS中变量变了,HTML中数据也跟着改变)
特性
低耦合
视图(View)可以独立于Model变化和修改,1个ViewModel可以绑定到不同的View上,当View变化的时候 Model可以不变,当Model变化的时候 View也可以不变
可复用
可以把一些视图逻辑放在1个ViewModel中,让很多View重用这端视图的逻辑(以此减少代码冗余)
独立开发
开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计
可测试
界面元素是比较难以测试的,而现在的测试可以针对ViewModel来编写
引入方式
CDN引入
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
使用静态文件
在浏览器中打开https://cdn.jsdelivr.net/npm/vue/dist/vue.js,然后复制下来,创建一个js文件再粘贴进去
简单使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<p>{{name}}</p>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data:{
name: 'Hello World'
}
})
</script>
</html>
插值语法
插值语法中可以放
变量、对象取值、数组取值,简单的js语法,函数
# 插值不能写在标签的属性上,只能写在标签内部
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
{{name}}
{{age}}
{{sb}}----{{sb.name}}----{{sb['age']}}
{{a_url}} <!--默认不会渲染成标签,识别为字符串-->
<p>运算:{{10*2+3*4}}</p>
<p>三目运算符【条件?'符合了':'不符合了'】:{{10>90?'大于':'小于'}}</p>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data:{
name: 'Hello World',
age: 18,
sb: {name: '张红', age: 38},
a_url: '<a href="https://www.xrmn01.cc/uploadfile/202302/13/0616402528.jpg">点我看美女</a>'
}
})
</script>
</html>
文本指令
写在标签上,任意标签都可以,原来插值语法中能写的文本指令都可以,不需要再加{{}}
写法:v-xx=""
v-text <p v-text="a_url"></p>
直接把字符串内容渲染在标签内部,等同于<p>{{a_url}}</p>
v-html <p v-html="a_url"></p>
将字符串的内容渲染成标签,写在标签内部
v-show 等于布尔值,在样式上控制该标签是否显示
v-if 等于布尔值,在dom中删除或显示标签来控制标签是否显示,效率低
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<p v-text="a_url"></p>
<p v-html="a_url"></p>
<img src="https://img.lesmao.vip/k/1178/T/XiuRen/6217/6217_003_66o_3324_5400.jpg" v-show="show" width="400px" height="400px">
<img src="https://img.lesmao.vip/k/1178/T/XiuRen/6217/6217_006_40y_3600_5400.jpg" v-if="show_if" width="400px" height="400px">
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data:{
a_url: '<a href="https://www.xrmn01.cc/uploadfile/202302/13/0616402528.jpg">点我看美女</a>',
show: true,
show_if: true
}
})
</script>
</html>
属性指令
标签上的属性可以绑定变量,以后变量变化属性的值跟着变化
语法:v-bind:属性名="变量名" 可以简写为::属性名="变量名"
事件指令
在标签中绑定各种事件如点击事件、双击事件、滑动事件等,我们用的最多的就是点击事件click
v-on:事件名="函数"
<button v-on:click="handleClick">点我看美女</button>
函数handleClick必须写在methods的配置项中
methods: {
'handleClick': function () {
var i =Math.round(Math.random()*(this.url_list.length - 1))
this.url = this.url_list[i]
}
这里v-on:click="handleClick"可以简写成
@click="handleClick"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<button @click="handleClick">点我看美女</button>
<div>
<img :src="url" alt="" width="400px" height="400px">
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data:{
url: 'https://img.lesmao.vip/k/1178/T/XiuRen/6217/6217_003_66o_3324_5400.jpg',
url_list: [
'https://img.lesmao.vip/k/1178/T/XiuRen/6217/6217_007_pge_3600_5400.jpg',
'https://img.lesmao.vip/k/1178/T/XiuRen/6217/6217_008_4sz_3600_5400.jpg',
'https://img.lesmao.vip/k/1178/T/XiuRen/6217/6217_010_qcs_3600_5400.jpg',
'https://img.lesmao.vip/k/1178/T/XiuRen/6217/6217_012_g3k_3600_5400.jpg',
'https://img.lesmao.vip/k/1178/T/XiuRen/6217/6217_020_jx6_3600_5400.jpg'
]
},
methods: {
'handleClick': function () {
var i =Math.round(Math.random()*(this.url_list.length - 1))
this.url = this.url_list[i]
}
}
})
</script>
</html>
class和style
class与style都是属性指令,但是他们俩应用广泛
class语法
:class='变量' 变量可以是字符串、数组、对象
class多使用数组
style语法
:style='变量' 变量可以是字符串、数组、对象
style多使用对象
# js数组的常用方法 https://blog.csdn.net/qq_39132756/article/details/85007082/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<script src="js/vue.js"></script>
<style>
.fount {
font-size: 60px;
}
.red {
background-color: red;
}
.font-color {
color: rebeccapurple;
}
</style>
</head>
<body>
<div id="app">
<h1>class</h1>
<div :class="class_obj">我是class的div</div>
<h1>style</h1>
<div :style="style_obj">我是style的div</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
class_obj: {font:true, },
style_obj: {color: 'yellow'}
}
})
</script>
</html>
条件渲染
v-if=条件 放在标签上,如果条件成立,该标签就显示,否则不显示
v-else-if=条件 放在标签上,如果条件成立,该标签就显示,否则不显示
v-else 放在标签上,上面的条件都不成立显示这个标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<h1>成绩</h1>
<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="score<60">不及格</div>
</div>
</body>
<script>
var vm = new Vue ({
el: '#app',
data: {
score: 90
}
})
</script>
</html>
列表渲染
使用v-for可对数据进行for循环 v-for="item in good_list
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<script src="js/vue.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
</head>
<body>
<div id="app">
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="text-center">
<h1>显示购物车</h1>
</div>
<div>
<table class="table table-hover">
<thead>
<tr>
<th>id</th>
<th>品名</th>
<th>价格</th>
</tr>
</thead>
<tbody>
<tr v-for="item in good_list">
<th scope="row">{{item.id}}</th>
<th>{{item.name}}</th>
<th>{{item.price}}</th>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</body>
<script>
var vm = new Vue ({
el: '#app',
data: {
good_list: [
{id: 1, name: '面包', price: '12'},
{id: 2, name: '牛奶', price: '8'},
{id: 3, name: '巧克力', price: '14'},
{id: 4, name: '瓜子', price: '9'},
{id: 5, name: '可乐', price: '3.5'},
]
}
})
</script>
</html>
js的几种循环方式
v-for可以循环的变量
v-for可以循环的变量有数组、对象、字符串、数字
data: {
l: [1, 2, 3, 4],
info: {name: 'zyg', age: 18},
s: 'hello word'
}
循环数组
v-for="(i, b) in l" i为值,b为索引位
循环对象
v-for="(i, b) in info" i为value,b为key
循环字符串
v-for="(i, b) in s" i为字符,b为索引位
循环数字
v-for="(i, b) in 9" i为数字,b为索引位
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<script src="./js/vue.js"></script>
</head>
<body>
<div class="app">
<h1>数组</h1>
<div v-for="i in l">{{i}}</div>
<h2>循环数组带索引</h2>
<div v-for="(i, b) in l">{{i}}---{{b}}</div>
<h1>对象</h1>
<div v-for="i in info">{{i}}</div>
<h2>对象,带key和value</h2>
<div v-for="(i, b) in info">{{i}}---{{b}}</div>
<h1>字符串</h1>
<div v-for="i in s">{{i}}</div>
<h2>字符串带索引</h2>
<div v-for="(i, b) in s">
<p v-if="i!=' '">{{i}}---{{b}}</p>
<br v-else>
</div>
<h1>数字</h1>
<div v-for="i in 9">{{i}}</div>
<h2>数字带索引</h2>
<div v-for="(i, b) in 9">{{i}}---{{b}}</div>
</div>
</body>
<script>
var vm = new Vue ({
el: '.app',
data: {
l: [1, 2, 3, 4],
info: {name: 'zyg', age: 18},
s: 'hello word'
}
})
</script>
</html>
js的循环方式
1.js的循环,基于索引的循环
var a = [1, 2, 3, 4, 5, 6]
for (i=0; i<a.length; i++){
console.log(i) // 拿的是索引位
console.log(a[i]) // 拿的是值
}
2. js的in循环,拿的也是索引
var a = [1, 2, 3, 4, 5, 6]
for (i in a) {
console.log(i) // 拿的是索引位
console.log(a[i]) // 拿的是值
}
3.js的of循环(ES6语法)
var a = [1, 2, 3, 4, 5, 6]
for (i of a) {
console.log(i) // 直接取值
}
4.针对数组的方法,forEach
var a = [1, 2, 3, 4, 5, 6]
a.forEach(function (i) {
console.log(i) // 直接取值
})
5.jQuery的循环,数组和对象
var a = [1, 2, 3, 4, 5, 6]
$.each(a, function(i, b) {
console.log(i)
console.log(b)
})
key值的解释
vue的v-for写在标签上,在标签上加一个key,用属性指令绑定一个变量,key的值每次都不一样,这样可以加速虚拟dom的替换,从而提高循环效率,key值必须唯一
<div v-for="item in 8" :key="item">{{item}}</div>
数组、对象的检测与更新
页面上已经有的可以直接修改,但是如果要新增需要使用Vue.set(this.info, 'key', 'value')
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div>
<div class="app">
<h1>循环对象</h1>
<div v-for="(value,key) in info">
<h3>key值是:{{key}}</h3>
<h2>value是:{{value}}</h2>
<hr>
</div>
<button @click="handleAdd">点我,加数据</button>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data: {
info: {name: 'lqz', age: 19},
},
methods: {
handleAdd() {
// 页面会变化
// this.info['name'] = '彭于晏'
// 页面不会变,单是值有了
// this.info['hobby'] = '篮球'
// 遇到数据变了,页面没变的情况,都是用
Vue.set(this.info, 'hobby', '篮球')
}
},
})
</script>
</html>
input事件
input的事件有
click 点击事件
input 当输入框输入的时候触发的事件,只要有输入就会触发
change 当元素的值改变的时候触发的事件,输入完成以后失去聚焦才会触发
blur 当输入框失去焦点的时候触发的事件
focus 获得焦点触发的事件
代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<script src="./js/vue.js"></script>
</head>
<body>
<div>
<div class="app">
<h1>点击事件</h1>
<input type="text" @click="handleClick">
<h1>失去焦点</h1>
<input type="text" @blur="handleBlur">
<h1>input事件</h1>
<input type="text" @input="handleInput">
<h1>change事件</h1>
<input type="text" @change="handleChange">
<h1>focus事件</h1>
<input type="text" @focus="handleFocus">
</div>
</div>
</body>
<script>
var vm = new Vue ({
el: '.app',
data: {},
methods: {
handleClick() {
alert('点击事件')
},
handleBlur() {
alert('失去焦点')
},
handleInput() {
alert('input事件')
},
handleChange() {
alert('change事件')
},
handleFocus() {
console.log('focus事件')
}
}
})
</script>
</html>
v-model双向数据绑定
input输入,如果使用 :value='变量' 这种形式,页面输入框会变,但是变量不变
使用v-model='变量'做了双向数据绑定后,变量随着页面输入框的变化而变化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<script src="./js/vue.js"></script>
</head>
<body>
<div>
<div class="app">
<h1>单项数据绑定</h1>
<input type="text" :value="name">{{name}}---单向数据绑定
<h1>双向数据绑定</h1>
<input type="text" v-model="age">{{age}}---双向数据绑定
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data:{
name: 'zyg',
age: 18
}
})
</script>
</html>
v-model进阶
lazy: 等待input框的数据绑定失去焦点之后再变化
number: 数字开头只保留数字后面的从字母出现开始不保留,字母开头全都保留
trim: 去除首尾的空格
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<script src="./js/vue.js"></script>
</head>
<body>
<div class="app">
<h1>lazy</h1>
<p><input type="text" v-model.lazy="name1">{{name1}}---</p>
<h1>number</h1>
<p><input type="text" v-model.number="name2">{{name2}}---</p>
<h1>trim</h1>
<p><input type="text" v-model.trim="name3">{{name3}}---</p>
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data: {
name1: '',
name2: '',
name3: '',
}
})
</script>
</html>
过滤
需求:根据输入框输入的字符搜索含有该字符的数据
数组过滤方法filter(),括号内放一个匿名函数
字符串的indexOf()方法,判断子字符串是否在当前字符串中,如果在返回的是索引,如果不在返回-1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<script src="./js/vue.js"></script>
</head>
<body>
<div>
<div class="app">
<p>请输入要搜索的内容:<input type="text" v-model="myText" @input="handleInput"></p>
<ul>
<li v-for="i in newDatalist">{{i}}</li>
</ul>
</div>
</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:{
handleInput(){
// 方式一
// var _this = this
// this.newDatalist = this.datalist.filter(function (item) { // item是从datalist中取出来的值
// return item.indexOf(_this.myText) >= 0 // 使用字符串的indexOf方法判断输入框输入的字符是否在datalist取出的字符串中
// })
// 方式二 使用箭头函数
this.newDatalist = this.datalist.filter(
item => item.indexOf(this.myText) >=0
)
}
}
})
</script>
</html>
箭头函数
箭头函数没有自己的this,用的都是上一级的this
1.原始函数
var f = function () {
console.log('函数')
}
2. 上面的变为箭头函数,也是无参数无返回值的箭头函数
var f = () => {
console.log('函数')
}
3. 有一个参数没有返回值的箭头函数
var f = item => {
console.log('函数')
}
4. 有多个参数,没有返回值的函数
var f = (item, index) => {
console.log('函数')
}
5. 有一个参数一个返回值
var f = (item) => {
return item
}
==> var f = item => {
return item
}
==> var f = item => item
事件修饰符
事件修饰符 | 释义 |
---|---|
.stop | 只处理自己的事件,阻止子控件冒泡 |
.self | 只处理自己的事件,子控件冒泡的事件不处理 |
.prevent | 阻止a链接的跳转 |
.once | 事件只会触发一次(适用于抽奖页面) |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div>
<div class="app">
<h1>事件修饰符stop,子控件不再冒泡给父控件</h1>
<ul @click='handleUl'>
<li @click.stop="handleLi">第一</li>
<li>第二</li>
</ul>
<h1>事件修饰符self:只处理自己的事件,子控件的冒泡,不处理</h1>
<ul @click.self='handleUl'>
<li @click="handleLi">第一</li>
<li>第二</li>
</ul>
<h1>prevent阻止a的跳转</h1>
<a href="http://www.baidu.com" @click.prevent="handleA">点我看美女</a>
<h1>once 只响应一次</h1>
<button @click.once="handleClick">点我抽奖</button>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data: {},
methods: {
handleLi() {
console.log('li被点击了')
},
handleUl() {
console.log('ul被点击了')
},
handleA() {
console.log('a标签被点了')
// 阻止a的跳转,自己决定要不要跳
// 手动指定跳
location.href = 'http://www.cnblogs.com'
},
handleClick() {
console.log('我被点了')
}
}
})
</script>
</html>
按键修饰符
按键事件
按了键盘上的键,就会触发函数的执行
案件修饰符
只有某个按键被按下,才会触发函数的执行
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div>
<div class="app">
<!-- <input type="text" v-model="text" @keyup="handleKeyUp">-–>{{text}}-->
<!-- <input type="text" v-model="text" @keyup.13="handleKeyUp2">-–>{{text}}-->
<input type="text" v-model="text" @keyup.enter="handleKeyUp2(1,$event)">--->{{text}}
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data: {
text: ''
},
methods: {
handleKeyUp(event) {
// console.log('按键被按下了')
// keyCode 对照表https://blog.csdn.net/zqian1994/article/details/109486445
// console.log('按钮被按下了:', event.key, event.keyCode)
if (event.keyCode == 13) {
console.log('开始跟后端交换搜索了')
}
},
handleKeyUp2(a, event) {
console.log(event)
console.log('enter被按了')
}
}
})
</script>
</html>
表单控制
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div>
<div class="app">
<p>用户名:<input type="text" v-model="username"></p>
<p>密码:<input type="password" v-model="password"></p>
<p>性别:
男:<input type="radio" v-model="gender" value="1">
女:<input type="radio" v-model="gender" value="2">
</p>
<p>记住密码:<input type="checkbox" v-model="remember"></p>
<p>爱好:
篮球:<input type="checkbox" v-model="hobby" value="篮球">
足球:<input type="checkbox" v-model="hobby" value="足球">
排球:<input type="checkbox" v-model="hobby" value="排球">
</p>
<button @click="handleClick">登录</button>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data: {
username: '',
password: '',
gender: '', // radio单选,多个radio绑定同一个变量,选中某个,就对应value值
remember: false, // checkbox 单选是true或false
hobby: [] // checkbox 多选是数组类型,必须一开始定义就是数组,多个checkbox绑定一个变量
},
methods: {
handleClick() {
console.log(this.username, this.password, this.gender, this.remember, this.hobby)
}
}
})
</script>
</html>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix