一.初识Vue
1. Vue是什么
1.1 概念:Vue是一个用于构建用户界面的渐进式框架
构建用户界面:基于数据渲染出用户看到的页面
渐进式:Vue相关的生态语法:**Vuejs:声明式渲染,组件系统;**客户端路由(VueRouter),大规模状态管理(Vuex),构建工具(Webpack / Vite)
框架:一套完整的项目解决方案,大大提高开发效率(70%)
1.2 Vue的两种使用方法
①Vue核心包开发,场景:局部模块改造
②Vue核心包&Vue插件工程化开发,场景:整站开发
2.创建Vue实例,初始化渲染
核心步骤:1.准备容器
2.引包(官网)-开发版本 / 生产版本
3.创建Vue实例 new Vue()
4.指定配置项→渲染数据:①el 指定挂载点②data 提供数据
<body>
<div id="app">
<h1>{{msg}}</h1>
<a href='#'>{{count}}</a>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
const app=new Vue({
//通过el配置选择器
el:'#app',
//通过data提供数据
data:{
msg:'hello 世界',
count:666
}
})
</script>
</body>
3.插值表达式(一种Vue的模板语法)
3.1作用:利用表达式进行插值,渲染到页面中
3.2语法:{{表达式}}
3.3注意点
(1)使用的数据必须存在(data)
(2)支持的是表达式,而非语法
(3)不能再标签属性中使用{{ }}插值
<body>
<div id="app">
<p>{{nickname}}</p>
<p>{{nickname.toUpperCase()}}</p>
<p>{{nickname+'你好'}}</p>
<p>{{age>=18?'成年':'未成年'}}</p>
<p>{{friend.name}}</p>
<p>{{friend.desc}}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
const app=new Vue({
//通过el配置选择器
el:'#app',
//通过data提供数据
data:{
nickname:'tony',
age:18,
friend:{
name:'Tom',
desc:'热爱学习Vue'
}
}
})
</script>
</body>
3.Vue响应式特性
比如:数据的响应式处理→响应式:数据变化,视图自动更新
如何访问or修改?data中的数据,最终会被添加到实例上
①访问数据:“实例 . 属性名”
②修改数据:“实例 . 属性名”=“值”
二.Vue指令(带有v-前缀的特殊标签属性)(官网→学习→API)
根据不同的指令,针对标签实现不同的功能
1.v-html:设置元素的innerHTML
<body>
<div id="app">
<div v-html="msg"></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
const app=new Vue({
//通过el配置选择器
el:'#app',
//通过data提供数据
data:{
msg:`
<a href="https://www.baidu.com/index.php?tn=68018901_58_oem_dg">
百度
</a>
`
}
})
</script>
</body>
2.v-show 与 v-if
(1)v-show
1.作用:控制元素显示隐藏
2.语法:v-show=“表达式” 表达式的值true显示,false隐藏
3.原理:切换display:none控制显示隐藏
4.场景:频繁切换显示隐藏的场景
(2) v-if
1.作用:控制元素显示隐藏(条件渲染)
2.语法:v-if=“表达式” 表达式的值true显示,false隐藏
3.原理:基于条件判断,是否创建或移除元素节点
4.场景:要么显示,要么隐藏,不频繁切换的场景
<body>
<style>
.box{
height: 100px;
width: 200px;
line-height: 100px;
text-align: center;
border-radius: 5px;
box-shadow: 2px 2px 2px black;
}
</style>
<div id="app">
<div v-show="flag" class="box">我是v-show控制的盒子</div>
<div v-if="flag" class="box">我是v-if控制的盒子</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
const app=new Vue({
//通过el配置选择器
el:'#app',
//通过data提供数据
data:{
flag:true
}
})
</script>
</body>
3.v-else 与 v-else-if
(1) 作用:辅助v-if 进行判断渲染
(2)语法:v-else(表否则)
v-else-if = “表达式”
(3) 注意:需要紧挨着v-if 一起使用
<body>
<div id="app">
<p v-if="gender===1">性别:♂男</p>
<p v-else>性别:♀女</p>
<hr>
<p v-if="score>=90">成绩A</p>
<p v-else-if="score>=70">成绩B</p>
<p v-else-if="score>=60">成绩C</p>
<p v-else>成绩D</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
const app=new Vue({
//通过el配置选择器
el:'#app',
//通过data提供数据
data:{
gender:1,
score:80
}
})
</script>
</body>
4.v-on
(1) 作用:注册事件=事件监听 + 提供处理逻辑
(2) 语法:
①v-on:事件名=“内联语句”(v-on:可替换为@)
<body>
<div id="app">
<button v-on:click="count--">-</button>
<span>{{count}}</span>
<button @mouseenter="count+=2">+</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
const app=new Vue({
//通过el配置选择器
el:'#app',
//通过data提供数据
data:{
count:100
}
})
</script>
</body>
②v-on:事件名=“methods中的函数名”
<body>
<div id="app">
<button @click="fn">切换</button>
<span v-show="isShow">黑马</span>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
const app=new Vue({
//通过el配置选择器
el:'#app',
//通过data提供数据
data:{
isShow:true
},
methods:{
fn(){
app.isShow=!app.isShow
}
}
})
</script>
</body>
3.注意:methods函数内的this指向Vue实例
5.v-on调用传参
小黑自动售货机
<body>
<div id="app">
<div class="box">
<h3>小黑自动售货机</h3>
<button @click="buy(5)">可乐5元</button>
<button @click="buy(10)">咖啡10元</button>
</div>
<p>银行余额:{{money}}元</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
const app=new Vue({
//通过el配置选择器
el:'#app',
//通过data提供数据
data:{
money:100
},
methods:{
buy(price){
this.money-=price
}
}
})
</script>
</body>
6.v-bind
(1) 作用:动态的设置HTML的标签属性→src url title
(2) 语法:v-bind:属性名=“表达式”
(3) 简写:v-bind:src → :src
图片切换案例
<body>
<div id="app">
<button v-show="index>0" @click="index--">上一页</button>
<div>
<img :src="list[index]" alt="">
</div>
<button v-show="index<list.length-1" @click="index++">下一页</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
const app=new Vue({
//通过el配置选择器
el:'#app',
//通过data提供数据
data:{
index:0,
list:[
'.imgs/1.gif',
'.imgs/2.gif',
'.imgs/3.gif',
'.imgs/4.gif',
'.imgs/5.gif',
'.imgs/6.gif',
]
}
})
</script>
</body>
7.v-for
(1)作用:基于数据循环,多次渲染整个元素 → 数组 (对象,数字…)
(2)遍历数组语法:v-for = “( item,index) in 数组” (item每一项,index下标)
小黑水果店
<body>
<div id="app">
<h3>小黑水果店</h3>
<ul>
<li v-for="(item,index)in list">
{{item}}-{{index}}
</li>
</ul>
<ul>
<li v-for="(item)in list">
{{item}}
</li>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
const app=new Vue({
//通过el配置选择器
el:'#app',
//通过data提供数据
data:{
index:0,
list:[ '西瓜','苹果','梨子']
}
})
</script>
</body>
(3) 图书管理案例-小黑的书架
<body>
<div id="app">
<h3>小黑的书架</h3>
<ul>
<li v-for="(item, index) in booksList" :key="item.id">
<span>{{ item.name }}</span>
<span>{{ item.author }}</span>
<!-- 注册点击事件 → 通过 id 进行删除数组中的 对应项 -->
<button @click="del(item.id)">删除</button>
</li>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
booksList: [
{ id: 1, name: '《红楼梦》', author: '曹雪芹' },
{ id: 2, name: '《西游记》', author: '吴承恩' },
{ id: 3, name: '《水浒传》', author: '施耐庵' },
{ id: 4, name: '《三国演义》', author: '罗贯中' }
]
},
methods: {
del (id) {
// console.log('删除', id)
// 通过 id 进行删除数组中的 对应项 → filter(不会改变原数组)
// filter: 根据条件,保留满足条件的对应项,得到一个新数组。
// console.log(this.booksList.filter(item => item.id !== id))
this.booksList = this.booksList.filter(item => item.id !== id)
}
}
})
</script>
</body>
(4)v-for中的key
语法:key属性 = " 唯一标识 "
作用:给列表项添加的唯一标识。便于Vue进行列表项的正确排序复用
v-for的默认行为会尝试原地修改元素(就地复用)
注意点:1.key的值只能是字符串或者数字类型
2.key的值必须具备唯一性
3.推荐使用id作为key(唯一),不推荐使用index作为key(会变化,不对应)
8.v-model
(1)作用:给表单元素使用,双向数据绑定 → 可以快速 获取 或者 设置 表单元素内容
①数据变化 → 视图自动更新
②试图变化 → 数据自动更新
(2)语法:v-model = ‘变量’
<body>
<div id="app">
<div class="box">
账户:<input type="text" v-model="username"><br><br>
密码:<input type="password" v-model="password"><br><br>
<button @click="login">登录</button>
<button @click="reset">重置</button>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
const app=new Vue({
//通过el配置选择器
el:'#app',
//通过data提供数据
data:{
username:'',
password:''
},
methods:{
login(){
console.log(this.username,this.password)
},
reset(){
this.username=''
this.password=''
}
}
})
</script>
</body>
三.综合案例 - 小黑记事本
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="./css/index.css" />
<title>记事本</title>
</head>
<body>
<!-- 主体区域 -->
<section id="app">
<!-- 输入框 -->
<header class="header">
<h1>小黑记事本</h1>
<input v-model="todoName" placeholder="请输入任务" class="new-todo" />
<button @click="add" class="add">添加任务</button>
</header>
<!-- 列表区域 -->
<section class="main">
<ul class="todo-list">
<li class="todo" v-for="(item, index) in list" :key="item.id">
<div class="view">
<span class="index">{{ index + 1 }}.</span> <label>{{ item.name }}</label>
<button @click="del(item.id)" class="destroy"></button>
</div>
</li>
</ul>
</section>
<!-- 统计和清空 → 如果没有任务了,底部隐藏掉 → v-show -->
<footer class="footer" v-show="list.length > 0">
<!-- 统计 -->
<span class="todo-count">合 计:<strong> {{ list.length }} </strong></span>
<!-- 清空 -->
<button @click="clear" class="clear-completed">
清空任务
</button>
</footer>
</section>
<!-- 底部 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 添加功能
// 1. 通过 v-model 绑定 输入框 → 实时获取表单元素的内容
// 2. 点击按钮,进行新增,往数组最前面加 unshift
const app = new Vue({
el: '#app',
data: {
todoName: '',
list: [
{ id: 1, name: '跑步一公里' },
{ id: 2, name: '跳绳200个' },
{ id: 3, name: '游泳100米' },
]
},
methods: {
del (id) {
// console.log(id) => filter 保留所有不等于该 id 的项
this.list = this.list.filter(item => item.id !== id)
},
add () {
if (this.todoName.trim() === '') {
alert('请输入任务名称')
return
}
this.list.unshift({
id: +new Date(),
name: this.todoName
})
this.todoName = ''
},
clear () {
this.list = []
}
}
})
</script>
</body>
</html>