面试总结 vue

什么是DOM

当网页被加载时,浏览器就会创建页面的文档对象模型(document object model)。dom定义了访问HTML文档的标准。dom是中立于平台和语言的接口,允许程序和脚本动态的访问更新文档内容结构样式

DOM渲染流程

1、浏览器解析HTML代码,创建一个DOM树
2、浏览器解析css代码,计算出样式,构建一个渲染树
3、浏览器根据渲染树绘制页面

vue打包后,static和assets的区别

相同点:都是放静态资源的
不同点:项目打包时assets的资源也会打包;static不需要打包直接进入打包好的目录,占用空间较大

vue指令有哪些

v-model v-for v-if v-else v-show v-html

vue自定义指令

Vue.directive('focus', {
    inserted: function (el) {
        el.focus()
    },
})

bind:只调用一次,指令第一次绑定到元素时调用
inserted:被绑定元素插入父节点时调用
update:所在组件的vnode更新时调用
componentUpdated:所在组件的vnode及子组件的vnode全部更新后调用
unbind:只调用一次,指令和元素解绑时调用

vue注册全局组件

components文件下建立公共组件

<template>
  <el-button :disabled="disabled" :type="type" @click.stop="clickFunction">
    <slot></slot>
  </el-button>
</template>
<script>
export default {
  name: "Button",
  props: {
    type: { // primary denger
      type: String,
      default: "primary",
    },
    disabled: {
      type: Boolean,
      default: false,
    },
  },
};
</script>

components文件下建立index.js

// 给自定义组件添加install方法
const components = require.context('./', false, /\.vue$/) // require.context获取指定目录下符合条件的文件,这里获取所有components目录下的组件
let newComponents = []
components.keys().map(item => {
    const componentConfig = components(item).default
    componentConfig.install = function (Vue) {
        Vue.component(componentConfig.name, componentConfig);
    };
    newComponents.push(componentConfig)
})
export default newComponents;

在main.js中引用

// 注册全局组件
import components from '../src/components/index'
components.map(component => {
  Vue.use(component)
})
// 使用
<Button @click="btn1">Button</Button>
<Button type="denger" @click="btn2">denger</Button>

效果在这里插入图片描述

Vue的修饰符有哪些?

.tirm(首尾去空格) .number(先输入数字就限制输入只能是数字) .lazy(光标离开后再更新input数据)

v-if和v-show的区别

v-if是通过添加删除DOM元素控制显示隐藏,频繁操作会消耗性能,初次加载使用v-if
v-show是通过设置display的值控制显示隐藏,只会编译一次,频繁切换使用v-show

v-if和v-for为什么不能同时使用

v-for的优先级高于v-if,每次渲染都要先循环再进行条件判断,同时使用会导致性能浪费

说说key的作用

key主要作用是更高效的更新虚拟dom
key是vue在patch过程中判断两个节点是否是相同节点的必要条件。渲染一组列表时,key往往是唯一标识。如果不定义key的话,vue就会认为比较的两个节点是同一个,哪怕实际上不是,这导致了频繁更新元素,影响性能。如果定义key且两个节点的key相同,那么两个节点为相同节点的可能性就很大,在patch过程中就可以直接利用之前的节点,不必删除或新建节点

v-for为什么要用key

key是vnode唯一的id,也是diff的优化策略。可以根据key更快更准确的找到对应的vnode节点
未用key:vue采用就地复用原则,最小化element的移动,并且会尝试尽最大程度在同适当的地方对相同类型的element,做patch或者reuse。
使用key:vue根据key的顺序记录element,曾经拥有了key的element如果不再出现的话,会被直接remove或者destoryed
在这里插入图片描述

组件传值的方法

父组件向子组件传值用props
子组件向父组件传值用$emit
兄弟组件传值:

// 创建一个事件总线 新建一个bus.js文件
import Vue from 'vue';
export default new Vue;
// 需要传值的组件使用$emit传递参数
import bus from '@/common/bus';
bus.$emit(‘transfer’,this.msg)
// 在接收数据的组件中使用$on监听自定义事件
import bus from '@/common/bus';
bus.$on(‘transfer’,(data)=>{
	// data就是兄弟组件传过来的msg
	this.str = data
})

