vue 面试点

169 阅读2分钟

计算属性 vs 监听器

  • 监听器更通用,理论上计算属性能实现的侦听器也能实现
  • 处理数据的场景不同,监听器适合一个数据影响多个数据,计算属性适合一个数据受多个数 据影响
  • 计算属性有缓存性,计算所得的值如果没有变化不会重复执行
  • 监听器适合执行异步操作或较大开销操作的情况

关于Vue的生命周期,下列哪项是不正确的?()[单选题]

  • A、Vue 实例从创建到销毁的过程,就是生命周期。
  • B、页面首次加载会触发beforeCreate, created, beforeMount, mounted, beforeUpdate, updated。
  • C、created表示完成数据观测,属性和方法的运算,初始化事件,$el属性还没有显示出来。
  • D、DOM渲染在mounted中就已经完成了

答案:B 原因是:页面首次加载会触发的生命周期不包含beforeUpdate, updated,因为他们是数据更新时触发

结论:

  • 三个阶段:初始化、更新、销毁
  1. 初始化:beforeCreate、created、beforeMount、mounted
  2. 更新:beforeUpdate、updated
  3. 销毁: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。
  • 优点:从上面案例可以看出组件化可以增加代码的复用性、可维护性和可测试性。
  • 使用场景:什么时候使用组件?以下分类可作为参考:
    1. 通用组件:实现最基本的功能,具有通用性、复用性,例如按钮组件、输入框组件、布局组件等。
    2. 业务组件:它们完成具体业务,具有一定的复用性,例如登录组件、轮播图组件。
    3. 页面组件:组织应用各部分独立内容,需要时在不同页面组件间切换,例如列表页、详情页组件
  • 如何使用组件
	定义: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>

其原理是通过使用 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>