day02
目录指令修饰符 "."
- 所谓指令修饰符就是通过
“.”
指明一些指令后缀不同的后缀封装了不同的处理操作- 简化代码
按键修饰符
-
@keyup.enter
:当点击 enter 键的时候才触发-
例如用在
<input @keyup.enter = "某事件一" />
-
@keyup = "某事件二"
是实时触发事件二 -
想找到
.enter
就可以给事件二方法处加一个形参获取事件对象,如:<input @keyup="fn" type="text"> <!-- --> methods: { fn(e){ console.log(e) } }
- 就可以获取整个事件对象,看到在 e 中就有 enter,所以
@keyup.enter
就相当于在 fn 方法中加了if(e.key === 'Enter'){ ...... }
简化代码
- 就可以获取整个事件对象,看到在 e 中就有 enter,所以
-
事件修饰符
-
@事件名.stop
:阻止冒泡-
例:
<div @click="father"> <div @click="son">子</div> </div>
- 冒泡是默认存在的:点击子后,会先触发
son
事件,紧接着就会触发father
事件
- 冒泡是默认存在的:点击子后,会先触发
-
原先方式的话,想阻止冒泡就得
son(e){ e.stopPropagation() }
这样在方法中编写阻止
-
-
@事件名.prevent
:阻止默认行为-
例:
<div href="http:www.baidu.com">跳转</div>
- 点击后默认的行为就是跳转到百度,想要点击后不跳转就加上
@事件名.prevent
来阻止默认的跳转行为
- 点击后默认的行为就是跳转到百度,想要点击后不跳转就加上
-
-
@事件名.stop.prevent
:可以连用,即阻止事件冒泡也阻止默认行为
v-bind 对样式控制的增强 — :class
- 平常只有 class 类名、style 行内样式两种对于样式的操作
- 为了方便开发者进行样式控制, Vue 扩展了
v-bind
的语法,可以针对这两种进行控制
普通语法
<div> :class = "对象/数组">这是一个div</div>
对象语法
-
当 class 动态绑定的是对象时,键就是类名,值就是布尔值,如果值是 true,就有这个类,否则没有这个类(注意:这里的布尔值可以是一个结果为布尔值的表达式,不要太死板)
<div class="box" :class="{ 类名1: 布尔值, 类名2: 布尔值 }"></div>
- 适用场景:一个类名,来回切换
- 例如一些动态的收缩显示,点击改变宽度、大小等
数组语法
-
当 class 动态绑定的是数组时,数组中所有的类,都会添加到盒子上,本质就是一个 class 列表
<div class="box" :class="[ '类名1', '类名2', '类名3' ]"></div>
- 使用场景:批量添加或删除类
tab 栏切换导航高亮
-
点击哪个 tab 页签时,哪个 tab 页签就高亮
li a { display: block; text-decoration: none; font-weight: bold; color: #333333; } li a.active { background-color: #e01222; color: #fff; } </style> <div id="app"> <ul> <li v-for="(item, index) in list" :key="item.id" @click="activeIndex = index"> <a :class="{ active: index === activeIndex }">{{ item.name }}</a> <!-- 选中的加上class样式 --> </li> </ul> </div> <script src="https://"></script> <script> const app = new Vue({ el: '#app', data: { activeIndex: 0, // 标记高亮的那一个 list: [ { id: 1, name: 'xxx' }, { id: 2, name: 'yyy' }, { id: 3, name: 'lll' } ] } }) </script>
v-bind 对有样式控制的增强 — :style
语法
<div class="box" :style="{ CSS属性名1: 'CSS属性值', CSS属性名2: 'CSS属性值' }"></div>
- 注意在
:style
里面,不能直接写background-color: 'red'
(js 对象中的属性名不支持带横线的),应该写成'background-color': 'red'
或backgroundColor: 'red'
编写进度条 css 显示进度
<div class="黑色底色盒子">
<div class="进度条颜色盒子" :style="{ width: percent + '%' }">
<span>{{ percent }}%</span>
</div>
</div>
<button @click="percent = 25">进度设置25%</button>
<button @click="percent = 50">进度设置50%</button>
<button @click="percent = 75">进度设置75%</button>
<button @click="percent = 100">进度设置100%</button>
v-model 在其他表单元素的使用
-
v-model 会根据控件类型,自动选取正确的方法来更新元素
输入框 input:text ——> value ——> 选中的 value 值 文本域 textarea ——> value ——> 选中的 value 值 复选框 input:checkbox ——> checked ——> true / false 单选框 input:radio ——> checked ——> (加 name 分组,value 值) ——> value 值 下拉菜单 select ——> value ——> 选中的 value 值 ...
computed 计算属性
概念
- 基于现有的数据,计算出来的新属性
- 依赖的数据变化,自动重新计算
语法
- 声明在 computed 配置项中,一个计算属性对应一个函数
- 使用起来和普通属性一样使用
{{ 计算属性名}}
注意
- computed 配置项和 data 配置项是同级的
- computed 中的计算属性虽然是函数的写法,但他依然是个属性
- computed 中的计算属性不能和 data 中的属性同名
- 使用 computed 中的计算属性和使用 data 中的属性是一样的用法
- computed 中计算属性内部的 this 依然指向的是 Vue 实例
computed 计算属性 VS methods 方法
computed 计算属性
-
作用:封装了一段对于数据的处理,求得一个结果
-
语法:
-
作为属性,直接使用
-
js 中使用计算属性:
this.计算属性
-
模板中使用计算属性:
{{ 计算属性 }}
-
-
注意:
- 使用的时候不加括号
- 定义的时候不要忘了括号和 return
methods 计算属性
-
作用:给 Vue 实例提供一个方法,调用以处理业务逻辑
-
语法:
-
作为方法调用
-
js 中调用:
this.方法名()
-
模板中调用
{{方法名()}}
或者@事件名=“方法名”
-
计算属性的优势
- 缓存特性(提升性能)
- 计算属性会对计算出来的结果缓存,再次使用直接读取缓存
- 只有依赖项(数据)变化了,才会自动重新计算并再次缓存
- methods 没有缓存特性
总结
- computed 有缓存特性,methods 没有缓存
- 当一个结果依赖其他多个值时,推荐使用计算属性
- 若是用 methods 的话,多次使用就需要执行此方法多次,而用计算属性可能只需要一次即可
- 当处理业务逻辑时,推荐使用 methods 方法,比如事件的处理函数
计算属性的完整写法
-
计算属性默认的简写,只能读取访问,不能 " 修改 "
-
如果要 " 修改 " 需要写计算属性的完整写法
-
加 get()、set(),get 就是原 return 部分的内容,
set(要修改的值) { 修改的代码逻辑 }
computed:{ 计算属性名: { get() { 一段代码逻辑(计算逻辑) return 结果 }, set(修改的值) { 一段代码逻辑(修改逻辑) } } }
- 这个时候的计算属性名后面就不要加括号了
- 这里调用的时候不需要写上 .set()、.get() 的,还是和之前用法一样,直接
计算属性名
使用即可,set 中的 value 就是计算属性名自己,都是被封装好了的,无需显示调用
-
watch 侦听器(监视器)
作用
- 监视数据变化,执行一些业务逻辑或异步操作
简单语法
-
watch 同样声明在跟 data 同级的配置项中
-
简单写法: 简单类型数据直接监视
-
例:
watch: { // 该方法会在数据变化时,触发执行 数据属性名 (newValue, oldValue) { 一些业务逻辑或异步操作 }, '对象.属性名' (newValue, oldValue) { 一些业务逻辑或异步操作 } }
- 注意如果是子属性的话要加上引号(因为是不允许出现特殊字符的)
防抖操作
- 防抖:延迟执行 —> 干啥事先等一等,延迟一会,一段时间内没有再次触发,才执行(如果被触发就重新计时、重新再等一等)
- 否则可能会产生
input
每做一次更改就会立即执行走路由,对后台压力很大,所以要防抖 - 就像百度翻译一样,输入被翻译内容时需要等一会才翻译出内容,而不是每输一个字就翻译一次
- 可以理解为延时器,但不单纯是延迟(还有清空先前无效操作的作用)
- 否则可能会产生
watch: {
// 该方法会在数据变化时调用执行
// newValue新值, oldValue老值(一般不用)
// words (newValue) {
// console.log('变化了', newValue)
// }
// 'obj.words' (newValue) {
// setTimeout(async () => {
// const res = await axios({
// url: 'https://',
// params: {
// words: newValue
// }
// })
// this.result = res.data.data
// console.log(res.data.data)
// }, 1000) // 1000就是1秒
// }
// 但是这里只是做了延迟,延迟过后还是会发出夹杂无意义的请求,所以要清空之前的延时操作:
'obj.words' (newValue) {
clearTimeout(this.timer) // clearTimeout(延时器id),每次新开启时清空旧的
this.timer = setTimeout(async () => {
const res = await axios({
url: 'https://',
params: {
words: newValue
}
})
this.result = res.data.data
console.log(res.data.data)
}, 300) // 300毫秒
}
}
- 注意这里的
this.timer
如果和渲染页面相关的话,需要先在data: { 里存放延时器id —— timer }
声明,但如果和渲染页面无关的话,就不需要先声明在 data 里了,直接this.xxx
使用即可,这样可以理解为了 this 就是:let app实例对象 = {}
,然后this.xxx
就是app实例对象.timer = null
,这时候app实例对象
就是{timer: null}
的形式了(就是把 this 当成一个普通对象来看)- 注意:是在与渲染页面无关的时候
完整语法
-
完整写法:添加额外的配置项
deep:true
对复杂类型进行深度监听- 对对象当中的所有属性都做监视,任意属性发生变化都会触发
handler()
- 例:上述的代码只有在
obj
的words
属性变化时才编译,这次再加一个翻译为xx 语言
的属性,当修改语言时也会实时的翻译 - 原来的写法只能选择再加一个
'obj.yuyan (){ ...... }'
,可是每加一个属性就要写一遍太罗嗦,所有用完整写法监听整个对象
- 对对象当中的所有属性都做监视,任意属性发生变化都会触发
immdiate:true
初始化时立刻执行一次- 即:翻译是只有更改后才触发监听,那样的话,如果有初始值就不会翻译初始值了,那就可以加上此句,这样在一开始就会执行并触发一次(翻译初始值了)
-
例:
watch: {// watch 完整写法 对象: { deep: true, // 深度监视(针对复杂类型) immdiate:true,//立即执行handler函数 handler (newValue) { // 剩下的照搬 clearTimeout(this.timer) // clearTimeout(延时器id),每次新开启时清空旧的 this.timer = setTimeout(async () => { const res = await axios({ url: 'https://', params: newValue // 这里就直接传整个对象了 }) this.result = res.data.data console.log(res.data.data) }, 300) // 300毫秒 } } }
-
注意:在需要的时候再用
deep: true
,一般情况下能用普通的写法解决的就用普通的写法即可