祖孙传值:

// 祖先使用provide传值
provide() {
	return {
    	grandPaMsg: "我是祖先数据",
	};
},
// 子孙使用inject接收值
<template>
  <div>子孙组件:{{ grandPaMsg }}</div>
</template>
<script>
export default {
  inject: ["grandPaMsg"],
};
</script>

vuex mixin 浏览器存储等

vue子组件和父组件创建和挂载的顺序

创建过程自上而下,挂载过程自下而上
parent created => child created => child mounted => parent mounted

vue中的data为什么是函数而不是对象?

函数有自己的作用域,组件被复用时,每个组件都有自己的数据,这样组件之间才不会相互干扰

watch和computed的区别

watch特点:侦测变化,执行回调
watch监听的数据必须是在data里声明或从父组件传过来的数据,当监听的数据发生改变时会触发,无缓存支持异步
computed特点:有响应式的返回值
computed监听的数据直接定义在computed里面,当传入的数据发生改变就会触发,有缓存不支持异步

//watch场景:一个数据影响多个数据
watch:{
	newObj:{
		handle(newV,oldV){}
		deep:true
	}
}
//computed场景:一个数据受多个数据影响
computed:{
	newStr(){
		return this.str.toUpperCase()
	}
}

computed特性

1、computed是惰性的。computed依赖的数据发生变化时,computed不会立即计算,要等到求值时才会重新计算
2、computed是有缓存的。computed依赖的数据没有变化,及时重新对computed求值,也不会重新计算

computed缓存原理

当computed依赖的数据发生变化时才会清空缓存重新计算
computed的缓存机制是通过dirty属性控制的,当依赖数据变化时dirty就会设置为true,才会重新计算结果,计算后dirty再次设为false

keep-alive

作用:缓存组件,提升性能;
添加了activated和deactivated生命周期,首次进入keep-alive页面触发了beforeCreate、created、beforeMount、mounted、activated,再次进入只触发activated;离开组件时触发了deactivated

// 只缓存组件名字为home的组件
<keep-alive include="home"></keep-alive>
// 除了组件名字为home的组件不缓存,其他都缓存
<keep-alive exclude="home"></keep-alive>

什么是插槽slot

默认插槽:把父组件的内容分发到子组件<slot></slot>
具名插槽:通过name属性将不同的内容分发到不同的位置

// 父组件
<Son>
	<p slot='a'></template>
</Son>
// 子组件
<slot name='a'></slot>

作用域插槽:将子组件的数据反馈到父组件

// 父组件
<slot-child><template slot-scope='scope'>{{scope.str}}</template></slot-child>
// 子组件
<slot :str='我是子组件数据'></slot>

vue有哪些修饰符

.trim 首尾去空格
.number 先输入数字就限制只能输入数字
.lazy 光标离开后在更新input数据

vue2为什么监听不到数组

Vue中使用object.defineProperty监听数据,但数组长度不定且数据太多,出于性能考虑使用this.$set

vue生命周期

beforeCreate创建前,在数据观测和初始化事件还未开始时触发
created创建后,会完成数据观测属性和方法的运算
beforeMount挂载前,render函数被调用生成虚拟DOM
mounted挂载后,DOM树渲染到页面,页面可以进行DOM操作
beforeUpdate更新前,数据有更新时调用
updated更新后,调用时组件已更新
beforeDestroy销毁实例前调用,实例仍可用
destroyed实例销毁后调用

vue中created和mounted的区别

created在模板渲染前调用,数据初始化请求放在created里
mounted在模板渲染后调用,依赖DOM的请求放在mounted里

vue数据双向绑定原理

通过object.defineProperty劫持数据的改变,如果数据改变了(在set中赋值),触发update方法更新节点内容,从而实现数据双向绑定

什么是MVVM

MVVM是model view viewmodel的缩写,model代表data数据访问层,view代表视图,viewmodel是在视图和模型之间进行通信
优点:耦合度低,可重用性高

怎么理解Vue单向数据流

