2022-03-10

一 vue

vue的优点?

  • 渐进式
  • 组件化开发
  • 虚拟dom
  • 响应式数据
  • 单页面路由
  • 数据与试图分开
    用户体检好,内容改变的时候不需要加载整个页面,避免不必要的重复渲染和跳转
    基于上面一点 single 相对于服务器压力小
    前后端职责分离,架构清晰

vue的缺点?

  • 单页面不利于SEO
  • 首屏加载时间长
  • 不兼容IE
    初始加载耗时, seo难度较大: 由于所有的内容都在一个页面中动态替换显示 所有 seo有着天然的劣势

为什么说Vue是一个渐进式框架?

Vue的全家桶,你可以选择不用,或者只选几样去用,比如不用vuex
根据场景,官方提供了方便的框架供你使用

Vue跟React的异同点?

相同点:
  • 都是单向数据流
  • 都使用了虚拟DOM的技术
  • 都支持SSR
  • 组件化开发
不同点:
  • 前者template,后者JSX
  • 数据改变,前者响应式,后者手动setState
  • React单向绑定,Vue双向绑定
  • React状态管理工具Redux、Mobx,Vue状态管理工具Vuex

MVVM是什么?和MVC有何区别呢?

MVC

  • Model:负责从数据库中取数据
  • View:负责展示数据
  • Controller:用户交互的地方,例如点击事件

MVVM

  • VM:就是View-Model,数据双向绑定
  • Model:取数据的地方
  • View:展示数据的地方

组件中的data是个函数并且返回一个对象呢?

组件是用来复用的, js 的对象是引用关系,如果组件中的data是一个对象,这样作用域没有隔离,子组件中的data属性值会互相影响

使用过哪些Vue的修饰符呢?

  • .lazy:输入框失焦时才会更新v-model的值
  • .trim:讲v-model绑定的值首位空格给去掉
  • .number:将v-medol绑定的值转数字
  • .stop:阻止事件冒泡
  • .capture:事件的捕获
  • .self:点击事件绑定本身才触发
  • .once:事件只触发一次
  • .prevent:阻止默认事件
  • .native:绑定事件在自定义组件上时,确保能执行
  • .left、.middle、.right:鼠标左中右键的触发
  • passive:相当于给移动端滚动事件加一个.lazy
  • camel:确保变量名会被识别成驼峰命名
  • .sync:简化子修改父值的步骤

这样理解vue单向数据流?

父组件传输props给子组件时,子组件只能使用不能修改,这是为了组件之间更好的去解耦.比如有一个父组件,传props给10个子组件,如果某一个子组件修改了,那么会影响其它9个子组件跟着刷新,所以不推荐子组件修改props

组件之间的通信方式都有哪些,用过eventBus,eventbus的是想是什么

  • 父组件传值给子组件数据props
  • 子组件传值给父组件,通过$emit事件对父组件进行传值
  • 父组件和之组件通过parent 和children进行获取实例数据
  • 二次封装时经常使用attrs 和listener进行传值
  • 使用$refs 获取实例组件,进行数据获取
  • 使用vuex 进行状态管理
  • 使用eventBus 进行跨组件传值 进而传递数据(发布订阅模式)
  • 使用provide 和inject官方不建议 一般用户UI组件开发
  • 浏览器本地缓存 例如localStorage
  • 路由传值

写个自定义 v-model?

v-model实际是:value + @input的语法糖

<input v-model="inputValue" />

<input 
:value="inputValue" 
@input="inputValue = $event.target.value" 
/>

attrs 和 $listener 有了解吗?

常用于对组件进行二次封装时,比如A -> B -> C,B可以直接将爷爷组件的所有数据或者事件直接传给孙子

Vue 生命周期有哪些,都是做什么的,updated 什么情况下会触发,beforeCreate 的时候能拿到 Vue 实例么,组件销毁的时候调用的是哪个 API

  • beforeVCreated:实例了Vue但是还没有进行数据初始化与响应式处理
  • created 数据已经被初始化和响应式处理,这里可以访问和修改数据
  • beforeMount render函数在这里调用,生成虚拟DOM,但是还没有转真实DOM并替代到el
  • mounted 真实DOM挂载完毕
  • beforeUpdated 数据更新后,新的虚拟DOM生成,但还没更旧虚拟DOM对比打补丁
  • update 新旧虚拟DOM对比打补丁后,进行真实DOM的更新
  • activated 被keep-alive 缓存的组件被激活时调用
  • deactivated 被keep-alive缓存的组件停用时调用
  • beforeDestroy 实例销毁之前调用,在这一步,依然可以访问数据
  • destroyd 实例销毁后调用 vue实例的所有指令都被解绑,实例的监听器被移除,所有子实例也都被销毁
  • errorCapured 捕获子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回false以阻止该错误继续向上传播。

