vue面试题(day05)

vue3中Composition API 的优势?

1.了解 Options Api

Options API,即大家常说的选项API,即以vue为后缀的文件,通过定义methods,computed,watch,data等属性与方法,共同处理页面逻辑。

Composition

在 Vue3 Composition API 中,组件根据逻辑功能来组织的,一个功能所定义的所有 API 会放在一起(更加的高内聚,低耦合),即使项目很大,功能很多,我们都能快速的定位到这个功能所用到的所有 API,Compositon API,将某个逻辑关注点相关的代码全都放在一个函数里,这样当需要修改一个功能时,就不再需要在文件中跳来跳去。

composition APi:
  • setup

     Vue3.0中一个新的配置向,值为一个函数
     setup是所有Composition API(组合API) ”表演的舞台“
     组件中所有用到的:数据、方法等等,均要配置在setup中
    
  • setup语法糖

     <script setup> 语法糖里面的代码会被编译成组件setup()函数的内容,不需要通过return
     暴露声明的变量、函数以及import引入的内容,即可在<template/>使用,并且不需要
     export default{}
    
  • ref函数

    作用:定义一个响应式的数据。
    基本类型的数据:响应式依然是靠Object.defineProperty()的get和set完成的
    对象类型的数据:内部“求助”了Vue3.0的一个新的函数------reactive函数

  • reactive函数

    作用:定义一个对象类型的响应式数据

  • defineEmits

setup语法糖中引入defineEmits方法,传入数组,数组里面则是父组件传递的自定义事件名。

  • 自定义hooks

    ve3中还可以自定义 hooks, 将单个功能封装成单个的函数,在集成到组件中去复用! 将功能进行解耦,方便维护、复用、可读性强

2.shallowReactive和shallowRef的区别?

shallowReactive:只处理对象最外层的响应式(浅响应式)。
shallowRef:只处理基本数据类型的响应式,不进行对象的响应式处理。
使用场景:

	如果有一个对象数据,结构比较深,但变化时候,只是外层属性变化,使用shallowReactive。
	如果有一个对象数据,后续功能不会修改改对象中的属性,而是生成新的对象来替换,使用shallowRef。

3.provide与inject如何使用?

概述:父子组件传参可以通过props和emit来实现,但是当组件的层次结构比较深时,props和emit就没什么作用了。vue为了解决这个提出了Provide / Inject;provider/inject:简单的来说就是在父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量.
作用:实现祖和后代组件间通信。
例如:
provide()函数
定义:提供一个值,可以被后代组件注入。

具体实现:

父组件有一个provide选项提供数据,后代组件有一个inject选项来开始使用这些数据。
provide(第一个参数是要注入的key,它可以是一个字符串或一个symbol;第二个参数是要注入的值(具体要传递给子孙组件的数据)。

import {reactive,provide} from "vue"; 
let person = reactive({name: '张三',age: 14});
provide('person',person);

inject()函数
定义: 注入一个由祖先(父)组件或整个应用提供的值
实现: 接收父(祖)组件传递过来的值.

具体实现

inject(第一个参数,第二个参数(可选)):第一个参数是注入的key,来自父(祖)组件,它们两者是需要保持一致的

Vue会遍历父组件链,通过匹配key来确定所提供的值,如果父组件链上多个组件对同一个key提供了之,那么离得更近的将会覆盖链上更远的组件所提供的值

如果没有能通过key匹配到的值,inject()函数将返回undefined,除非提供一个默认值

第二个参数是可选的,即没有匹配到key时,使用默认值,它也可以是一个函数,用来返回某些创建起来比较复杂的值,如果默认值本身就是一个函数

那么必须将false作为第三个参数传入,表明这个函数就是默认值,而不是一个工厂函数。

与注册生命周期钩子的API类似,inject()必须在组件的setup()阶段同步调用

import {inject,toRefs} from  "vue";
const person = inject('person');
// 若是使用解构,则会丢失响应式,修改数据时,页面不会更新,具体解决,可以引入toRef或toRefs函数
const {name,website} = toRefs(person);

模板使用
{{person.name}}---{{person.website}}

总结

provide/inject 做全局状态管理的原则:
多人协作时,做好作用域隔离;
尽量使用一次性数据作为全局状态

4.toRaw 与 markRaw是什么作用?

  • toRaw

     作用:将一个由reactive生成的响应式对象转化为普通对象。
     使用场景:用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新.
    
  • markRaw:

     	作用:标记一个对象,使其永远不会再成为响应式对象。
     	应用场景:
     		1.有些值不应被设置为响应式的,例如复杂的第三方类的库。
     		2.当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能。
    

5.readonly 与 shallowReadonly谈谈你对他的理解?

  • readonly:让一个响应式数据变为只读的(深只读)。
	readonly是一个函数,他会接收一个响应式的数据,如上定义的name变量,将该变量加工一番readonly函数
	包裹后后重新返回一个name,这个重新返回的name变量中的所有的东西都不允许修改,所以我们现在再
	点击上面的修改按钮 name 变量也不会有任何改变,并且控制台会有警告。
<template>
  <h1>{{ name }}</h1>
  <h1>{{ age }}</h1>
  <button @click="age++">age+1</button>
</template>

<script setup>
import { ref, reactive, readonly, shallowReadonly, toRefs} from 'vue'

let name = ref("张三")
let age = ref(18)
let job = reactive({
          salary:{  value:70  }
        })
name = readonly(name)
age = readonly(age)
job = readonly(job)
</script>
  • shallowReadonly:让一个响应式数据变为只读的(浅只读)。
shallowReadonly只限制对象中的第一层数据(不能改动,如:salary),但是嵌套的深层次的value属性值
是可以更改的,我们点击更改按钮测试就能发现,被shallowReadonly包裹的对象的深层次值改变了。
<template>
  <h1>{{ job }}</h1>
  <!--> 不可以修改 <-->
  <button @click="job.salary = { value: 80 }">修改salary</button>
  <!--> 可以修改 <-->
  <button @click="job.salary.value = 100">修改value</button>
</template>

<script setup>
import { ref, reactive, readonly, shallowReadonly, toRefs} from 'vue'

let job = reactive({
          salary:{  value:70  }
        })
        
job = shallowReadonly(job)
</script>

6.自定义hook是什么?

在 Vue 3 中,Hook 是通过 Vue 3 新特性的最重要的部分——组合式 API 来实现的.
本质是一个函数。自定义hook,就是将setup中使用过的组合式函数进行封装,实现代码复用。
把数据、方法、和生命周期钩子封装在一个js文件。
在src目录下新建子目录hooks,并在hooks目录下新建文件:usePoint.js
在这里插入图片描述

7.虚拟DOM一定更快吗?

虚拟DOM/domDiff

我们常说的虚拟DOM是通过JS对象模拟出来的DOM节点,domDiff是通过特定算法计算出来一次操作所带来的DOM变化。react和vue中都使用了虚拟DOM,我们借着react聊聊虚拟DOM。

react中涉及到虚拟DOM的代码主要分为以下三部分,其中核心是第二步的domDiff算法:

把render中的JSX(或者createElement这个API)转化成虚拟DOM
状态或属性改变后重新计算虚拟DOM并生成一个补丁对象(domDiff)
通过这个补丁对象更新视图中的DOM节点

虚拟DOM不一定更快

干前端的都知道DOM操作是性能杀手,因为操作DOM会引起页面的回流或者重绘。相比起来,通过多一些预先计算来减少DOM的操作要划算的多。

但是,“使用虚拟DOM会更快”这句话并不一定适用于所有场景。例如:一个页面就有一个按钮,点击一下,数字加一,那肯定是直接操作DOM更快。使用虚拟DOM无非白白增加了计算量和代码量。即使是复杂情况,浏览器也会对我们的DOM操作进行优化,大部分浏览器会根据我们操作的时间和次数进行批量处理,所以直接操作DOM也未必很慢。

那么为什么现在的框架都使用虚拟DOM呢?因为使用虚拟DOM可以提高代码的性能下限,并极大的优化大量操作DOM时产生的性能损耗。同时这些框架也保证了,即使在少数虚拟DOM不太给力的场景下,性能也在我们接受的范围内。

而且,我们之所以喜欢react、vue等使用了虚拟DOM框架,不光是因为他们快,还有很多其他更重要的原因。例如react对函数式编程的友好,vue优秀的开发体验等,目前社区也有好多比较这两个框架并打口水战的,我觉着还是在两个都懂的情况下多探究一下原理更有意义一些

8.vue路由中,history和hash两种模式有什么区别?

  • hash 模式

hash 模式是一种把前端路由的路径用井号 # 拼接在真实 URL 后面的模式。当井号 # 后面的路径发生变化时,浏览器并不会重新发起请求,而是会触发 hashchange 事件。

<script>
<a href="#/a">A页面</a>
<a href="#/b">B页面</a>
<div id="app"></div>
<script>
  function render() {
    app.innerHTML = window.location.hash
  }
  window.addEventListener('hashchange', render)
  render()
</script>

在上面的例子中,我们利用 a 标签设置了两个路由导航,把 app 当做视图渲染容器,当切换路由的时候触发视图容器的更新,这其实就是大多数前端框架哈希路由的实现原理。

hash 模式的优缺点:

优点:浏览器兼容性较好,连 IE8 都支持
缺点:路径在井号 # 的后面,比较丑。

  • history 模式

history API 是 H5 提供的新特性,允许开发者直接更改前端路由,即更新浏览器 URL 地址而不重新发起请求。

<a href="javascript:toA();">A页面</a>
<a href="javascript:toB();">B页面</a>
<div id="app"></div>
<script>
  function render() {
    app.innerHTML = window.location.pathname
  }
  function toA() {
    history.pushState({}, null, '/a')
    render()
  }
  function toB() {
    history.pushState({}, null, '/b')
    render()
  }
  window.addEventListener('popstate', render)
</script>

history API 提供了丰富的函数供开发者调用:

history.replaceState({}, null, '/b') // 替换路由
history.pushState({}, null, '/a') // 路由压栈
history.back() // 返回
history.forward() // 前进
history.go(-2) // 后退2次

history 模式的优缺点:

优点:路径比较正规,没有井号 #
缺点:兼容性不如 hash,且需要服务端支持,否则一刷新页面就404了。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值