父组件向子组件传值,子组件不能直接修改父组件传过来的数据
如何修改:子组件使用$emit让父组件修改;子组件将传过来的数据重新赋值

对vue响应式的理解

1、数据响应式就是能够检测数据变化并对这种变化作出响应的机制
2、响应式过程:
数据劫持(侦测数据的变化)
依赖收集(收集视图依赖了哪些数据)
发布订阅模式(数据变化时,通知需要更新的视图,并进行更新)
3、vue 目前通过 Object.defineProperty 来实现数据响应式。

对虚拟dom的理解

虚拟dom本身是一个JavaScript对象,它通过不同的属性去描述一个视图结构
优点:减少直接操作dom的次数,提高程序性能;方便实现跨平台
在这里插入图片描述

虚拟DOM的原理

1、用JavaScript模拟并渲染DOM树
2、比较新老DOM树,得到差异对象
3、将差异对象渲染到DOM树上

对diff算法的理解

是什么:diff算法是虚拟dom技术的必然产物:diff就是对比新旧虚拟dom,将变化的地方更新到真实的dom上。
何时执行:组件数据发生变更时通知该组件执行渲染函数得到最新的虚拟dom,对比新旧虚拟dom找到变化的地方,将其转化为对应的dom操作
diff策略:深度优先、同层比较。

  1. 比较同层节点
  2. 没有相同节点就删除重新创建,
  3. 节点相同,双方都是文本则更新文本内容
  4. 节点相同,双方都是元素节点,则递归更新子元素,同时更新元素属性
  5. 更新子节点又分为以下几种情况:
    新子节点为文本,老子节点为数组,则清空数组设置文本
    新子节点为文本,老子节点为文本,则更新文本
    新子节点为数组,老子节点为文本,则清空文本并创建数组中的子元素
    新子节点为数组,老子节点为数组,则比较两组子节点,vue2使用双端算法从开头结尾找相同节点,如果找到就直接做比对

nextTick的使用和原理

作用:获取更新后的dom
原理:vue有异步更新机制,响应式数据发生变化vue不会立刻更新dom,开启一个队列存放组件的更新函数,同步代码执行完毕之后,使用异步的方式清空队列
场景:created中获取dom;响应式数据变化后获取更新后的dom

从template到render发生了什么

vue通过compiler编译器将template编译为js可执行的render函数
1、通过parser将template解析成AST抽象语法树
2、遍历AST标记所有的静态节点
3、将AST生成render函数

Vue实例挂载过程发生了什么

挂载过程指的是app.mount()过程
1、初始化。创建组件实例,初始化组件状态,创建各种响应式数据
2、建立更新机制。执行组件的更新函数,执行渲染函数得到虚拟DOM,通过patch将虚拟DOM转换成真实DOM;同时将我们的数据和组件的更新函数之间建立一个依赖关系,使得数据变化时执行对应的更新函数

vue优化方法有哪些

路由懒加载
keep-alive缓存组件
合理使用v-show和v-if
避免同时使用v-for和v-if
长列表性能优化
离开页面时,销毁定时器
图片懒加载<img v-lazy=''></img>
代码组件化
第三方插件按需加载
服务端渲染SSR

为什么选择使用vue

轻量级;简单易学;
组件化,方便管理维护;
响应式

vue的缺点

vue单页面应用不利于SEO优化
初次加载耗时多

SPA单页面应用

优点:前后端分离;减轻服务器压力
缺点:不利于SEO优化;首屏加载时间长

intercepetor拦截

请求拦截:

// 在请求头添加token
axios.interceptors.request.use((config)=>{})

响应拦截:

// 统一返回错误信息
axios.interceptors.response.use((res))=>{}

mixin是什么

用来分发vue组件可复用的组件
知识点:
混入对象的变量是不会共享的
同名钩子函数被调用,mixin比组件先执行
mixin的变量和组件的变量冲突,则以组件优先

mixin和vuex的区别

vuex是状态共享管理,vuex的变量和方法都是可以读取、更改并相互影响的;
mixin可以定义公共的变量和方法,引入组件后,各个变量都是相互独立的,值的修改不会相互影响

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值