Vue 简介
Vue 是一个用于"构建用户界面(基于数据渲染出用户看到的画面)" 的渐进式框架
基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="box">
<h1>{
{ msg }}</h1>
<p>{
{ num }}</p>
</div>
<!-- 引入的是开发版本的包 - 它包含完整的注释和警告 -->
<script src="./js/vue.js"></script>
<script>
// 创建实例
const boxObj = new Vue({
el: '.box',
data: {
msg: 'Hello World',
num: 520
}
})
// data中的内容绑定到了 boxObj 中,我们可以使用 boxObj.msg 和 boxObj.num 获得数据
console.log(boxObj.msg)
console.log(boxObj.num)
</script>
</body>
</html>
Vue 指令
v-html
作用:设置元素的 innerHTML
<body>
<div class="box">
<div v-html="msg"></div>
</div>
<script src="./js/vue.js"></script>
<script>
const boxObj = new Vue({
el: '.box',
data: {
msg: '<a href="https://www.baidu.com">百度</a>'
}
})
</script>
</body>
v-show
作用:控制元素显示隐藏
使用场景:频繁切换显示隐藏的场景
v-if
作用:控制元素显示隐藏(条件渲染)
使用场景:不频繁切换显示隐藏的场景
<body>
<!--
两者的区别:
v-show 底层原理:切换 css 的 display:none 来控制显示隐藏
v-if 底层原理:根据"判断条件"控制"元素节点"是否"创建"或"移除"
-->
<div class="box">
<div v-show="flag">我是v-show控制的盒子</div>
<div v-if="flag">我是v-if控制的盒子</div>
</div>
<script src="./js/vue.js"></script>
<script>
const boxObj = new Vue({
el: '.box',
data: {
flag: false // false 让元素隐藏,true 让元素显示
}
})
</script>
</body>
v-else
v-else-if
<body>
<div class="box">
<p v-if="gender === 1">性别:男</p>
<p v-else>性别:女</p>
<hr>
<p v-if="score >= 90">成绩为 A</p>
<p v-else-if="score >= 75">成绩为 B</p>
<p v-else-if="score >= 60">成绩为 C</p>
<p v-else>成绩为D</p>
</div>
<script src="./js/vue.js"></script>
<script>
const boxObj = new Vue({
el: '.box',
data: {
gender: 1,
score: 80
}
})
</script>
</body>
v-on
作用:注册事件(即:添加监听 + 逻辑处理)
<body>
<div class="box">
<button v-on:click="count--">-</button>
<span>{
{ count }}</span>
<button @click="count++">+</button> <!-- v-on:click 可以简写为 @click -->
</div>
<script src="./js/vue.js"></script>
<script>
const boxObj = new Vue({
el: '.box',
data: {
count: 100
}
})
</script>
</body>
<body>
<div class="box">
<button @click="showChange">显示或隐藏</button>
<h1 v-show="isShow">Hello World</h1>
</div>
<script src="./js/vue.js"></script>
<script>
const boxObj = new Vue({
el: '.box',
data: {
isShow: true
},
// 这里提供函数,处理复杂的业务逻辑
methods: {
showChange() {
this.isShow = !this.isShow } // 这里的this指的是boxObj
// ...
}
})
</script>
</body>
<body>
<div class="box">
<h1>账户余额: {
{ money }}元</h1>
<button @click="buy(8)">冰淇淋8元</button>
<button @click="buy(15)">奶茶15元</button>
</div>
<script src="./js/vue.js"></script>
<script>
const boxObj = new Vue({
el: '.box',
data: {
money: 100
},
methods: {
buy(price) {
this.money -= price
}
}
})
</script>
</body>
v-bind
作用:动态的设置标签属性
<body>
<div class="box">
<img v-bind:src="imgURL" v-bind:alt="msg">
<!-- 如果觉得上面的写法太复杂,可以简写成下面的形式 -->
<img :src="imgURL" :alt="msg">
</div>
<script src="./js/vue.js"></script>
<script>
const boxObj = new Vue({
el: '.box',
data: {
imgURL: './images/img0.png',
msg: 'Jack'
}
})
</script>
</body>
<body>
<div class="box">
<!-- 要求实现:除了top之外,为这个div继续添加类名 className1、className3 -->
<!-- 方法一 -->
<div class="top" :class="{ className1: true, className2: false, className3: true }"></div>
<!-- 方法二 -->
<div class="top" :class="['className1, className3']"></div>
</div>
<script src="./js/vue.js"></script>
<script>
const boxObj = new Vue({
el: '.box',
data: {
}
})
</script>
</body>
<body>
<div class="box">
<span>当前盒子宽度: {
{ wd }}</span><br>
<span>当前盒子高度: {
{ ht }}</span><br>
<button @click="wd++">横向拉长</button>
<button @click="ht++">纵向拉长</button><hr>
<div class="inner" :style="{ 'width': wd + 'px', 'height': ht + 'px', 'background-color': bgc }"></div>
</div>
<script src="./js/vue.js"></script>
<script>
const boxObj = new Vue({
el: '.box',
data: {
wd: 100,
ht: 50,
bgc: 'pink'
}
})
</script>
</body>
v-for
- 基本使用
<body>
<div class="box">
<h3>城市列表</h1>
<ul>
<li v-for="(item, index) in list">{
{ item }} || {
{ index }}</li>
<!-- 上面的index如果不需要的话,可以写成下面的形式 -->
<li v-for="item in list">{
{ item }}</li>
</ul>
</div>
<script src="./js/vue.js"></script>
<script>
const boxObj = new Vue({
el: '.box',
data: {
list: ['北京', '上海', '广州', '深圳']
}
})
</script>
</body>
- key 作用:给元素添加唯一的标识,便于 Vue 进行列表项的正确排序复用
- 注意:key 的值只能是"字符串"或数字类型,且必须具有唯一性
<body>
<div class="box">
<h3>我的收藏</h1>
<ul>
<li v-for="item in list" v-bind:key="item.id">
<span>{
{ item.name }}</span>
<span>{
{ item.time }}</span>
<button @click="move(item.id)">取消收藏</button>
</li>
</ul>
</div>
<script src="./js/vue.js"></script>
<script>
const boxObj = new Vue({
el: '.box',
data: {
list: [
{
id: 1, name: '水杯', time: '中午' },
{
id: 2, name: '茶壶', time: '傍晚' },
{
id: 3, name: '电脑', time: '清晨' },
{
id: 4, name: '毛巾', time: '下午' }
]
},
methods: {
move(id) {
this.list = this.list.filter(item => item.id !== id)
}
}
})
</script>
</body>
v-model
作用:给 表单元素
使用,双向数据绑定,可以快速获取或设置表单元素内容
<body>
<!--
v-model 可以让数据和视图,形成双向数据绑定
(1)数据变化,视图自动更新
(2)视图变化,数据自动更新
-->
<div class="box">
账户:<input type="text" v-model="username"> <br>
密码:<input type="password" v-model="password"> <br>
<button @click="reset">重置</button>
</div>
<script src="./js/vue.js"></script>
<script>
const boxObj = new Vue({
el: '.box',
data: {
username: '',
password: ''
},
methods: {
reset() {
this.username = ''
this.password = ''
}
}
})
</script>
</body>
<body>
<div class="box">
<form action="http://127.0.0.1/">
姓名: <input type="text" name="username" v-model="usernameYX">
<br><br>
是否成年: <input type="checkbox" name="isAdult" v-model="isAdultYX">
<br><br>
性别:
<input type="radio" name="gender" value="1" v-model="genderYX">男
<input type="radio" name="gender" value="0" v-model="genderYX">女
<br><br>
所在城市:
<select name="city" v-model="cityYX">
<option value="北京">北京</option>
<option value="上海">上海</option>
<option value="广州">广州</option>
<option value="深圳">深圳</option>
</select>
<br><br>
自我描述:
<textarea name="selfDescribe" v-model="descYX"></textarea>
<button type="submit">点击提交</button>
</form>
</div>
<script src="./js/vue.js"></script>
<script>
const boxObj = new Vue({
el: '.box',
data: {
usernameYX: '',
isAdultYX: true,
genderYX: '1',
cityYX: '深圳',
descYX: "请在这里输入..."
}
})
</script>
</body>
指令修饰符
@keyup.enter | 键盘回车监听 |
---|---|
v-model.trim | 去除首尾空格 |
v-model.number | 转为数字类型 |
@事件名.stop | 阻止冒泡 |
@事件名.prevent | 阻止默认行为 |
<body>
<div class="box">
<input @keyup.enter="warn" v-model="username" type="text">
</div>
<script src="./js/vue.js"></script>
<script>
const boxObj = new Vue({
el: '.box',
data: {
username: ''
},
methods: {
warn() {
this.username = '输入错误,请重试'
}
}
})
</script>
</body>
计算属性(简写)
概念:
基于现有的数据,计算出来的新属性。依赖的数据变化,自动重新计算
注意:
计算属性,是有缓存功能的,一旦计算出来结果,就会立即缓存,如果依赖项没有变化,则当我们再次调用时,是会直接读取缓存的结果,而不是像methods 那样调用一次执行一次代码
对比:
computed 计算属性 VS methods 方法:
1. computed 偏向计算,偏向对数据的处理,通过它的缓存的特性,可以将非常复杂的计算的结果缓存下来,只要依赖项没有发生变化,它的结果就一定没有变化,直接从缓存中读取上一次保留的结果即可
2. methods 偏向处理业务逻辑
语法:(演示如下)
<body>
<div class="box">
<h3>购物车清单</h3>
<table style="border: 1px solid #000;">
<tr>
<th>名字</th>
<th>数量</th>
</tr>
<tr v-for="item in list" :key="item.id">
<td>{
{ item.name }}</td>
<td>{
{ item.num }}</td>
</tr>
</table>
<p>物品总数:{
{ totalCount }}个</p>
</div>
<script src="./js/vue.js"></script>
<script>
const boxObj = new Vue({
el: '.box',
data: {
list: [
{
id: 1, name: '卫衣', num: 3 },
{
id: 2, name: '帽子', num: 7 },
{
id: 3, name: '墨镜', num: 2 }
]
},
computed: {
totalCount() {
// 使用 reduce 求和
const total = this.list.reduce((sum, item) => sum + item.num, 0)
// 一定要记得返回结果
return total
}
}
})
</script>
</body>
计算属性(完整写法)
- 计算属性默认的简写,只能读取访问,不能"修改"
- 如果要"修改",需要写计算属性的完整写法
<body>
<div class="box">
姓: <input type="text" v-model="firstName">+
名: <input type="text" v-model="lastName">=
<span>{
{ fullName }}</span><br><br>
改名为: <input type="text" v-model="nameIs">
<button @click="changeName">确认改名</button>
</div>
<script src="./js/vue.js"></script>
<script>
const boxObj = new Vue({
el: '.box',
data: {
firstName: '',
lastName: '',
nameIs: ''
},
methods: {
changeName() {
this.fullName = this.nameIs
}
},
computed: {
// 下面是简写形式(这样写只能读,不能改)
// fullName() {
// return this.firstName + this.lastName
// }
// 完整的写法 -> 获取 + 设置
fullName: {
// 当fullName计算属性被"获取求值"时,执行get(如果有缓存,优先读取缓存)
get() {
return this.firstName + this.lastName },
// 当fullName计算属性被"修改赋值"时,执行set(修改的值,转递给set方法的形参)
set(value) {
this.firstName = value.slice(0, 1) // 截取字符串的第一个字符
this.lastName = value.slice(1) // 截取字符串剩下的字符
}
}
}
})
</script>
</body>
监视器(简写)
作用:监视数据变化,执行一些业务逻辑或异步操作
<body>
<div class="box">
请输入简体中文: <input type="text" v-model="words"><br>
对应的外星语言: <input type="text" v-model="translation">
</div>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="./js/vue.js"></script>
<script>
const boxObj = new Vue({
el: '.box',
data: {
words: '',
translation: '',
obj: {
picture: ''
}
},
watch: {
// 监视obj.picture,该方法会在数据变化时执行,形参里的oldValue可以省略
// 'obj.picture'(newValue, oldValue) {
// console.log('变化了', newValue)
// }
// 监视words,该方法会在数据变化时执行
words(newValue, oldValue) {
// 防抖: 为了解决访问过快对服务器造成太大压力的问题,我们可以设置一些延迟,本例中延时400ms
clearTimeout(this.timer)
this.timer = setTimeout(async () => {
// 直接给boxObj这个实例挂载timer属性
const res = await axios({
url: 'https://applet-base-api-t.itheima.net/api/translate/',
params: {
words: newValue
}
})
this.translation = res.data.data
}, 400)
}
}
})
</script>
</body>
监视器(完整写法)
<body>
<div class="box">
翻译成:
<select name="language" v-model="obj.lang">
<option value="001">简体中文</option>
<option value="002">英文</option>
<option value="003">意大利语</option>
</select><br>
要翻译的语言: <input type="text" v-model="obj.words"><br>
翻译内容结果: <input type="text" v-model="translation">
</div>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="./js/vue.js"></script>
<script>
const boxObj = new Vue({
el: '.box',
data: {
// 要监视的对象
obj: {
lang: '002',
words: '',
},
// 翻译结果
translation: ''
},
watch: {
obj: {
deep: true, // 深度监视
// immediate: true, // 初始化立即执行一次handler方法
handler(newValueObj) {
// 实现防抖功能,人为制造延迟(400ms),减轻服务器压力
clearTimeout(this.timer) // 让boxObj挂载timer属性
this.timer = setTimeout(async () => {
const res = await axios({
url: 'https://applet-base-api-t.itheima.net/api/translate/',
params: newValueObj
})
console.log(res)
this.translation = res.data.data
}, 400)
}
}
}
})
</script>
</body>