什么情况下会触发组件销毁,销毁的时候会卸载自定义事件和原生事件么?

组件销毁时会自动卸载组件本身绑定的事件,但是仅限于组件本身。例如一些定时器、全局对象的事件绑定、eventBus则不会自动解绑,需要手动解绑。

自定义指令写过么,自定义指令都有哪些钩子?

vue2
  • bind 指令绑定到指定元素时触发,只触发一次
  • inserted 指令元素插入到DOM时触发,只触发一次
  • update:VNode更新时触发,会触发多次
  • unbind 指令解绑时触发,只触发一次
vue3
  • created:指定元素的attribute或事件监听器被应用之前被调用
  • beforeMount:指令绑定到指定元素上触发
  • mounted:指定元素被挂载时触发
  • beforeUpdate:在更新包含组件的VNode之前触发
  • updated:在包含组件的VNode及其VNode更新后调用
  • beforeUnMount:在卸载指定元素的父组件之前触发
  • unmounted:指令解绑时触发

Vue2 的数据响应式有两个缺陷,你知道是哪两个缺陷么,为什么会有这样的缺陷,如何解决?

  • 对象新增属性或修改新增的属性时,无法触发视图更新,需要使用 Vue.set,对象删除属性时需要使用Vue.delete才能触发更新
  • 数组直接通过下标修改元素无法触发视图更新,需要使用数组的方法splice、push等等

vue 如何实现对数组的监听,为什么vue没有对数组下标修改做劫持?

vue2是通过重写了数组原型上的方法来达到对数组的修改的监听,vue2没有对数组下标做劫持,是出于心梗的考虑,因为通常数组元素都是非常多的,可能成百上千,如果每个元素都进行劫持,则非常耗费性能。

路由的几种模式?

  • hash 哈希模式 根据hash值的更改进行组件切换,而不刷新页面
  • history 历史模式 依赖于HTML5 的pushState和replaceState
  • abstract:适用于Node

路由的钩子函数?

全局钩子

beforeEach:跳转路由前

  • to:将要跳转进入的路由对象
  • from:将要离开的路由对象
  • next:执行跳转的方法

afterEach:路由跳转后

  • to: 将要跳转进入的路由对象
路由独享钩子
routes: [
  {
    path: '/xxx',
    component: xxx,
    beforeEnter: (to, from, next) => {
      
    }
  }
]
组件内路由钩子
  • beforeRouteEnter(to, from, next):跳转路由渲染组件时触发
  • beforeRouteUpdate(to, from, next):跳转路由且组件被复用时触发
  • beforeRouteLeave(to, from, next):跳转路由且离开组件时触发

使用过哪些Vue的内部指令呢?

  • v-text:元素的textContent
  • v-html:元素的innerHTML
  • v-show:通过样式display改变显隐
  • v-if:通过操作DOM改变显隐
  • v-else:配合v-if
  • v-else-id:配合v-else
  • v-for:循环渲染
  • v-on:绑定事件,缩写@
  • v-bind:绑定变量,缩写:
  • v-model:双向绑定
  • v-slot:插槽
  • v-once:只渲染一次
  • v-pre:跳过元素编译
  • v-cloak:隐藏双括号,有值再显示

v-if和v-show有何区别?

  • v-if 通过操作dom来控制显隐,适用于偶尔显隐的情况
  • v-show 通过改变样式display属性控制显隐,适用于频繁显隐的情况

computed和watch有何区别?

computed

计算属性将会混入到Vue的实例当中,所有 getter 和 setter 的 this 上下文自动地绑定为 Vue 实例。

  • 监控自定义变量,这个变量不可以和data 和props里面的变量重复;
  • computed属性的属性值是函数默认走get方法(必须有返回值)属性都有一个get和set方法;
  • 支持缓存,依赖多个变量计算出一个变量,只有所依赖的数据发生变化才会重新计算,否则会取缓存中的数据;
  • 不支持异步 在computed里面操作异步无效;
watch
  • 监听data、props里面数据的变化;
  • 不支持缓存,每次都会重新计算;
  • 支持异步,监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
    一般情况下,computed的是 多对一 watch 是一对多

为什么v-if和v-for不建议用在同一个标签上?

v-for的优先级高于v-if每项都通过v-for渲染出来后再去通过v-if判断显隐,做了很多无用功

uex的有哪些属性?用处是什么?

  • state 定义初始状态
  • getter 从store取数据
  • mutation 更改store中的状态 只能同步操作
  • action 用于提交mutation,而不直接更改状态,可异步操作
  • module:store的模块拆分


    微信图片_20220310141143.png

不需要响应式的数据应该怎么处理?

  • 定义在data的return之外
  • 使用Object.freeze进行数据冻结

