学---前端框架及项目面试-聚焦Vue---笔记

vue面试

基本使用

1.插值和指令

v-html

​ 有xss风险

2.computed和watch

​ computed:有缓存效果,data中的值不变则不运行

如何深度监听

​ 在监听数组对象时,监听不到内部的变化,只有打开深度监听

​ 在watch中添加:deep:true

监听引用类型,拿不到oldval
  watch: {
        name(oldVal, val) {
            // eslint-disable-next-line
            console.log('watch name', oldVal, val) // 值类型,可正常拿到 oldVal 和 val
        },
        info: {
            handler(oldVal, val) {
                // eslint-disable-next-line
                console.log('watch info', oldVal, val) // 引用类型,拿不到 oldVal 。因为指针相同,此时已经指向了新的 val
            },
            deep: true // 深度监听
        }
    }

3.class和style

  • 1.动态属性
  • 2.驼峰式写法
<template>
    <div>
        <p :class="{ black: isBlack, yellow: isYellow }">使用 class</p>
        <p :class="[black, yellow]">使用 class (数组)</p>
        <p :style="styleData">使用 style</p>
    </div>
</template>

<script>
export default {
    data() {
        return {
            isBlack: true,
            isYellow: true,

            black: 'black',
            yellow: 'yellow',

            styleData: {
                fontSize: '40px', // 转换为驼峰式
                color: 'red',
                backgroundColor: '#ccc' // 转换为驼峰式
            }
        }
        
    }

4.v-if和v-show

  • 1.区别

    ​ v-if是条件渲染
    v-show:只是添加了display:none

  • 2.使用场景

    ​ 使用频繁用v-show,因为v-if会使页面重排

5.v-for

  • ​ :key不要直接使用index,因为两个嵌套的for,index会重复,并且性能不高
  • ​ v-if不能跟v-for放一起,因为v-for先执行, 导致多次if的判断 ,所有要放在不同标签

6.event

  • ​ event.proto.constructor 是原始的构造函数

  • ​ taget

  • ​ currenttagt

  • ​ event是原生的

  • ​ 2事件被挂载到当前元素

7,表单

v-model
  • ​ .trim
  • ​ .lazy 输入完在执行
  • ​ .number 转换为数字
表单

​ v-model可以是数组,多选的话,值由value来控制

8.props $emit

属性传递
:属性=value    
props:['属性']
触发事件
this.$emit('自定义事件名',val)
自定事件名 = '下面函数名'  //这里时不要写参数的,参数在methods的函数写

​ 总结:以左边为媒介

9.自定义事件

兄弟间传值(任何两个组件)
调用事件
event.$emit('自定义事件名',val)  //注意和父子传值区别,event
event.$on('自定义事件名',触发的函数名)  //绑定事件
beforeDestory(){
	event.$off('自定义事件名',触发的函数名)   //及时销毁,以免内存泄漏
}

10.生命周期

img
单文件
  • ​ created:vue实例创建完毕
  • ​ mounted:页面渲染完
  • ​ updataed:更改data数据时
  • ​ detoryed:触发 vm.destory()时,在beforeDestory要解除绑定、销毁子组件及事件监听器
多个组件
  • ​ ”父子子父“嵌套的顺序执行执行
  • ​ 销毁的时候先销毁子组件,再销毁父组件

高级特性

1,自定义v-model

2,$nextTick

  • ​ Vue是异步渲染

  • ​ data改变之后不会立刻渲染, 所以如果下一步直接获取dom的话, 获取到的是还没有更新的dom

  • ​ this.$nextTick是页面渲染完后的一个回调,以获取最新的dom节点

  • ​ $ref:用来获取dom元素

  this.$nextTick(()=>{
  	this.$ref.node
  })

3,slot

  • ​ 基础用法

​ 默认值可以再slot里随便写的

  • ​ 作用域

​ 是为了从子组件获取数据

//子组件
	<slot :自定义名="data">
	<slot>
//父组件
	<tempelate v-slot="scope">
	{{scope.自定义名}}
  • ​ 具名插槽

​ 为了插入指定插槽,当插槽多时

//子组件
	<slot name="data">
	<slot>
//父
	<tempelate v-slot="data">

4,动态组件

​ 根据不同的组件名,渲染不同的组件

  <component :is="组件名">

5,异步加载组件

​ 什么时候用到再去加载,如果一开始就加载导致进入页面慢

 <自定义组件 v-if='false'>
 components:{
 	自定义组件:()=>import('../aas/ddd')  //当false变成true再引用
 }

6,keep-alive

  • ​ 缓存组件

  • ​ 频繁切换,不需要渲染(tab栏

  • ​ vue性能优化

 <keep-alive>
	tab栏     //组件内的组件,切出去后不会被销毁  //与v-show相比,更适合复杂的切换
</keep-alive>

7,mixin

8,老师说的:可以不用深入,但要知道,最好能跟项目经验结合起来

9,vuex

 state
 getter
 mutation
 action

10.vue-router

  • ​ 懒加载

  • ​ hash和history,后者必须服务端支持

配置路由时
  {path:login/:id 
  	components:()=>import('../aas/ddd')
  }

原理

1组件化基础

很久以前的组件化

​ 传统组件只是静态改变了数据,跟新依然要操作dom

数据驱动视图(mVVM,setState)

​ vue-mVVM

​ react-setState

2MVVM

​ view----viewmodel—model

​ template data

在这里插入图片描述

3响应式

data发生变化,立即触发视图跟新

​ 原理上就是,单纯的改变属性是无法直接响应,

​ 而是要触发个函数才会影响视图

核心API:Object.defineProperty
基本用法
    const data = {name :"lisi"};
    Object.defineProperty(data, "name", {
      get: function () {
        console.log("get");  //获取date.name时会触发这个函数
        return name;
      },
      set: function (newval) {
        console.log("set");		//给date.name赋值时触发set
        name = newval;
      },
    });

    console.log("data :>> ", data);
    data.name = "wocao";
深度监听

​ 需要递归到底

// 重新定义属性,监听起来
function defineReactive(target, key, value) {
    // 深度监听
    observer(value)

    // 核心 API
    Object.defineProperty(target, key, {
        get() {
            return value
        },
        set(newValue) {
            if (newValue !== value) {
                // 深度监听
                observer(newValue)

                // 设置新值
                // 注意,value 一直在闭包中,此处设置完之后,再 get 时也是会获取最新的值
                value = newValue

                // 触发更新视图
                updateView()
            }
        }
    })
}
几个缺点

​ 需要递归到底,计算量大

​ 无法监听新增属性和删除属性(Vue.set Vue.delete)

监听数组

​ Object.defineProperty无法监听数组,这时要重新定义数组原型

  //创建对象  将对象原型指向数组原型  可以在对象上扩展新的方法而不影响原始原型
    const arrproto = Object.create(Array.prototype);
    ['push',"shift"].array.forEach(element => {
      arrproto[element]=function(){
        console.log("跟新视图");
        //执行原始push
        Array.prototype[element].call(this,...arguments)
        //this指向函数调用者,
      }
    });
    //监测为数组是,把他的原型换成自定义原型
    target.protype = arrproto
    

4,虚拟dom

  • vdom是vue和react核心
  • diff算法是vdom最核心的部分

vdom:用js模拟dom结构,js运行快,计算出最小的变更,操作dom .diff则是比较vdom

在这里插入图片描述

snabbdom来学习vdom

diff算法 diff:对比

2js可diff

2树可diff,如vdom

树dif的复杂度

​ 两颗树做比较,每个节点都互相做比较,就会比较n的平方次, 还排序就是n3次方,算法不可以

​ 解决

​ 只比较同层

​ tag不同直接删掉重建,不深度比较

​ tag和key,都相同,则认为是相同节点,不深度比较
在这里插入图片描述

5模板编译

js的with语法

  • {}里的自由变量,用obj.a的方式查找
  • 匹配不到obj属性,会报错

在这里插入图片描述

vue template complier 将模板编译成render函数

执行render函数生成vnode,patch(diff算法)可将vnode渲染成html

vnode为dom的js版,也就是虚拟dom

总结

  • 响应式: 监听data属性 getter setter (包括数组)
  • 模板编译: 模板到 render函数 ,再到vnode
  • vdom: patch(elem,vnode) patch(vnode,newnode)

6,vue组件的渲染和跟新过程

初次渲染

  • 解析模IC板生产render函数(或是在开发环境已完成,vue-loader)
  • 触发响应式, 监听data属性 getter setter
  • 执行render函数, 生成vnode , patch(elem,vnode)

在这里插入图片描述

跟新过程

  • 修改data,触发setter(此前在getter中已被监听)
  • 重新执行render函数, 生成newnode
  • patch(vnode,newVnode)

在这里插入图片描述

​ 响应式(紫色):监听属性,更改属性会通知,看看是不是之前收集过

​ 模板渲染(黄色):执行render会触发getter,收集依赖

​ 虚拟dom(绿色)

异步渲染

  • $nextTick: 多次修改data时,等dom渲染完时再回调
  • 汇总data的修改,一次性进行渲染
  • 减少操作dom次数,提高性能

7,路由

hash

​ 网页组成部分

image-20200818153124167

​ 特点

  • hash变化触发跳转,及前进后退
  • 不会刷新页面
  • 不会提交到服务端

​ hash变化

<script>
        // hash 变化,包括:
        // a. JS 修改 url
        // b. 手动修改 url 的 hash
        // c. 浏览器前进、后退
        window.onhashchange = (event) => {
            console.log('old url', event.oldURL)
            console.log('new url', event.newURL)

            console.log('hash:', location.hash)
        }

        // 页面初次加载,获取 hash
        document.addEventListener('DOMContentLoaded', () => {
            console.log('hash:', location.hash)
        })

        // JS 修改 url
        document.getElementById('btn1').addEventListener('click', () => {
            location.href = '#/user'
        })
    </script>

H5history

  • 用url规范的路由,但跳转不刷新
  • history.pushState(state,”,page1):跳转到page1
  • window.onpopstate=(event)=>{} :监听浏览器前进后退 event.name能够拿到当前页的state
  • 后端要配置: 简单点说, 后端无论拿到什么路由,都返回index.html

总结

hash—window.onhashchange

history—history.pushState 和 window.onpopstate

真题模拟

1 v-show 和 v-if

v-show是加了dispaley:none的显示隐藏

v-if是条件渲染销毁,而不是显示隐藏

使用频繁用v-show

2为何在v-if中使用key

增强性能,diff算法,判断tag和key, 如果都相同 ,就判断为 是相同的节点, 就不会再向下比较

不能使用index和random

3描述生命周期(单组件和父子组件)

beforecreated new Vue 初始化生命周期和事件完

created 初始化注入和校验完

beforemounted vm.$mount(el)指定el元素 指定template模板 将template编译到render渲染函数

mounted 创建vm.$el替换el ,页面渲染挂载完成

beforeupdataed data被修改后

updataed 跟新完成,data改变,虚拟dom重新渲染

beforedestory vm.$destory后

destory 销毁子组件及事件监听器 解除绑定

子组件先于父组件

4,vue组件如何通讯

  • 1父子 v-on props
  • 2,子父 this.emit 自定义事件
  • 3,兄弟 event.$emit event .on绑定 event.off解绑
  • 4,vuex

5,描述组件渲染更新的过程

组件render函数,渲染虚拟dom的过程中,会触发getter,getter将收集这个属性监听起来. 当data中属性发生改变,触发setter, 会通知,有没有收集了这个属性, 有的话,这重新渲染vdom

6,v-model的实现原理

通过input事件 this.data=$evnet.target.value

:value=data

改变data, 触发render,重新渲染

7,对mvvm的理解

数据驱动视图

view = >监听 => model

view <=指令<=model

8,computed有何特点

缓存,data不改变就不执行

9为何data必须是个函数

vue文件,本质是个构造函数. 当实例化两个,改变data值时, 如果data是对象, 那么另一个的data也会改变. 但如果是函数,返回的是个全新的数据对象

10ajax放在哪个生命周期

mounted

因为 生命周期是单线程 , ajax是个异步 , 如果放mounted之前 , 他也会排到队列里 , 等渲染完成

11 多个组件有相同逻辑,如何抽离

mixin

12何时使用异步组件

加载大组件

路由异步加载

需要用时再去加载

13何时使用keeplive

给组件缓存

想tab栏静态

14何时使用beforeDestory

解绑事件 event.$off

清除计时器

解绑自定义dom事件 如 window scroll

15什么是作用域插槽

可以拿到父组件的数据

v-slot=‘scope’

slot :scope=‘data’

16vuex中的action和mutation的区别

action处理异步,mutation处理同步

mutation更多是单个操作

action可以整合多个mutation

17vue常用的路由模式

hash

history(需后端配合)

18 如何配置vue-router异步加载

components:()=>(import ‘…/’)

19用vnode描述一个dom结构

<div class=aa> 
	<text style='color:red'>dd</text>
</div>

{
	tag:div,
	props:{
		classname:aa
	}	
	children:[
		{
			tag:text
			style:cloor:red
			children:aa
		}
	]
	
}

20监听data变化的核心api是什么

Obeject.difineProperty

深度监听:递归调用

监听数组:自定义数组原型 Array.property.

21响应式原理

监听data变化

组件渲染更新流程图

22diff算法的时间复杂度

o(n)

原本是n的3次方

通过同层级比较,以及tag和key进行优化

23,Vue为何是异步渲染,$nexttick有什么用

异步渲染(合并data修改),为了提高性能

nexttick是组件渲染完的回调函数,用来拿到最新的dom

24,vue常见性能优化

v-if 和 v-show

computed

v-for key , 避免 v-for 和v-if同时用

自定义事件\ dom事件 及时销毁

异步组件

keeplive

data层级不要太深, 底层监听会 递归 ,影响性能

webpack

前端通用,如 图片懒加载

ssr

简述diff算法的过程

如何将组件所有props穿给子组件

$porps

v-bind = “prop”

如何自己实现v-model

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值