第二章:vue指令和事件处理 回顾:vue:
vue ?
发展历史,产生背景
优势:
核心:数据决定视图,双向数据绑定
MVC:
三层架构:
全栈工程师开发实战之从入门到技术实战之02--vue指令_javascript MVVM: Model View ViewModel vue的实例对象
本章目标了解什么是 Vue.js 指令理解 Vue.js 指令的用途掌握 Vue.js 指令的书写规范能够使用 Vue.js 指令完成部分页面交互效果 一、vue指令 1.1 相关插件安装高亮代码括号的插件
全栈工程师开发实战之从入门到技术实战之02--vue指令_javascript_02vue的代码提示插件
全栈工程师开发实战之从入门到技术实战之02--vue指令_javascript_03[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6kqd13Tt-1654938578648)(assets/image-20220202161926801.png)]
标签重命名插件
全栈工程师开发实战之从入门到技术实战之02--vue指令_javascript_04 1.2 什么是 Vue指令指令 (Directives) 是带有 v- 前缀的特殊 attribute。指令 attribute 的值预期是单个 JavaScript 表达式。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。解析模板/标签(标签属性,标签体内容,绑定事件等)
例如:
代码语言:javascript复制//点击toggle按钮,会显示红色方块,再次点击,红色方块消失,这里就是通过控制属性的真假,通过指令作用到红色方块上来控制方块的显示隐藏
全栈工程师开发实战之从入门到技术实战之02--vue指令_vue.js_05 1.3 Vue.js 指令的书写规范代码语言:javascript复制//书写位置:任意 HTML 元素的开始标签内现在你看到我了
//注意:一个开始标签内可写入多个指令,多个指令间使用空格分隔
全部 1.4 常用指令v-text
语法格式:v-text='表达式'作用相当于之前学习的DOM操作中的innerText属性,会直接覆盖元素中原本的文本内容,实际开发中使用不多代码语言:javascript复制
let app = new Vue({
el:'p',
data:{
stat:true,
name:'张三'
}
})
v-html
语法格式:v-html='表达式'作用相当于DOM操作中的innerHTML属性,可以识别字符串中的标签。全栈工程师开发实战之从入门到技术实战之02--vue指令_前端_06代码语言:javascript复制
let app = new Vue({
el:'p',
data:{
msg:'
你好哈哈哈
'}
})
**v-if v-else-ifv-else **
作用等同于js代码中的 if else if elseif else 帮助我们按照需求去控制DOM元素的显示与隐藏。
语法格式:v-if='表达式'v-else-if='表达式'v-else='表达式'注意: v-if 和后续的v-else-if v-else都要连续使用,如果中间有间隔,效果是可以正常显示的,但是,控制台会报错。这个特性针对操作同级元素的时候来说。代码语言:javascript复制
- 你好哈哈1
- 你好哈哈2
- 你好哈哈3
- 你好嘿嘿1
- 你好嘿嘿2
- 你好嘿嘿3
let app = new Vue({
el: '#max',
data: {
num: 9
}
})
v-show
控制元素是否显示,作用等同于css样式的display:none 或非none
语法格式:v-show='true/false'; true为显示,false为不显示代码语言:javascript复制
你好哈哈哈
let app = new Vue({
el:'#max',
data:{
stat:true,
},
methods:{
tiggleShow(){
this.stat = !this.stat;
}
}
})
代码语言:javascript复制v-if与v-show区别:
v-show指令的元素始终会被渲染到HTML
它只是简单地为元素设置CSS的style属性。当不满足条件的元素被设置style="display:none"样式
v-if指令满足条件是,会渲染到html中,不满足条件时,是不会渲染到html中的
v-if 指令有更高的切换消耗
v-if当条件成立的时候会将元素加上,不成立的时候,就会移除dom,并且内部的指令不会执行
v-show 指令有更高的初始渲染消耗
v-show只是简单的隐藏和显示
如果需要频繁切换使用 v‐show 较好,如果在运行时条件不大可能改变 使用v‐if 较好v-for 循环遍历 #*
v-for的作用等同于js代码中的for循环,用于循环生成DOM结构,想循环哪个DOM结构,就在哪个DOM结构上添加v-for。
但凡使用到v-for的地方 必须添加第二个属性 :key=‘id’代码语言:javascript复制
- {{item}}
- {{key}}--{{val}}--{{i}}
- {{item}}
let app = new Vue({
el: '#box',
data: {
arr: ['a', 'b', 'c'],
user: { "name": '张三', "age": 18, "address": '郑州' },
str:'abcdefg'
}
})
v-on 绑定事件和事件处理
vue的绑定事件的方式,只需要把原生事件名字的on去掉就可以了
例如: onclick === > @click/v-on:click onblur ===> @blur/v-on:blur普通用法代码语言:javascript复制为 HTML 元素绑定事件监听
v-on:事件名称 =‘函数名称()’
表达式可以是一个方法的名字或一个内联语句
简写语法:@事件名称 =‘函数名称()’
注意:函数定义在 methods 配置项中
v-on: 可以简写成 @
v-bind
作用:为元素的属性 动态的绑定值代码语言:javascript复制v-bind可以在其名称后面带一个参数,参数通常是HTML元素的属性(attribute),v-bind是动态绑定指令,默认情况下自带属性的值是固定的,为了能够动态的给这些属性添加/修改值可以使用v-bind指令
v-bind:属性名 = ‘表达式’
简写形式:v-bind可以省略,直接书写为 :属性名 = ‘表达式’
等价于
//绑定一个属性 v-bind:绑定class
代码语言:javascript复制//对象语法
我们可以传给 v-bind:class 一个对象,以动态地切换 class:
格式:
//isActive是boolean属性的参数,为true就给div添加类名active,为false就不添加
可以同时绑定多个类名,也可以和静态类名同时存在
//数组语法
我们可以把一个数组传给 v-bind:class,以应用一个 class 列表:
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
//绑定多个属性
new Vue({
el:'#box',
data:{
url:'http://www.baidu.com',
classname:['aaa','bbb','ccc']
}
})
v-bind:绑定内联样式
代码语言:javascript复制#对象语法
//v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS property 名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名:
data: {
activeColor: 'red',
fontSize: 30
}
//直接绑定到一个样式对象通常更好,这会让模板更清晰:
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}
#数组语法
//v-bind:style 的数组语法可以将多个样式对象应用到同一个元素上:
v-model你可以用v-model 指令在表单、
v-model 会忽略所有表单元素的value、checked、selected attribute 的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的data 选项中声明初始值。
v-model说白了就像监听器一样,会自动的将vue实例的值同步更新到表单中,同样的也会把表达中的值同步到vue实例中。
这就是双向数据绑定。
**注意:**只有表单元素使用v-model使用才有意义,因为只有表单元素才可以跟用户交互。别的元素使用只能显示数据,没有别的意义。
对input框,操作的是value属性的值:代码语言:javascript复制
{{msg}}
new Vue({
el:'.box',
data:{
msg:'你好哈哈哈'
}
})
```
对单个复选框操作的是 checked属性的值:
代码语言:javascript复制
{{b}}
new Vue({
el:'.box',
data:{
b:''
}
})
此时vue实例中b的值会就跟复选框绑定到了一起。对多个复选框操作如果在vue实例中是用一个数组接收,接收到是一个数组,里边包含的是被选中的复选框的vlaue值
代码语言:javascript复制
{{b}}
new Vue({
el:'.box',
data:{
b:[]
}
})
想让哪个框默认选中,就直接把这个框的值写入到vue的实例中去。对于单选框来说,拿到的是被选中的那个单选框的value属性的值:
代码语言:javascript复制
男
女
{{s}}
new Vue({
el:'.box',
data:{
s:""
}
})
对于下拉框来说,拿到的是被选中的那个选项的值
代码语言:javascript复制
{{selected}}
new Vue({
el:'.box',
data:{
selected:''
}
})
此时selected拿到的就是被选中的项的value值,如果是多选的下拉框,此时的selected值就是选中的多个框的value值。v-model的专用修饰符代码语言:javascript复制.lazy - 取代 input 监听 change 事件
原本的数据绑定相当于对input框进行oninput事件监听,使用v-model.lazy之后相当于把oninput事件换成了onchange事件
.number - 输入字符串转为有效的数字 自动转换为数字
+={{num1+num2}}
new Vue({
el:'#app',
data:{
num1:1,
num2:2
}
})
.trim - 输入首尾空格过滤 1.5 事件处理vue中的event事件对象:
如果调用函数时不传递参数,那么在函数中可以直接使用e来表示事件对象,但是如果进行参数的传递,在函数内部就无法再使用e了,此时 vue中给我们提供了一个 $event 来表示时间对象,只需要调用函数时传入即可。代码语言:javascript复制获取事件对象
new Vue({
el: '#max',
methods: {
fn(e){
console.log(e);
}
}
})
事件修饰符代码语言:javascript复制v-on后面可以增加修饰符
事件修饰符:
常用:
.stop:调用event.stopPropagation() 阻止事件冒泡
.prevent : 调用event.preventDefault()阻止默认行为
不常用:
.self : 只当事件是从侦听器绑定的元素本身触发时才触发回调
例如:如果不想添加冒泡事件,可以给父子级的元素都添加.self修饰符这样就不会触发冒泡事件,只有在点击元素自身的时候才会触发。
.once:点击事件将只会触发一次
事件只会被触发一次,触发后,底层就会解绑事件 类似于jquery中one()事件绑定
.capture:添加事件监听器时使用事件捕获模式
.passive:滚动事件的默认行为 (即滚动行为) 将会立即触发按键修饰符
在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为v-on 在监听键盘事件时添加按键修饰符:代码语言:javascript复制
注意:keyCode 的事件用法已经被废弃了并可能不会被最新的浏览器支持。
使用 keyCode attribute 也是允许的:
代码语言:javascript复制enter键触发
a键触发为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键码的别名:
.enter.tab.delete (捕获“删除”和“退格”键).esc.space.up.down.left.right有一些按键 (.esc 以及所有的方向键) 在 IE9 中有不同的 key 值, 如果你想支持 IE9,这些内置的别名应该是首选。
你还可以通过全局 config.keyCodes 对象自定义按键修饰符别名:
代码语言:javascript复制// 可以使用 `v-on:keyup.f1`
//单个定义
Vue.config.keyCodes.f1 = 112
//当以多个
Vue.config.keyCodes = {
aaa:65,
bbb:66
}
new Vue({
el: '#max',
methods: {
fn4(){
alert('a键被按下了');
}
}
})
系统修饰键代码语言:javascript复制系统修饰键
.ctrl
.alt
.shift
.meta
注意:在 Mac 系统键盘上,meta 对应 command 键 (⌘)。在 Windows 系统键盘 meta 对应 Windows 徽标键 (⊞)。在 Sun 操作系统键盘上,meta 对应实心宝石键 (◆)。在其他特定键盘上,尤其在 MIT 和 Lisp 机器的键盘、以及其后继产品,比如 Knight 键盘、space-cadet 键盘,meta 被标记为“META”。在 Symbolics 键盘上,meta 被标记为“META”或者“Meta”。
同时按下alt键和c键
#请注意: 修饰键与常规按键不同,在和 keyup 事件一起用时,事件触发时修饰键必须处于按下状态。换句话说,只有在按住 ctrl 的情况下释放其它按键,才能触发 keyup.ctrl。而单单释放 ctrl 也不会触发事件。如果你想要这样的行为,请为 ctrl 换用 keyCode:keyup.17。.exact 修饰符
2.5.0 新增
.exact 修饰符允许你控制由精确的系统修饰符组合触发的事件。代码语言:javascript复制
鼠标按钮修饰符
2.2.0 新增
.left.right.middle这些修饰符会限制处理函数仅响应特定的鼠标按钮。
代码语言:javascript复制当点击鼠标右键时才会触发事件
二、案例作业 案例1—注册页面需求说明
使用常见表单元素布局注册页面
使用v-model指令完成对应数据的绑定
填写的表单内容可以显示在表单下方
全栈工程师开发实战之从入门到技术实战之02--vue指令_javascript_07 案例2—点击重新编辑需求说明
点击“Edit Me”,下方出现文本框,可以自行修改文本
输入框中的文字和页面中的文字保持一致
使用 v-show、v-on、v-model 指令
案例3—仿京东左侧菜单需求说明
完成京东左侧菜单的页面布局
使用 v-for 指令遍历子分类名称,从而显示子分类的列表
全栈工程师开发实战之从入门到技术实战之02--vue指令_javascript_08 案例4—导航切换需求说明:
点击导航条中的导航项目,当前被点击的项目内容会显示在下方绿色方块中,并且当前被点击项目的背景会变成红色
使用 v-for 指令遍历显示导航项目,使用v-on添加添加事件,使用v-bind指令动态绑定class和key属性
全栈工程师开发实战之从入门到技术实战之02--vue指令_前端_09 案例5—商品的增加,删除,上下架全栈工程师开发实战之从入门到技术实战之02--vue指令_javascript_10全栈工程师开发实战之从入门到技术实战之02--vue指令_javascript_11需求:
点击新增,添加商品,如果输入框为空字符串则弹出提示框点击删除,删除对应的行点击操作栏中的上下架,改变对应的状态代码语言:javascript复制
td{
height: 30px;
text-align: center;
}
名称:
数量:
是否上架:
| 编号 | 名称 | 状态 | 数量 | 操作 | |
|---|---|---|---|---|---|
| {{item.id}} | {{item.name}} |
上架状态 下架状态 |
{{item.num}} |
选中的商品的总数量:{{count}}
/*
① 根据data数据渲染DOM结构
② 新增商品
③ 删除功能 根据id删除
④ 上下架功能 根据id修改上下架
⑤ 首先把数据中新增一个属性 isChecked
在把这个属性跟页面中的input框做双向数据绑定
全选:给全选框绑定事件
反选:给所有的复选框绑定事件
*/
new Vue({
el:'#app',
data:{
goods:[
{id:1,name:'苹果',state:true,num:5,isChecked:false},
{id:2,name:'香蕉',state:false,num:5,isChecked:false},
{id:3,name:'橘子',state:true,num:5,isChecked:true},
{id:4,name:'甘蔗',state:true,num:5,isChecked:false},
{id:5,name:'荔枝',state:true,num:5,isChecked:false}
],
//定义商品名称
gName:'',
//商品的数量
gNum:0,
//上下架的状态
gState:true,
//商品id
ids:5,
//全选状态
allState:false,
//记录选中的商品的总数量
//count:0
},
methods: {
//定义新增商品的方法/函数
addGoods(){
//1.先创建一个商品对象
let obj = {
id:++this.ids,
name:this.gName,
num:this.gNum,
state:this.gState
}
//2.把数据整体追加到 data中goods中
this.goods.push(obj);
},
//定义删除按钮
del(e,i){
//方式一:DOM方式 不推荐使用
//e.target.parentElement.parentElement.remove()
//e.target.parentNode.parentNode.remove()
//方式二:从数据的角度来删除
/* this.goods.forEach((item,index) => {
if(item.id==i){
//index表示删除的下标 1 表示删除的个数
this.goods.splice(index,1)
}
}); */
//使用数组的filter方法做过滤操作 拿到符合条件的所有结果
this.goods = this.goods.filter(item=>item.id!=i)
},
//定义修改状态的函数
/* changeState(i){
this.goods.forEach((item) => {
if(item.id==i){
//index表示删除的下标 1 表示删除的个数
item.state = !item.state
}
});
} */
//定义全选事件
checkAll(){
//全选:要把购物车中所有的选项的isChecked属性值都变成跟全选框一致
this.goods.forEach((item) => {
item.isChecked = this.allState
});
},
//定义反选事件
reverseChk(){
//点击每一个复选框时,都要对所有复选框做遍历,看里边是否存在isChecked为false的选项
//只要有false 那么allState也等于false
this.allState = this.goods.every(item=>item.isChecked==true)
},
//定义数量的增加方法
add(i){
this.goods.forEach((item) => {
if(item.id==i){
item.num+=1
}
});
},
//定义数量的减少方法
sub(i,a){
//如果数量为1的 就直接return
if(this.goods[a].num==1) return ;
this.goods.forEach((item) => {
if(item.id==i){
item.num-=1
}
});
}
},
computed: {
//计算选中结算的商品总数量
count(){
//先 筛选 出被选中的商品 再 计算中总数量赋值给count
return this.goods.filter(item=>item.isChecked==true).reduce((total,item)=>total+=item.num,0)
}
}
})
三、作业:作业1:学生信息录入系统
作业2:任务列表案例
需求:观察视频中各项特效变化,完成效果。
代码语言:javascript复制
.active{
text-decoration: line-through;
color: gray;
}
任务列表
任务总数{{sum()}}; 未完成{{daiban()}};已完成{{sum()-daiban()}}
-
{{item.content}}
let vm = new Vue({
el:'#app',
data:{
lists:[
{isChecked:false,content:'学习java',isEdit:true},
{isChecked:false,content:'学习html',isEdit:true},
{isChecked:false,content:'学习vue',isEdit:true},
{isChecked:false,content:'学习css',isEdit:true}
],
msg:'',
id:0
},
methods:{
//添加任务
add(){
let obj = {
id:++this.id,
isChecked:false,
content:this.msg,
isEdit:true
}
this.lists.push(obj);
},
//定义双击任务时显示input输入框
showInp1(i){
//如果任务是已完成状态此时无法再次编辑
if(this.lists[i].isChecked) return;
//改变当前编辑的数据的isedit的值
this.lists[i].isEdit = false;
},
//任务总数
sum(){
return this.lists.length;
},
//未完成的任务
daiban(){
let aaa = 0;
this.lists.forEach(obj => {
if(!obj.isChecked){
aaa++;
}
});
return aaa;
},
//删除已完成任务
del(){
//通过原生js的数组的fillter方法筛选出未完成的任务
this.lists = this.lists.filter((obj)=>{
return obj.isChecked!=true;
})
}
}
})
务是已完成状态此时无法再次编辑
if(this.lists[i].isChecked) return;
//改变当前编辑的数据的isedit的值
this.lists[i].isEdit = false;
},
//任务总数
sum(){
return this.lists.length;
},
//未完成的任务
daiban(){
let aaa = 0;
this.lists.forEach(obj => {
if(!obj.isChecked){
aaa++;
}
});
return aaa;
},
//删除已完成任务
del(){
//通过原生js的数组的fillter方法筛选出未完成的任务
this.lists = this.lists.filter((obj)=>{
return obj.isChecked!=true;
})
}
}
})
```