watch有哪些属性,分别有什么用?

  • immediate: 初次加载时立即执行
  • deep 是否进行深度监听
  • handler 监听的回调函数

父子组件生命周期顺序?

1.父beforeCreate --> 2.父created --> 3.父beforeMount --->
4.子beforeCreate --> 5.子created ---> 6.子beforeMount ---->
7.子mounted ----> 8.父mounted

对象新属性无法更新视图,删除属性无法更新视图,为什么?怎么办?

  • 原因:Object.defineProperty没有对对象的新属性进行劫持
  • 解决:
    1.新增属性:Vue.set(target, key, value)
    2.删除属性:Vue.delete(target, key)

直接arr[index] = xxx无法更新视图怎么办?为什么?怎么办?

  • 原因:Vue出于性能考虑没有对数组下标进行劫持,而是通过改写数组原型方法
  • 解决:
  1. splice:arr.splice(index, 1, value)
  2. Vue.set(target, index, value)

nextTick的原理?

维护一个数组,每次调用时讲回调函数压入这个数组,然后优先选择微任务,在微任务回调中去执行数组中的所有回调,同时维护一个布尔值,确保每一次队列进行一次执行数组所有回调

let callbacks = []; //回调函数
let pending = false;
function flushCallbacks() {
  pending = false; //把标志还原为false
  // 依次执行回调
  for (let i = 0; i < callbacks.length; i++) {
    callbacks[i]();
  }
}
let timerFunc; //先采用微任务并按照优先级优雅降级的方式实现异步刷新
if (typeof Promise !== "undefined") {
  // 如果支持promise
  const p = Promise.resolve();
  timerFunc = () => {
    p.then(flushCallbacks);
  };
} else if (typeof MutationObserver !== "undefined") {
  // MutationObserver 主要是监听dom变化 也是一个异步方法
  let counter = 1;
  const observer = new MutationObserver(flushCallbacks);
  const textNode = document.createTextNode(String(counter));
  observer.observe(textNode, {
    characterData: true,
  });
  timerFunc = () => {
    counter = (counter + 1) % 2;
    textNode.data = String(counter);
  };
} else if (typeof setImmediate !== "undefined") {
  // 如果前面都不支持 判断setImmediate
  timerFunc = () => {
    setImmediate(flushCallbacks);
  };
} else {
  // 最后降级采用setTimeout
  timerFunc = () => {
    setTimeout(flushCallbacks, 0);
  };
}

export function nextTick(cb) {
  callbacks.push(cb);
  if (!pending) {
    pending = true;
    timerFunc();
  }
}

审查元素时发现data-v-xxxxx,这是啥?

样式模块化scoped的效果,在本组件的标签都会带上data-v-xxx的属性,然后通过属性选择器实现样式模块化的效果

provide 和inject是响应式的吗?

引用数据类型是响应式,基础数据类型不响应式

自定义v-model

export default {
model: {
   event: 'change',
   prop: 'checked'
}
}

为什么不建议用index做key,为什么不建议用随机数做key?

举个例子:

<div v-for="(item, index) in list" :key="index">{{item.name}}</div>

list: [
    { name: '小明', id: '123' },
    { name: '小红', id: '124' },
    { name: '小花', id: '125' }
]

渲染为
<div key="0">小明</div>
<div key="1">小红</div>
<div key="2">小花</div>

现在我执行 list.unshift({ name: '小林', id: '122' })

渲染为
<div key="0">小林</div>
<div key="1">小明</div>
<div key="2">小红</div>
<div key="3">小花</div>


新旧对比

<div key="0">小明</div>  <div key="0">小林</div>
<div key="1">小红</div>  <div key="1">小明</div>
<div key="2">小花</div>  <div key="2">小红</div>
                         <div key="3">小花</div>

可以看出,如果用index做key的话,其实是更新了原有的三项,并新增了小花,虽然达到了渲染目的,但是损耗性能

现在我们使用id来做key,渲染为

<div key="123">小明</div>
<div key="124">小红</div>
<div key="125">小花</div>

现在我执行 list.unshift({ name: '小林', id: '122' }),渲染为

<div key="122">小林</div>
<div key="123">小明</div>
<div key="124">小红</div>
<div key="125">小花</div>

新旧对比

                           <div key="122">小林</div>
<div key="123">小明</div>  <div key="123">小明</div>
<div key="124">小红</div>  <div key="124">小红</div>
<div key="125">小花</div>  <div key="125">小花</div>

可以看出,原有的三项都不变,只是新增了小林这个人,这才是最理想的结果

插槽的使用以及原理?

