- 不是每个都很常用,但用到的时候都必须要知道。
- 考察候选人对Vue的掌握是否全面,且由深度。
- 考察做过的项目是否有深度和复杂度(至少用到高级特性)
- 自定义 v-mdel
- $nextTick
- slot
- 动态、异步组件
- keep-alive
- mixin
- refs
3-1vue如何自己实现v-model
1.父组件index.vue,子组件CustomVMode.vue
在父组件中引入子组件。
<p>{{name}}</p>
<CustomVModel v-model="name"></CustomVModel>
2.子组件CustomVMode.vue
<template>
<input :value="text" type="text" @input="$emit('change', $event.target.value)" />
</template>
<script>
export default {
name: "CustomVModel",
model: {
prop: "text",
event: "change"
},
props: {
text: {
type: String,
default: ""
}
}
};
</script>
解析:
(1)上面的input 使用了:value 而不是v-model
(2)上面的change和model的event对应起来。
(3)text属性对应起来。
3-2 $nextTick 和 $refs
- Vue是异步渲染
- data改变之后,DOM不会立刻渲染。
- $nextTick 会在DOM渲染之后被触发,以获取最新DOM节点。
<template>
<div>
<button @click="addItem">Add</button>
<ul ref="ul1">
<li v-for="(item, index) in list" :key="index">{{item}}</li>
</ul>
</div>
</template>
<script>
export default {
name: "app",
data() {
return {
list: ["a", "b", "c"]
};
},
methods: {
addItem() {
this.list.push(Date.now());
this.list.push(Date.now());
this.list.push(Date.now());
// 添加完想立刻获取长度, 不能及时拿到
// 要用nextTick等渲染完了才能获取准确的dom个数
this.$nextTick(() => {
console.log(this.$refs.ul1.childNodes.length);
});
// console.log(this.$refs.ul1.childNodes.length);
}
}
};
</script>
定义:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
所以就衍生出了这个获取更新后的DOM的Vue方法。所以放在Vue.nextTick()回调函数中的执行的应该是会对DOM进行操作的 js代码;
理解:nextTick(),是将回调函数延迟在下一次dom更新数据后调用,简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数,
3-3 slot是什么?
- 基本使用
- 作用域插槽
- 具名插槽
基本使用:
在组件App.vue中引入SlotDemo.vue
<SlotDemo :url="website.url">{{website.title}}</SlotDemo>
...
data() {
return {
website: {
url: 'http://imooc.com/',
title: 'imooc',
subTitle: '程序员的梦工厂'
}
};
}
SlotDemo.vue
<template>
<a :href="url">
<slot>默认插槽文字</slot>
</a>
</template>
<script>
export default {
name: "SlotDemo",
props: {
url: {
type: String,
default: ""
}
}
};
</script>
解析:通过父向子属性传值,在props中接收了传来的url,slot是插槽,如果父级为没有插入时即App.vue中 ,删去下面的{{website.title}},会显示默认的。
<SlotDemo :url="website.url">{{website.title}}</SlotDemo>
现在由于有插入,所以显示的时{{website.title}},即imooc
插槽的意义是让父组件往子组件插入一段内容。
作用域插槽:
理解:把子组件里的数据通过slot让父组件获取到。
子组件ScopedSlotDemo.vue
<template>
<a :href="url">
<slot :slotData="website">
{{website.subTitle}} //默认字显示subTitle, 即父组件不传
</slot>
</a>
</template>
<script>
export default {
name: "ScopedSlotDemo",
props: {
url: {
type: String,
default: ""
}
},
data() {
return {
website: {
url: 'http://wangEditor.com/',
title: 'wangEditor',
subTitle: '轻量级富文本编辑器'
}
};
}
};
</script>
解析:在子组件中slot中绑定属性,值为data中的website,在作用域插槽中的是父组件不传时显示的。
<slot :slotData="website">
{{website.subTitle}} //默认字显示subTitle, 即父组件不传
</slot>
父组件在App.vue里,在App.vue里引入了ScopedSlotDemo.vue。
<ScopedSlotDemo :url="website.url">
<template v-slot="slotProps">
{{slotProps.slotData.subTitle}}
</template>
</ScopedSlotDemo>
解析:关于作用域插槽的理解,主要在父组件中即可。
(1)通过在父组件的template标签中通过v-slot="slotProps"定义作用域插槽名称。
(2)插值表达式{{slotProps.slotData.subTitle}}中的slotData必须和子组件slot绑定属性名一样。
slot-具名插槽
3-4 动态组件
- :is = “component-name” 用法
- 需要根据数据,动态渲染的场景。即组件类型不确定。
<div v-for = "(val, key) in newsData :key = "key">
<component :is="val.type" />
</key>
...
newsData: {
1: {
type: 'text'
},
2: {
type: 'image'
}
}
3-5 异步组件
- import()函数
- 按需加载,异步加载大组件
<FormDemo v-if = "showFormDemo" />
<button @click="showFormDemo = true">show form demo</button>
...
export default {
components: {
FormDemo: () => import('../BaseUse/FormDemo')
}
},
data () {
showFormDemo: false
}
解析:通过v-if首先把显示默认为false,再通过在button控制,在components中import。
3-6 keep-alive
- 缓存组件
- 频繁切换,不需要重复渲染
- Vue常见性能优化
<button @click="changeState('A')">A</button>
<button @click="changeState('B')">B</button>
<button @click="changeState('C')">C</button>
<keep-alive>
<KeepAliveStageA v-if="state === 'A'"></KeepAliveStageA>
<KeepAliveStageB v-if="state === 'B'"></KeepAliveStageB>
<KeepAliveStageC v-if="state === 'C'"></KeepAliveStageC>
</keep-alive>
通过引入keepAliveStageABC,把组件包裹在标签中,通过button控制显示。
3-7vue组件如何抽离公共逻辑 mixin
- 多个组件有相同的逻辑,抽离出来
- mixin 并不是完美的解决方案,会有一些问题
- vue 3 提出的Composition API旨在解决这些问题
mixin.js
export default {
data() {
return {
city: "深圳",
};
},
mounted() {
console.log("mixin mounted", this.name);
},
methods: {
showName() {
console.log(this.name);
},
},
};
MixinDemo.vue
<template>
<div>
<p>{{name}} - {{major}} - {{city}}</p>
<button @click="showName">显示姓名</button>
</div>
</template>
<script>
import mixin from "./mixin";
export default {
name: "MixinDemo",
mixins: [mixin],
data() {
return {
name: "Bruski",
major: "Web 前端"
};
},
methods: {},
mounted() {
console.log("this mounted");
}
};
</script>
解析:通过在组件中引入mixin,mixins: [mixin](可以混入多个)把mixin中的逻辑引入。如下图,在MixinDemo.vue并没有直接声明city和showName()方法,都是靠mixin混入进去的。
mixin的缺点:
- 变量来源不明确,不利于阅读。
- 多mixin可能造成变量命名冲突。
- mixin 和组件可能出现多对多的关系,复杂度较高。
3-8 Vuex使用
- 面试考点并不多(因为熟悉Vue之后,vuex没有难度)
- 但基本概念,基本使用和API必须要掌握。
- 可能会考察state的数据结构设计。
- dispatch mapGetters
- commit mapActions
- state mapstate
actions才能异步操作。
3-9 Vue-router 使用
- 路由模式 (hash、H5、history)
- 路由配置(动态路由、懒加载)
路由模式:
- hash模式(默认),如http://abc.com/#/user/10
- H5 history模式,如http://abc.com/user/20
路由配置 动态路由:
路由配置 懒加载:
在不同的路由下异步加载不同的路由。