计算属性 vs 监听器
- 监听器更通用,理论上计算属性能实现的侦听器也能实现
- 处理数据的场景不同,监听器适合一个数据影响多个数据,计算属性适合一个数据受多个数 据影响
- 计算属性有缓存性,计算所得的值如果没有变化不会重复执行
- 监听器适合执行异步操作或较大开销操作的情况
关于Vue的生命周期,下列哪项是不正确的?()[单选题]
- A、Vue 实例从创建到销毁的过程,就是生命周期。
- B、页面首次加载会触发beforeCreate, created, beforeMount, mounted, beforeUpdate, updated。
- C、created表示完成数据观测,属性和方法的运算,初始化事件,$el属性还没有显示出来。
- D、DOM渲染在mounted中就已经完成了
答案:B 原因是:页面首次加载会触发的生命周期不包含
beforeUpdate,updated,因为他们是数据更新时触发
结论:
- 三个阶段:初始化、更新、销毁
- 初始化:beforeCreate、created、beforeMount、mounted
- 更新:beforeUpdate、updated
- 销毁:beforeDestroy、destroyed
生命周期使用场景分析
beforeCreate(){} // 执行时【组件实例还未创建】,通常用于插件开发中执行一些初始化任务
created(){} // 【组件初始化完毕,各种数据可以使用】,常用于异步数据获取
beforeMounted(){} // 【未执行渲染、更新,dom未创建】
mounted(){} // 【初始化结束,dom已创建,可用于获取访问数据和dom元素】
beforeUpdate(){} // 更新前,可用于获取更新前各种状态
updated(){} // 更新后,所有状态已是最新
beforeDestroy(){} // 销毁前,可用于一些定时器或订阅的取消
destroyed(){} // 组件已销毁,作用同上
在组件上使用v-model
<!-- 自定义组件支持v-model需要实现内部input的:value和@input -->
<course-add v-model="course" @add-course="addCourse"></course-add>
<script>
Vue.component('course-add', { // 接收父组件传递value,不需要额外维护course
props: ['value'],
template: `
<div><!-- 需要实现input的:value和@input -->
<input :value="value" @input="onInput" @keydown.enter="addCourse"/>
<button v-on:click="addCourse">新增课程</button>
</div> `,
methods: {
addCourse() { // 派发事件不再需要传递数据
this.$emit('add-course') // this.course = ''
},
onInput(e) {
this.$emit('input', e.target.value)
}
},
})
const app = new Vue({
data: {
course: '', // 还原course
},
methods: {
addCourse() {// 还原addCourse
this.courses.push(this.course);
this.course = '';
}
}
})
</script>
v-model默认转换是:value和@input,如果想要修改这个行为,可以通过定义model选项
v-model
子组件定义
<template>
<div>
<span>用户名:</span>
<input :value="value" @input="$emit('input', $event.target.value)" />
<!-- <input :value="value" @input="onInput" /> -->
</div>
</template>
<script>
export default {
name: 'Kinput',
props: {
value: {
type: String,
default: "",
},
},
// methods: {
// onInput(e) {
// this.$emit("input", e.target.value);
// },
// },
};
</script>
<style lang="scss" scoped>
</style>
Vue.component('course-add', {
model: {
prop: 'value',
event: 'change'
}
})
子组件使用:
<template>
<KInput v-model="userVal"></KInput>
</div>
</template>
<script>
import KInput from "./components/my-Form/KInput";
export default {
name: "App",
components: {
KInput,
},
data() {
return {
userVal: "",
};
},
};
</script>
Vue组件化的理解
组件化是Vue的精髓,Vue应用就是由一个个组件构成的。Vue的组件化涉及到的内容非常多,当面试时 被问到:谈一下你对Vue组件化的理解。这时候有可能无从下手,可以从以下几点进行阐述:
- 定义:组件是可复用的 Vue 实例,准确讲它们是VueComponent的实例,继承自Vue。
- 优点:从上面案例可以看出组件化可以增加代码的复用性、可维护性和可测试性。
- 使用场景:什么时候使用组件?以下分类可作为参考:
- 通用组件:实现最基本的功能,具有通用性、复用性,例如按钮组件、输入框组件、布局组件等。
- 业务组件:它们完成具体业务,具有一定的复用性,例如登录组件、轮播图组件。
- 页面组件:组织应用各部分独立内容,需要时在不同页面组件间切换,例如列表页、详情页组件
- 如何使用组件
定义:Vue.component(),components选项,sfc
分类:有状态组件,functional,abstract
通信:props,$emit()/$on(),provide/inject,$children/$parent/$root/$attrs/$listeners
内容分发 :<slot>,<template>,`v-slot`
使用及优化:is,keep-alive,异步组件
- 组件的本质
vue中的组件经历如下过程
组件配置 => VueComponent实例 => render() => Virtual DOM=> DOM
所以组件的本质是产生虚拟DOM
Scoped CSS
当 标签有 scoped 属性时,它的 CSS 只作用于当前组件中的元素。
<style scoped>
.red {
color: red;
}
</style>
<style scoped>
.red {
color: red;
}
</style>
其原理是通过使用 PostCSS 来实现以下转换:
<template>
<div class="red" data-v-f3f3eg9>hi</div>
</template>
<style>
.red[data-v-f3f3eg9] {
color: red;
}
</style>
混用本地和全局
<style>
/* 全局样式 */
</style>
<style scoped>
/* 本地样式 */
</style>
深度作用选择器:使用 >>> 操作符可以使 scoped 样式中的一个选择器能够作用得“更深”,例如影响子组件
<style scoped>
#app >>> a {
color: red
}
</style>
Sass 之类的预处理器无法正确解析 >>> 。这种情况下你可以使用 /deep/ 或 ::v-deep 操作符取而代之
<style scoped lang="scss">
#app {
/deep/ a {
color: rgb(196, 50, 140)
}
::v-deep a {
color: rgb(196, 50, 140)
}
}
</style>