Vue
详细面试题
computed
和watch
computed
有缓存,data
不变则不回重新计算set
不用加return
watch
如何深度监听deep:true
watch
监听引用类型,拿不到oldVal
v-for
循环
key
视情况是否采用index
,尽量避免对象Obj
:(val,key,index)
v-for
与v-if
尽量避免一起用(现在会报错),v-for
优先级高,会先遍历,然后才会判断是否显示- 解决办法:使用计算属性,或者
v-if
在外层
- 解决办法:使用计算属性,或者
事件
event
参数,自定义参数event.currentTarget event.target
:事件是被注册到当前元素的event
是原生的
- 事件修饰符,按键修饰符
- 【观察】事件被绑定到哪里?
Vue
组件使用
props
和$emit
$emit
:传递多个参数的时候,传递argument
showTime(arguments) ==> this.$emit("showTime", msg[0], msg[1]);
- 组件间通讯 - 自定义事件
event.$on('doSomething',this.hanlder)
event.$off('doSomething',this.hanlder)
beforDsetroy event.$off
及时销毁,否则可能会造成内存泄漏
组件生命周期
- 单个 组件
- 挂载阶段
- 更新阶段
- 销毁阶段
-
父子组件
-
加载渲染过程
-
父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
-
子组件更新过程
-
父beforeUpdate->子beforeUpdate->子updated->父updated
-
父组件更新过程
-
父beforeUpdate->父updated
-
销毁过程
-
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
-
-
【总结】:所以尽量将组件拆分,一是为了便于维护 二是 当某些子组件数据没发生改变,是不会更新的
Vue
高级特性
-
自定义组件
v-model
:比如颜色选择器-
一个组件上的
v-model
默认会利用名为value
的 prop 和名为input
的事件,但是像单选框、复选框等类型的输入控件可能会将value
attribute 用于不同的目的。model
选项可以用来避免这样的冲突: -
Vue.component('base-checkbox', { model: { prop: 'checked', event: 'change' }, props: { checked: Boolean }, template: ` <input type="checkbox" v-bind:checked="checked" v-on:change="$emit('change', $event.target.checked)" > ` }) ******************************************************** //现在在这个组件上使用 v-model 的时候:<base-checkbox v-model="lovingVue"></base-checkbox> //这里的 lovingVue 的值将会传入这个名为 checked 的 prop。同时当 <base-checkbox> 触发一个 change 事件并附带一个新的值的时候,这个 lovingVue 的 property 将会被更新。 //注意你仍然需要在组件的 props 选项里声明 checked 这个 prop。
-
-
$nextTick
Vue
是异步渲染data
改变之后,DOM
不会立刻渲染$nextTick
会在DOM
渲染之后被触发,以获取最新DOM
节点- 异步渲染,
$nextTick
待DOM
渲染完在回调 - 页面渲染时会将
data
得修改做整合,多次data
修改只会渲染一次
- 异步渲染,
-
slot
-
//子组件 <a :href="url"> <slot :slotData="website"> {{website.subTitle}} <!-- 默认值显示 subTitle ,即父组件不传内容时 --> </slot> </a> props: ['url'], data() { return { website: { url: 'http://wangEditor.com/', title: 'wangEditor', subTitle: '轻量级富文本编辑器' } } }
-
//父组件 <ScopedSlotDemo :url="website.url"> <template v-slot="slotProps"> //slotProps 是可以随便定义得 //接取的是子组件标签slot上属性数据的集合 <!-- {{slotProps.slotData.title}} --> {{slotProps}} </template> </ScopedSlotDemo> data(){ url: 'http://imooc.com/', title: 'imooc', subTitle: '程序员的梦工厂' }, }
-
-
keep-alive
- 缓存组件
- 频繁切换,不需要重复渲染
activated
deactivated
生命周期 该钩子在服务器端渲染期间不被调用。
-
mixin
-
多个组件有相同得逻辑,抽离出来
-
但并不是完美得解决方案,会存在一些问题
-
Vue3
提出的Composition API
旨在解决这些问题 -
mixins:[myMixin]
可以添加多个,会自动合并起来 -
mixin
的问题- 变量来源不明确,不利于阅读
- 多
mixin
可能会造成命名冲突 mixin
和组件可能出现多对多的关系,复杂度较高
-
-
动态、异步组件
动态组件
:is='component-name'
用法- 需要根据数据,动态渲染得场景。即组件类型不确定
异步组件
import()
函数- 按需加载,异步加载大组件
vUE-router
使用
- 路由模式(
hash、H5 history
) - 路由配置(动态路由、懒加载)
VueX
使用
-
mapState
辅助函数-
// 在单独构建的版本中辅助函数为 Vuex.mapState import { mapState } from 'vuex' computed: { localComputed () { /* ... */ }, // 使用对象展开运算符将此对象混入到外部对象中,取别名使用对象形式 否则如下 ...mapState({ // ... theme: "theme" }) //or ...mapState( ['theme'] ) }
-
-
mapGetters
辅助函数-
const store = new Vuex.Store({ state: { todos: [ { id: 1, text: '...', done: true }, { id: 2, text: '...', done: false } ] }, getters: { doneTodos: state => { return state.todos.filter(todo => todo.done) } } })
-
import { mapGetters } from 'vuex' export default { // ... computed: { // 使用对象展开运算符将 getter 混入 computed 对象中 ...mapGetters([ 'doneTodosCount', 'anotherGetter', // ... ]) } }
-
-
mapMutations
辅助函数将组件中的 methods 映射为store.commit
调用(需要在根节点注入store
)。-
import { mapMutations } from 'vuex' export default { // ... methods: { ...mapMutations([ 'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')` // `mapMutations` 也支持载荷: 'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)` ]), ...mapMutations({ add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')` }) } }
-
-
mapActions
辅助函数将组件的 methods 映射为store.dispatch
调用(需要先在根节点注入store
):-
import { mapActions } from 'vuex' export default { // ... methods: { ...mapActions([ 'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')` // `mapActions` 也支持载荷: 'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)` ]), ...mapActions({ add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')` }) } }
-