vue相关介绍
Vue的两种使用方式:
1、vue核心包开发
场景:局部模块改造
2、vue核心包&vue插件工程化开发
场景:整站开发
概念:vue是用于构建用户界面的渐进式框架
创建vue实例
- 创建Vue实例,初始化渲染步骤:
- 准备容器
- 引包(官网)(开发版本的包/生产版本的包)
- 创建Vue实例 new vue()
- 指定配置项→渲染数据
- el指定挂载点(即指明渲染的是哪一个地方,填写的是选择器)
- data提供数据
<!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 id = "app">{{msg}}
</div>
<!-- 引入开发版本的核心包 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>//一旦引入了vue.js核心包,在全局环境,就有了vue构造函数const app = new Vue({// 通过el配置选择器,指定el管理是哪一个盒子el:'#app',// 通过data提供数据data:{msg:'666',}})
</script>
</body>
</html>
插值表达式{{ }}
插值表达式是一种vue模板语法
作用:利用表达式进行插值,渲染到页面中,其中表达式是一种可以被求值的代码,JS引擎会将其计算出一个结果
语法:{{表达式}}
注意点:
1、使用数据时,数据必须是存在的
2、支持的是表达式(还可以是拼接字符串),而非语句,比如if for
3、不能在标签属性中使用{{ }}插值
<p title="{{username}}">我是标签</p>
vue响应式特性
响应式:数据变化,视图自动更新
vue指令
指令:带有v-前缀的特殊标签属性
指令—v-html
<!-- vue指令:v-前缀的标签属性 -->
<div v-html = "str"></div>
作用:设置元素的innerHTML
语法:v-html = ”表达式“
<!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 id = "app"><div v-html ='msg'></div></div><script src="./vue.js"></script>
<script>const app = new Vue({el:'#app',data:{msg:'<a href = "http://www.itheima.com">黑马</a>'}})</script>
</body>,
</html>
vue指令v-show vs v-if
v-show
1、作用:控制元素显示隐藏
2、语法:v-show=”表达式“,表达式值true显示,否则隐藏
3、底层原理:切换css的display:none来控制显示隐藏
4、使用场景:频繁切换显示隐藏场景
v-if
1、作用:控制元素显示隐藏(条件渲染)
2、语法:v-if=”表达式“,表达式值true显示,否则隐藏
3、底层原理:根据判断条件控制元素的创建和移除
4、使用场景:要么显示,要么隐藏,不频繁切换的场景
<!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 id = "app"><div v-show = "flag" class = "box">我是show</div><div v-if = "flag" class = "box">我是if</div><div class = "box">我是if</div>
</div><script src="./vue.js"></script>
<script>const app = new Vue({el:'#app',data:{flag:false}})</script>
</body>
</html>
vue指令v-else v-else-if
1、作用辅助v-if进行判断渲染
2、语法:v-else v-else-if= ”表达式“
3、注意:需要紧挨着v-if一起使用
<!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 id = "app"><p v-if = "sex == 1">性别:男</p><p v-else>性别:女</p><hr><p v-if = "grade >= 90">成绩评定A:奖励电脑一台</p><p v-else v-else-if = "grade < 90 && grade >= 80">成绩评定B</p><p v-else v-else-if = "grade < 80 && grade >= 70">成绩评定C</p><p v-else v-else-if = "grade < 70">成绩评定D</p>
</div><script src="./vue.js"></script>
<script>const app = new Vue({el:'#app',data:{grade:58,sex:8}})</script>
</body>,
</html>
指令v-on
1、作用:注册事件 = 添加监听 + 提供处理逻辑
2、语法:
- v-on:事件名=”内联语句“
- v-on:事件名=”methods中的函数名“
内联语句示例:
<!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 id = "app"><!-- click可以换做划入等动作,例如mouseenter,v-on:这一部分可以被替换为@ --><button v-on:click="count++">+</button><!-- <button @click="count++">+</button> --><span>{{count}}</span><button v-on:click="count--">-</button><!-- <button @click="count--">-</button> -->
</div><script src="./vue.js"></script>
<script>const app = new Vue({el:'#app',data:{count:0}})</script>
</body>
</html>
函数名示例:
<!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 id = "app"><button @click = "isDisplay">切换显示隐藏</button><h1 v-show = "isShow">黑马程序员</h1>
</div><script src="./vue.js"></script>
<script>const app = new Vue({el:'#app',data:{isShow:true},methods:{isDisplay(){this.isShow = !this.isShow;}}})</script>
</body>
</html>
v-on调用传参
<!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 id = "app"><div class = "box"><h3>小黑自动售货机</h3><button @click = "buy(5)">可乐5元</button><button @click = "buy(10)">咖啡10元</button></div><div>银行卡余额:{{money}}</div>
</div><script src="./vue.js"></script>
<script>const app = new Vue({el:'#app',data:{money:100},methods:{buy(price){this.money -= price;}}})</script>
</body>
</html>
指令v-bind
1、作用:动态的设置html的标签属性 → src url title......
2、语法:v-bind:属性名 = ”表达式“,即是将表达式的值设置给前面的属性名,后面的表达式一定是已经被定义过的,否则会报错
<!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 id = "app">
<!-- 简写方式直接 v-bind:src → :src --><img v-bind:src="imgURL" alt="">
</div><script src="./vue.js"></script>
<script>const app = new Vue({el:'#app',data:{imgURL:'./images/taobao.jpg'},})</script>
</body>
</html>
指令v-for
1、作用:基于数据循环,多次渲染整个元素,可以遍历数组、对象、数字等
<!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 id = "app"><h3>小黑水果店</h3><ul><!-- list[index] 也可以用item表示,for后面的括号里面也可以只有item省略index--><li v-for="(item , index) in list">{{list[index]}}</li></ul>
</div><script src="./vue.js"></script>
<script>const app = new Vue({el:'#app',data:{list:['西瓜', '苹果', '香蕉']},})</script>
</body>
</html>
案例展示:图书管理案例
明确需求:
1、基本渲染
2、删除功能
<!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 id = "app"><h3>小黑的书架</h3><ul><li v-for="(item , index) in bookList"><span>{{ item.name }}</span><span>{{ item.author }}</span><!-- 注册点击事件,通过id进行删除数组中的数据 --><button @click="del(item.id)">删除</button></li></ul>
</div><script src="./vue.js"></script>
<script>const app = new Vue({el:'#app',data:{bookList:[{id:1, name:'《红楼梦》', author:'曹雪芹'},{id:2, name:'《西游记》', author:'吴承恩'},{id:3, name:'《水浒传》', author:'施耐庵'}]},methods:{del(id){// filter:根据条件,保留满足条件的对影响,得到一个新数组this.bookList = this.bookList.filter(item => item.id!== id)}}})</script>
</body>
</html>
指令v-for的key
语法:key属性 = ”唯一标识“
作用:给列表项添加唯一标识。便于vue进行列表项的正确排序复用
没有加key的情况:
点击删除:
可以发现粉色的背景颜色依然存在
而加上key后:
v-for的默认行文会尝试原地修改元素,也就是当我们删除三个元素中的第一个元素时候,如果没有加那么就相当于删除的是最后一个元素,然后将文字位置进行对应的修改
注意点:
key的值只能是字符串或数字
key的值必须具有唯一性
推荐使用id作为key
指令v-model
1、作用:给表单元素使用,双向数据绑定→可以快速获取或设置表单元素内容
数据变化→视图自动更新
视图变化→数据自动更新
2、语法:v-model=‘变量’
<!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 id = "app"><!-- -->账户:<input type="text" v-model="username"><br><br>密码:<input type="password" v-model="pwd" ><br><br><button v-on:click="login">登录</button><button v-on:click="reset">重置</button>
</div><script src="./vue.js"></script>
<script>const app = new Vue({el:'#app',data:{username:'',pwd:''},methods:{login(){console.log(this.username);console.log(this.pwd);},reset(){this.username='';this.pwd='';}}})</script>
</body>
</html>
综合案例:小黑记事本
功能需求:
1、列表渲染
2、删除功能
3、添加功能
4、底部统计和清空
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>input[type="text"] {border: 1px solid black;border-radius: 5px;padding: 5px;} </style>
</head>
<body><div id="app"><div><h3>记事本</h3><div><input type="text" v-model="content"><!-- 添加功能1、通过v-model绑定输入框,实时获取表单元素的内容2、点击按钮,进行新增--><button @click="add" >添加</button></div><div><ul><li v-for="(item,index) in list" :key="item.id"><span>{{index + 1}}</span><span>{{item.content}}</span><button @click="del(item.id)">删除</button></li></ul><span>合计{{list.length}}</span><button @click="clear">清空</button></div></div>
</div>
<script src="./vue.js"></script>
<script>const app = new Vue({el:'#app',data:{list:[{id:1,content:'跑步1公里'},{id:2,content:'跳绳200次'},{id:3,content:'游泳100米'}]},methods:{add(){this.list.push({id:this.list.length+1,content:this.content})},del(id){this.list = this.list.filter(item => item.id!== id)},clear(){this.list = []}}})</script>
</body>
</html>
指令修饰符
通过”."指明一些指令后缀,不同后缀封装了不同的处理操作→简化代码
1、按键修饰符
@keyup.enter→键盘回车监听(没有加后缀的时候按住任意键都可出发监听,但是加上了就只能通过回车触发)
因此既可通过点击添加按钮添加任务,也可以通过回车
2、v-model修饰符
v-model.trim→去除首尾空格
v-model.number→转数字
输入年龄的时候,原来是实际上是字符串,使用.number可以将其转换为数字,但是如果输入的不是数字得到的仍然是字符串
3、事件修饰符
@事件名.stop→阻止冒泡
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.father{width: 200px;height: 200px;background-color:red;}.son{width: 100px;height: 100px;background-color:blue;}</style>
</head>
<body><div id="app"><div @click="father" class="father"><div @click.stop="son" class="son"></div></div>
</div>
<script src="./vue.js"></script>
<script>const app = new Vue({el:'#app',data:{username:'',age:''},methods:{father(){alert('父亲被点击了')},son(){alert('儿子被点击了')}}})</script>
</body>
</html>
在加上后缀之前,点击儿子的时候会触发点击父亲的事件,但是当加上后缀之后就不会触发父亲事件
@事件名.prevent→阻止默认行为
v-bind对于样式控制的增强
为了方便开发者进行样式控制,vue扩展了v-bind的语法,可以针对class类名和style行内样式进行控制
操作class
语法:
:class = "对象/数组"
1、对象→键就是类名,值是布尔值,如果值为true,有这个类,否则没有这个类
<div class="box" :class="{类名:布尔值,类名2:布尔值}"></div>
试用场景:一个类名,来回切换
2、数组→数组中所有的类,都会添加到盒子上,本质就是一个class列表
<div class="box" :class="[类名1,类名2,类名3]"></div>
试用场景:批量添加或删除类
三种表示方式具有相同的效果
导航高亮案例
点击哪一个哪一个就显示高亮
核心思路:
1、基于数据动态渲染tab
2、准备下标记录高亮的是哪一个tab
3、基于下标,动态控制class类名
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>/* li标签中的a作为顶部并排的导航 */ul {list-style-type: none;padding: 0;margin: 0;overflow: hidden;background-color: #333;}li {float: left;}li a {display: block;color: white;text-align: center;padding: 14px 16px;text-decoration: none;}/* 鼠标移入li变色 */.active{background-color: pink;}</style>
</head>
<body><div id="app"><ul><!-- 点击切换activeIndex的值 --><li v-for="(item, index) in list" :key="item.id" @click="activeIndex = index"><a href="#" :class="{active:index === activeIndex}">{{item.name}}</a></li></ul></div><script src="./vue.js "></script><script>const app = new Vue({el:'#app',data:{// 记录高亮activeIndex:0,list:[{id:1, name:'京东秒杀'},{id:2, name:'每日特价'},{id:3, name:'品类秒杀'}]}})</script>
</body>
</html>
v-bind对于样式控制增强-操作styl
语法:
:style=“样式对象”
注意点:属性值需要用引号引起来,当属性名含有‘-’时也需要用引号
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.box{width:200px;height:200px;background-color: pink;}</style>
</head>
<body><div id="app"><div class="box" :style="{width:'400px', height:'400px', 'background-color':'green'}"></div></div><script src="./vue.js "></script><script>const app = new Vue({el:'#app',data:{// 记录高亮activeIndex:0,list:[{id:1, name:'京东秒杀'},{id:2, name:'每日特价'},{id:3, name:'品类秒杀'}]}})</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.progress{/* 圆角矩形 */border-radius: 10px;/* 边框 */border: 1px solid #ccc;/* 背景色 */background-color: black;width:200px;}.inner{/* 圆角矩形 */border-radius: 10px;/* 边框 */border: 1px solid #ccc;background-color: blue;height:100%;}</style>
</head>
<body><div id="app"><div class="progress"><div class="inner" :style="{width:percent + '%'}"><span>{{percent}}%</span></div></div><div><button @click="percent = 25">设置25%</button><button @click="percent = 50">设置50%</button><button @click="percent = 100">设置100%</button></div></div><script src="./vue.js "></script><script>const app = new Vue({el:'#app',data:{percent:30}})</script>
</body>
</html>
v-model应用于其他表单元素
常见的表单元素都可以用v-model绑定关联→快速获取或设置表单元素的值
它会根据控件类型自动选取正确的方法来更新元素
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style></style>
</head>
<body><div id="app"><h1>小黑学习网</h1><br><br>姓名:<input type="text" v-model="username"><br><br>是否单身:<input type="checkbox"><br><br>性别:<!-- 1、name:给单选框加上name属性,可以分组,同一组相互会互斥2、value:给单选框加上value属性,用于提交给后台数据--><input type="radio" name="gender" value="1" v-model="gender" >男<input type="radio" name="gender" value="2" v-model="gender" >女<br><br>所在城市:<!-- 1、option需要设置value值,提交给后台2、select的value值,关联了选中的value值--><select v-model="cityId"><option value="101">北京</option><option value="102">上海</option><option value="103">成都</option></select><br><br>自我描述:<br><br><textarea v-model="desc" name="" id="" cols="30" rows="10"></textarea><br><br><button>注册</button></div><script src="./vue.js "></script><script>const app = new Vue({el:'#app',data:{username:'',gender:1,cityId:'101',desc:""}})</script>
</body>
</html>
计算属性
概念:
基于现有的数据,计算出来的新属性,依赖数据变化,自动重新计算
语法:
1、声明在computed配置项中,一个计算属性对应一个函数
2、使用起来和普通属性一样使用{{计算属性名}}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>/* 表格每一项都有边框*/table {border: 1px solid #ccc;}/* 表格每一项都有边框*/table th {width:50px;border: 1px solid #ccc;}/* 文字居中显示 */td, th {text-align: center;}table td {width:50px;border: 1px solid #ccc;}</style></style>
</head>
<body><div id="app"><table><tr><th>名字</th><th>数量</th></tr><tr v-for="(item , index) in list" :key="item.id"><td>{{item.name}}</td><td>{{item.num}}</td></tr><br><br></table><!-- 不能加括号 --><div>礼物总数为:{{totalCount}}个</div></div><script src="./vue.js "></script><script>const app = new Vue({el:'#app',data:{list:[{id:1, name:'篮球', num:1},{id:2, name:'足球', num:2},{id:3, name:'排球', num:3},{id:4, name:'气球', num:4}]},computed:{totalCount(){// 基于现有数据,编写求值逻辑// 计算属性函数内部,可以直接通过this访问到app实例let total = this.list.reduce((sum, item) => sum + item.num, 0);return total;}}})</script>
</body>
</html>
计算属性vs方法methods
计算属性:
作用:封装了一段对于数据的处理,求得一个结果
缓存特性(提升性能):
计算属性会对计算出来 的结果缓存,再次使用直接读取缓存,依赖项变化了,会自动重新计算,并再次缓存
methods方法:
作用:给实例提供一个方法,调用来处理业务逻辑
计算属性完整写法
计算属性默认的简写,只能读取访问,不能修改
如果要修改,需要写出计算属性的完整写法
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style></style>
</head>
<body><div id="app">姓:<input type="text" v-model="firstName"> + 名:<input type="text" v-model="lastName"> = <span>{{fullName}}</span><br><br><button @click="changeName">改名卡</button></div><script src="./vue.js "></script><script>const app = new Vue({el:'#app',data:{firstName:'刘',lastName:"备"},methods:{changeName(){this.fullName = fullName;}},computed:{fullName:{// 当fullName计算属性,被获取求值时,执行get(有缓存优先读缓存),// 会将返回值作为求值的结果get(){return this.firstName + this.lastName},set(){this.firstName = firstName;this.lastName = lastName;}}}})</script>
</body>
</html>
watch侦听器 (监视器)
作用:监视数据变化,执行一些业务逻辑或异步操作
语法:
1、简答类型,简单类型数据直接监视
2、完整写法,添加额外配置项
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>/* 为文本输入框添加边框 */</style>
</head>
<body><div id="app"><!-- 翻译框 --><div class="box"><textarea v-model="words" cols="30" rows="10">老值</textarea><textarea v-model="person.name" cols="30" rows="10"></textarea></div>
</div><script src="./vue.js"></script>
<script>const app = new Vue({el:'#app',data:{words:'',person:{name:''}},methods:{},watch:{words(newValue, oldValue){console.log('变化了',newValue,oldValue);},'person.name'(newValue){console.log('变化了',newValue);}}})</script>
</body>
</html>