51、Vue 修饰符有哪些
vue中修饰符分为以下五种
- 表单修饰符
- 事件修饰符
- 鼠标按键修饰符
- 键值修饰符
v-bind
修饰符
1. 表单修饰符
在我们填写表单的时候用得最多的是input
标签,指令用得最多的是v-model
关于表单的修饰符有如下:
lazy
在我们填完信息,光标离开标签的时候,才会将值赋予给value
,也就是在change
事件之后再进行信息同步
js
<input type="text" v-model.lazy="value">
<p>{{value}}</p>
trim
自动过滤用户输入的首空格字符,而中间的空格不会过滤
js
<input type="text" v-model.trim="value">
number
自动将用户的输入值转为数值类型,但如果这个值无法被parseFloat
解析,则会返回原来的值
js
<input v-model.number="age" type="number">
2. 事件修饰符
事件修饰符是对事件捕获以及目标进行了处理,有如下修饰符
.stop
阻止了事件冒泡,相当于调用了event.stopPropagation
方法
js
<div @click="shout(2)">
<button @click.stop="shout(1)">ok</button>
</div>
//只输出1
.prevent
阻止了事件的默认行为,相当于调用了event.preventDefault
方法
js
<form v-on:submit.prevent="onSubmit"></form>
.capture
使用事件捕获模式,使事件触发从包含这个元素的顶层开始往下触发
js
<div @click.capture="shout(1)">
obj1
<div @click.capture="shout(2)">
obj2
<div @click="shout(3)">
obj3
<div @click="shout(4)">
obj4
</div>
</div>
</div>
</div>
// 输出结构: 1 2 4 3
.self
只当在event.target
是当前元素自身时触发处理函数
js
<div v-on:click.self="doThat">...</div>
使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用
v-on:click.prevent.self
会阻止所有的点击,而v-on:click.self.prevent
只会阻止对元素自身的点击
.once
绑定了事件以后只能触发一次,第二次就不会触发
js
<button @click.once="shout(1)">ok</button>
.passive
告诉浏览器你不想阻止事件的默认行为
在移动端,当我们在监听元素滚动事件的时候,会一直触发onscroll
事件会让我们的网页变卡,因此我们使用这个修饰符的时候,相当于给onscroll
事件整了一个.lazy
修饰符
js
<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
<!-- 而不会等待 `onScroll` 完成 -->
<!-- 这其中包含 `event.preventDefault()` 的情况 -->
<div v-on:scroll.passive="onScroll">...</div>
- 不要把
.passive
和.prevent
一起使用,因为.prevent
将会被忽略,同时浏览器可能会向你展示一个警告。passive
会告诉浏览器你不想阻止事件的默认行为
native
让组件变成像html
内置标签那样监听根元素的原生事件,否则组件上使用v-on
只会监听自定义事件
js
<my-component v-on:click.native="doSomething"></my-component>
<!-- 使用.native修饰符来操作普通HTML标签是会令事件失效的 -->
3. 鼠标按钮修饰符
鼠标按钮修饰符针对的就是左键、右键、中键点击,有如下:
.left
左键点击.right
右键点击.middle
中键点击
js
<button @click.left="shout(1)">ok</button>
<button @click.right="shout(1)">ok</button>
<button @click.middle="shout(1)">ok</button>
4. 键盘事件的修饰符
键盘修饰符是用来修饰键盘事件(onkeyup
,onkeydown
)的,有如下:
keyCode
存在很多,但vue为我们提供了别名,分为以下两种:
- 普通键 (
enter
、tab
、delete
、space
、esc
、up
、down
、left
、right
...) - 系统修饰键 (
ctrl
、alt
、meta
、shift
...)
js
<!-- 只有按键为keyCode的时候才触发 -->
<input type="text" @keyup.keyCode="shout()">
还可以通过以下方式自定义一些全局的键盘码别名
js
Vue.config.keyCodes.f2 = 113
5. v-bind修饰符
v-bind
修饰符主要是为属性进行操作,用来分别有如下:
- async 能对
props
进行一个双向绑定
js
//父组件
<comp :myMessage.sync="bar"></comp>
//子组件
this.$emit('update:myMessage',params);
52、Composition API 与 Options API 有什么不同
Composition API
出现就是为了解决Options API导致相同功能代码分散的现象
-
Composition API
是一组API
,包括:Reactivity API
、生命周期钩子
、依赖注入
,使用户可以通过导入函数方式编写vue
组件。而Options API
则通过声明组件选项的对象形式编写组件 -
Composition API
最主要作用是能够简洁、高效复用逻辑。解决了过去Options API
中mixins
的各种缺点;另外Composition API
具有更加敏捷的代码组织能力,很多用户喜欢Options API
,认为所有东西都有固定位置的选项放置代码,但是单个组件增长过大之后这反而成为限制,一个逻辑关注点分散在组件各处,形成代码碎片,维护时需要反复横跳,Composition API
则可以将它们有效组织在一起。最后Composition API
拥有更好的类型推断,对ts支持更友好,Options API
在设计之初并未考虑类型推断因素,虽然官方为此做了很多复杂的类型体操,确保用户可以在使用Options API
时获得类型推断,然而还是没办法用在mixins
和provide/inject
上 -
Vue3
首推Composition API
,但是这会让我们在代码组织上多花点心思,因此在选择上,如果我们项目属于中低复杂度的场景,Options API
仍是一个好选择。对于那些大型,高扩展,强维护的项目上,Composition API
会获得更大收益
可能的追问
Composition API
能否和Options API
一起使用?
可以在同一个组件中使用两个script
标签,一个使用vue3,一个使用vue2写法,一起使用没有问题
js
<!-- vue3 -->
<script setup>
// vue3写法
</script>
<!-- 降级vue2 -->
<script>
export default {
data() {},
methods: {}
}
</script>
53、Computed和Watch的区别
-
前者支持缓存,不支持异步,当有异步操作的时候,无法发起监听的作用,根据依赖的响应式数据动态计算而来的属性,它具有缓存和实时更新的特点,适用于需要进行复杂计算的场景。
-
后者支持异步,监听数据的变化,并在特定数据发生变化时执行自定义的回调函数,适用于需要执行异步操作或复杂逻辑的场景。
54、你项目里用到了keepalive吗?有哪几种使用方式?
keep-alive是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在父组件链中;
使用keep-alive包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。
我在vue-router中的应用过
include
定义缓存白名单,keep-alive会缓存命中的组件;exclude
定义缓存黑名单,被命中的组件将不会被缓存,优先级高于前者;max
定义缓存组件上限,超出上限使用LRU的策略置换缓存数据。
js
// 只缓存组件name为a或者b的组件
<keep-alive include="a,b">
<component />
</keep-alive>
// 组件name为c的组件不缓存(可以保留它的状态或避免重新渲染)
<keep-alive exclude="c">
<component />
</keep-alive>
// 如果同时使用include,exclude,那么exclude优先于include, 下面的例子只缓存a组件
<keep-alive include="a,b" exclude="b">
<component />
</keep-alive>
// 如果缓存的组件超过了max设定的值5,那么将删除第一个缓存的组件
<keep-alive exclude="c" max="5">
<component />
</keep-alive>
- 视图组件都被缓存
js
<keep-alive>
<router-view>
<!-- 所有路径匹配到的视图组件都会被缓存! -->
</router-view>
</keep-alive>
- 只想要
router-view
里面的某个组件被缓存
- 使用
include
js
//只有路径匹配到的 name 为 a 组件会被缓存
<keep-alive include="a">
<router-view></router-view>
</keep-alive>
- 使用
meta
属性
js
// routes 配置
export default [
{
path: '/',
name: 'home',
component: Home,
meta: {
keepAlive: true // 需要被缓存
}
}, {
path: '/profile',
name: 'profile',
component: Profile,
meta: {
keepAlive: false // 不需要被缓存
}
}
]
js
<keep-alive>
<router-view v-if="$route.meta.keepAlive">
<!-- 这里是会被缓存的视图组件,比如 Home! -->
</router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive">
<!-- 这里是不会被缓存的视图组件,比如 Profile! -->
</router-view>
55、 Vue子组件和父组件的执行顺序
加载渲染过程:
- 父组件 beforeCreate
- 父组件 created
- 父组件 beforeMount
- 子组件 beforeCreate
- 子组件 created
- 子组件 beforeMount
- 子组件 mounted
- 父组件 mounted
更新过程:
- 父组件 beforeUpdate
- 子组件 beforeUpdate
- 子组件 updated
- 父组件 updated
销毁过程:
- 父组件 beforeDestroy
- 子组件 beforeDestroy
- 子组件 destroyed
- 父组件 destoryed