普通插槽 普通插槽slot会被当做子元素进行解析,最终会被解析成一个_t函数,他接收的第一个参数为插槽的名称,默认是default,也就是_t('default'),执行此函数进行最终元素的渲染,如果是具名插槽,则传对应的插槽名 作用域插槽 插槽会被封装成一个函数放置在scopeSlotes对象中,解析时_t第二个参数接收子组件的数据,并进行渲染

说说nextTick的用处?

修改数据时不能马上得到最新的DOM信息,所以需要使用nextTick,在nectTick回调中可以获取最新DOM信息

vue的hook的使用?

同一组件中使用

这是我们常用的使用定时器的方式

export default{
  data(){
    timer:null  
  },
  mounted(){
      this.timer = setInterval(()=>{
      //具体执行内容
      console.log('1');
    },1000);
  }
  beforeDestory(){
    clearInterval(this.timer);
    this.timer = null;
  }
}

上面做法不好的地方在于:得全局多定义一个timer变量,可以使用hook这么做:

export default{
  methods:{
    fn(){
      let timer = setInterval(()=>{
        //具体执行代码
        console.log('1');
      },1000);
      this.$once('hook:beforeDestroy',()=>{
        clearInterval(timer);
        timer = null;
      })
    }
  }
}
父子组件使用

如果子组件需要在mounted时触发父组件的某一个函数,平时都会这么写:

//父组件
<rl-child @childMounted="childMountedHandle"
/>
method () {
  childMountedHandle() {
  // do something...
  }
},

// 子组件
mounted () {
  this.$emit('childMounted')
},

使用hook的话可以更方便:

//父组件
<rl-child @hook:mounted="childMountedHandle"
/>
method () {
  childMountedHandle() {
  // do something...
  }
},

三 ES6

Symbol 有了解吗,迭代器有了解吗,哪些是可迭代的?

是ES6的特性,具体使用场景有:

symbol
  • 充当对象的属性名,实现私有属性
  • 充当变量,实现单独变量
  • 用来定义类里的私有属性
迭代

迭代器:Iterator,可迭代对象有Array、Set、Map,想将不可迭代对象变成可迭代对象,可以设置Symbol.iterator属性

const t = {
  name: '林三心',
  age: 12
}

t[Symbol.iterator] = function () {
  let index = 0,
    self = this,
    keys = Object.keys(this)

  return {
    next() {
      if (index < keys.length) {
        return {
          value: self[keys[index++]],
          done: false
        }
      } else {
        return {
          value: undefined,
          done: true
        }
      }
    }
  }
}
for (let value of t) {
  console.log(value)
}

用Set获取两个数组的交集,如何做?

合集
const heji = (arr1, arr2) => {
  return [...new Set(arr1.concat(arr2))]
}

交集
const jiaoji = (arr1, arr2) => {
  const temp = new Set(arr1)
  return Array.from(new Set(arr2)).filter(item => {
    return temp.has(item)
  })
}
差集
const chaji = (arr1, arr2) => {
  const temp1 = new Set(arr1)
  const temp2 = new Set(arr2)
  const res = []
  for (let item of temp1) {
    !temp2.has(item) && res.push(item)
  }
  return res
}

实现 Promise.all?

Promise.sx_all = (promises) => {
    return new Promise((resolve, reject) => {
        const result = []
        let count = 0
        for (let i = 0; i < promises.length; i++) {
            const promise = Promise.resolve(promises[i])
            promise.then(res => {
                result[i] = res
                count++
                if (count === promises.length) {
                    resolve(result)
                }
            }).catch(err => {
                reject(err)
            })
        }
    })
}

animation 和 transition 的区别?

  • animation需配合@keyframe,而transition不需要
  • animation可以出发多次,transition只能触发一次
  • animation可以设置多个帧,而transition只有两帧
  • 前者可能会引起多次重回回流,后者会比较少

来源: https://mp.weixin.qq.com/s/Gb_sTNP45T21LHAYk0QXaQ

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容

  • 最近在面试,总结总结遇到的面试题. 基础问题 LRU算法 [内存管理]的一种页面置换算法,对于在内存中但又不用的[...
    在牛魔角上狂码阅读 1,664评论 0 0
  • 完整版推荐在线阅读 https://interview2.poetries.top/[https://interv...
    程序员poetry阅读 3,436评论 2 20
  • 1. vue实现双向绑定的原理? MVVM 模式在于数据与视图的保持同步,意思是说数据改变时会自动更新视图,视图发...
    逸軒阅读 888评论 0 4
  • 目录 1.vue-router是怎么传递参数的 2.v-if和v-for一起使用的弊端以及解决办法 3.befor...
    裁尘的人儿阅读 1,029评论 1 5
  • 听说成年人的自尊都是工资给的,我已经没有自尊两个多月了,哈哈哈 疫情影响很多小伙伴都被破离职了,下面整理了一些常见...
    WEB前端含光阅读 5,756评论 9 156