vue面试题(day05)

简介: 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中
<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了。


相关文章
|
3月前
|
JavaScript 前端开发 应用服务中间件
【Vue面试题三十】、vue项目本地开发完成后部署到服务器后报404是什么原因呢?
这篇文章分析了Vue项目在服务器部署后出现404错误的原因,主要是由于history路由模式下服务器缺少对单页应用的支持,并提供了通过修改nginx配置使用`try_files`指令重定向所有请求到`index.html`的解决方案。
【Vue面试题三十】、vue项目本地开发完成后部署到服务器后报404是什么原因呢?
|
3月前
|
JavaScript
【Vue面试题十五】、说说你对slot的理解?slot使用场景有哪些?
这篇文章深入探讨了Vue中的`slot`概念,包括它的定义、使用场景和分类(默认插槽、具名插槽和作用域插槽),并通过代码示例展示了如何在组件中使用插槽来实现内容的分发和自定义。同时,文章还对插槽的工作原理进行了分析,解释了`renderSlot`函数和`$scopedSlots`对象的角色。
【Vue面试题十五】、说说你对slot的理解?slot使用场景有哪些?
|
3月前
|
JavaScript 前端开发
【Vue面试题二十五】、你了解axios的原理吗?有看过它的源码吗?
这篇文章主要讨论了axios的使用、原理以及源码分析。 文章中首先回顾了axios的基本用法,包括发送请求、请求拦截器和响应拦截器的使用,以及如何取消请求。接着,作者实现了一个简易版的axios,包括构造函数、请求方法、拦截器的实现等。最后,文章对axios的源码进行了分析,包括目录结构、核心文件axios.js的内容,以及axios实例化过程中的配置合并、拦截器的使用等。
【Vue面试题二十五】、你了解axios的原理吗?有看过它的源码吗?
|
3月前
|
JavaScript 前端开发 数据处理
【Vue面试题二十八】、vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?
这篇文章讨论了Vue中实现权限管理的策略,包括接口权限、路由权限、菜单权限和按钮权限的控制方法,并提供了不同的实现方案及代码示例,以确保用户只能访问被授权的资源。
【Vue面试题二十八】、vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?
|
3月前
|
JavaScript 前端开发
【Vue面试题二十七】、你了解axios的原理吗?有看过它的源码吗?
文章讨论了Vue项目目录结构的设计原则和实践,强调了项目结构清晰的重要性,提出了包括语义一致性、单一入口/出口、就近原则、公共文件的绝对路径引用等原则,并展示了单页面和多页面Vue项目的目录结构示例。
|
2月前
|
缓存 JavaScript 前端开发
vue面试题
vue面试题
165 64
|
1月前
|
JavaScript 前端开发
vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】
vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】
40 0
vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】
|
3月前
|
JavaScript 安全 前端开发
【Vue面试题二十九】、Vue项目中你是如何解决跨域的呢?
这篇文章介绍了Vue项目中解决跨域问题的方法,包括使用CORS设置HTTP头、通过Proxy代理服务器进行请求转发,以及在vue.config.js中配置代理对象的策略。
【Vue面试题二十九】、Vue项目中你是如何解决跨域的呢?
|
3月前
|
JavaScript 前端开发 编译器
【Vue面试题三十二】、vue3有了解过吗?能说说跟vue2的区别吗?
这篇文章介绍了Vue 3相对于Vue 2的改进和新增特性,包括性能提升、体积减小、更易维护、更好的TypeScript支持、新的Composition API、新增的Teleport和createRenderer功能,以及Vue 3中的非兼容性变更和API的移除或重命名。
【Vue面试题三十二】、vue3有了解过吗?能说说跟vue2的区别吗?
|
3月前
|
JavaScript 前端开发 API
【Vue面试题三十一】、你是怎么处理vue项目中的错误的?
这篇文章讨论了Vue项目中错误的处理方式,包括后端接口错误和代码逻辑错误的处理策略。文章详细介绍了如何使用axios的拦截器处理后端接口错误,以及Vue提供的全局错误处理函数`errorHandler`和生命周期钩子`errorCaptured`来处理代码中的逻辑错误。此外,还分析了Vue错误处理的源码,解释了`handleError`、`globalHandleError`、`invokeWithErrorHandling`和`logError`函数的作用和处理流程。
【Vue面试题三十一】、你是怎么处理vue项目中的错误的?

热门文章

最新文章