前端面试题

文章目录


React


一、什么是React?介绍一下优点及缺点。

React:是一个JavaScript库,用于构建高效、快速的用户界面。它遵循基于组件的方法,有助于构建可重用的UI组件,用于开发复杂和交互式的 Web(web端) 和移动(移动端) UI。
优点:

  1. react采用声明式编程,提高了应用性能和开发效率。
  2. 使用JSX,代码可读性很好。
  3. react可以与已有的库或者框架很好的配合。
  4. react的 componentWillUnmount 生命周期,能够清除相关的所有事件,避免内存泄露。
  5. 其单项数据流减少了重复的代码,轻松实现数据绑定。
  6. 并不直接对dom进行操作,引入了一个虚拟dom的概念,安插在js和真实dom中间,性能好,速度快。

缺点:

  1. react不适合单独做一个完整的框架,做大型项目需要和其他框架组合使用。
  2. 每次 state 更改,render 函数都要生成完整的虚拟 DOM, 哪怕 state 改动很小,render 函数也会完整计算一遍。如果 render 函数很复杂,这个过程就白白浪费了很多计算资源

二、React的设计思想

1. 组件化:
每个组件都符合开放-封闭原则,封闭是针对渲染工作流来说的,指的是组件内部的状态都由自身维护,只处理内部的渲染逻辑。开放是针对组件通信来说的,指的是不同组件可以通过props(单项数据流)进行数据交互。

2. 数据驱动视图: UI = f ( data),通过前面这个公式得出,如果要渲染界面,不应该直接操作DOM,而是通过修改数据(state或prop),数据驱动视图更新。
3. 虚拟dom:
由浏览器的渲染流水线可知,DOM操作是一个昂贵的操作,很耗性能,因此产生了虚拟DOM。虚拟DOM是对真实DOM的映射,React通过对比新旧虚拟DOM,得到需要更新的部分,实现dom的局部更新。

三、JSX是什么,它和JS有什么区别?

1. 在第一次发布react时,还引入了一种新的js方言jsx,将原始 HTML 模板嵌入到 JS 代码中。JSX 代码本身不能被浏览器读取,必须使用Babel和webpack等工具将其转换为传统的JS。
2. JSX 与 JS 的区别:
JS可以被打包工具直接编译,不需要额外转换,jsx需要通过babel编译,它是React.createElement的语法糖,使用jsx等价于React.createElement。
JSX 是 js 的语法扩展,允许在 html 中写 JS,JS 是原生写法,需要通过 script 标签引入

四、React 事件处理为什么要手动绑定 this

React 组件会被编译为 React.createElement ,在 createElement中,它的this丢失了,并不是由组件实例调用的,因此需要手动绑定 this 。

五、类组件和函数组件之间的区别是什么?

  1. 类组件可以使用其他特性,如状态和生命周期钩子,并且他有this。
  2. 函数组件只能接收props渲染到页面,无状态组件,没有this,不能使用生命周期钩子。
  3. 函数组件性能要高于类组件,因为类组件使用要实例化,而函数组件直接执行取返回结果即可,为了提高性能,尽量使用函数组件。

六、简述React的生命周期及其作用。

生命周期指的是组件实例从创建到销毁的流程,函数组件没有生命周期,只有类组件才有,因为只有class组件会创建组件实例。
组件的生命周期可以分为挂载、更新、卸载阶段:
挂载阶段: 由ReactDOM.render()触发—初次渲染

  1. constructor() 可以进行state和props的初始化。
  2. getDerivedStateFromProps 从更新后的props中获取State,它让组件在 props 发生改变时更新它自身的内部 state。
  3. render() (render函数)-----只能访问this.props和this.state,不允许修改状态和DOM输出
  4. componentDidMount() (组件挂载)-------成功render并渲染完成真实DOM之后触发,可以修改DOM

更新阶段: 由组件内部this.setState()或者父组件重新render触发或者forceUpdate()

  1. getDerivedStateFromProps 从更新后的props中获取State,它让组件在 props 发生改变时更新它自身的内部 state。
  2. ​shouldComponentUpdate() 能够减少render不必要的渲染。
  3. render() (render函数)-----只能访问this.props和this.state,不允许修改状态和DOM输出
  4. getSnapshotBeforeUpdate() 读取最新的 DOM 数据。
  5. componentDidUpdate() (组件更新)--------可以修改DOM

卸载阶段: 由ReactDOM.unmountComponentAtNode()触发

  1. componentWillUnmount() 在组件销毁之前调用,通常是用来做一些清除动作,比如移除事件监听、清除定时器等等。

七、React组件生命周期的阶段是什么?

组件的生命周期可分成三个状态:

  1. Mounting: 已载入真实 DOM。
  2. Updating: 正在被重新渲染。
  3. Unmounting: 已移除真实 DOM。

八、什么是props?并说明其作用和特点。

props是一个 JavaScript 对象,用于组件之间的通信,是一种数据传递的方式。
作用:

  • props用于接受组件外部的数据,通过标签属性从组件外向组件内传递变化的数据

特点:

  1. 可以给组件传递任意类型的数据。
  2. props是只读属性,值不可修改。
  3. 使用类组件时,如果写了构造函数,应该将props传递给super(),否则无法在构造函数中获取到props,其他的地方是可以获取到的。

九、props和state是什么?

  1. state是数据结构,只能使用setState来改变。
  2. props是组件的属性,由父组件传递给子组件,props是不可以改变的。
  3. state是局部的,除了它所在的这个组件其它组件都无法访问。

十、props和state的区别?

相同点:

  • 都是普通的js对象,他们包含着影响渲染输出的信息。

不同点:

  1. state的数据由当前组件管理,控制自己的状态,数据可改变。
  2. props是外部传入的数据参数,数据不可变。
  3. 没有state的叫做无状态组件,有state的叫有状态组件,建议多用props,少用state。

十一、什么是虚拟DOM?

虚拟DOM其实就是用一个原生的JS对象去描述一个DOM节点,实际上它只是对真实 DOM 的一层抽象。最终可以通过一系列操作使这棵树映射到真实环境上。 相当于在js与DOM之间做了一个缓存,利用patch(diff算法)对比新旧虚拟 DOM 的差异,记录到一个对象中按需更新, 最后创建真实DOM。

虚拟dom原理流程:
 模板 ==> 渲染函数 ==> 虚拟DOM ==> 真实DOM
 vuejs通过编译将模板(template)转成渲染函数(render),执行渲染函数可以得> 到一个虚拟节点树
 在对 Model 进行操作的时候,会触发对应 Dep 中的 Watcher 对象。Watcher 对象会调用对应的 update 来修改视图。
 
虚拟 DOM 的实现原理主要包括以下 3 部分:
用 JavaScript 对象模拟真实 DOM 树,对真实 DOM 进行抽象;
diff 算法- - -比较两棵虚拟 DOM 树的差异;
pach 算法 - - - 将两个虚拟 DOM 对象的差异应用到真正的 DOM 树。

十二、React中diff算法

作用:用来计算虚拟DOM中被改变部分,针对该部分进行原生DOM操作,不用重新渲染整个页面。

十三、React的工作原理以及阻止React的默认行为

  • 工作原理:React会创建一个虚拟的DOM。当一个组件的状态改变时,React首先会通过“diffing"算法来标记虚拟DOM中的改变,然后使用 diff 的结果来更新DOM。
  • 阻止React默认行为:e.preventDefault(),e是第三方提供的一个合成事件(注意:不能用return)

十四、调用setState之后发生了什么

setState会进行状态更新将传入的参数对象与组件当前状态合并,然后触发所谓的调和过程,经过调和过程,根据新的state,React元素会重新构建虚拟DOM,用 diff 算法对比新旧虚拟DOM树的区别,进行视图更新,而不是全部渲染。setState采用的任务队列机制,不会马上执行,而是加入队列,在下次事件循环时一次性执行。

十五、在构造函数中调用 super(props) 的目的是什么?

在super() 被调用之前,子类是不能使用 this 的,在 ES5 中,子类必须在 constructor 中调用 super(),才能使用this。传递 props 给 super() 的原因则是便于(在子类中)能在 constructor 访问 this.props。

十六、为什么浏览器无法读取JSX?

浏览器只能处理JS对象,而不能读取常规的JSX。为了使浏览器能够读取JSX,首先,需要像Babel这样的JSX转换器将JSX转换为JS对象,然后再传给浏览器。

十七、React中的状态是什么?它是如何使用的?

React中的状态是React 组件的核心,是数据的来源,必须尽可能简单。基本上状态是确定组件呈现行为的对象。与props不同,它们是可变的,并创建动态的和交互式的组件。
使用方法:可以通过this.state()访问它们。

十八、React中的合成事件是什么?

React中的合成事件是指:React模拟原生事件的所有功能的一个集合,即合成事件对象。

十九、react合成事件和原生事件有什么区别?

  1. 命名不同
    合成:驼峰命名。例:onClick。
    原生:非驼峰。例:onclick。
  2. 事件的值不同
    合成:合成事件值为函数。
    原生:原生事件的值为字符串。
  3. 阻止冒泡的方式不同
    合成:合成事件调用stop.preventDefault 方法。
    原生:原生事件使用 return false。

二十、受控组件和非受控组件

受控组件:通过 setState 的形式控制输入的值及更新 。
非受控组件:通过 dom 的形式更新值,使用 ref 的形式去获取值。

二十一、componentWillUpdate可以直接修改state的值吗?

不可以,会导致无限循环报错。在react中直接修改state,render函数不会重新执行渲染,应使用setState方法进行修改。

二十二、模仿vue中v-model指令,react实现类似双向绑定。

通过onChange事件监听input的value值,在通过this.setState改变显示出来。

二十三、React中什么是纯函数

即相同的输入,永远会得到相同的输出,而且没有任何观察的副作用。

二十四、setState是同步的还是异步的?

setState 并不是单纯同步的或异步的,它的表现会因调用场景的不同而不同。
异步:在合成事件 和 生命周期钩子(除componentDidUpdate) 中,setState是异步的。
同步:在原生事 和 setTimeout / setInterval中,setState是同步的。

二十五、react无状态组件和有状态组件的区别?

  1. 无状态组件是属于一个函数 ,它没有this, 也没有生命周期,他的动态数据都是通过父组件传递给子组件,再通过props接收渲染。
  2. 有状态组件属于一个class类,有this,有生命周期,可以通过this来接收状态和属性。

二十六、React中refs是什么?

React 中的 Refs提供了一种方式,允许我们访问 DOM节点或在 render方法中创建的 React元素。本质为ReactDOM.render()返回的组件实例,如果是渲染组件则返回的是组件实例,如果渲染dom则返回的是具体的dom节点。

二十七、React有什么特点 ?

  1. React使用虚拟DOM 而不是真正的DOM。
  2. React可以进行服务器端渲染。
  3. React遵循单向数据流或数据绑定。

二十八、列出React的一些主要优点。

  • React提高了应用的性能。
  • React可以方便地在客户端和服务器端使用。
  • React使用 JSX,代码的可读性很好。
  • React 很容易与 Meteor,Angular 等其他框架集成。
  • 使用React,编写UI测试用例变得非常容易

二十九、当调用setState时,React render 是如何工作的?

  • 虚拟DOM渲染:当render方法被调用时,它返回一个 新的组件 的虚拟 DOM 结构。当调用setState()时,render会被再次调用,因为默认情况下shouldComponentUpdate总是返回true,所以默认情况下React 是没有优化的。
  • 原生DOM渲染:React 只会在虚拟DOM中 修改真实DOM节点,而且修改的次数非常少——这是很棒的React特性,它优化了真实DOM的变化,使React变得更快。

三十、如何避免组件的重新渲染?

  1. React.memo():这可以防止不必要地重新渲染函数组件。
  2. PureComponent:这可以防止不必要地重新渲染类组件。
    注意: ------这两种方法都依赖于对传递给组件的props的浅比较,如果 props 没有改变,那么组件将不会重新渲染。浅比较会带来额外的性能损失,如果使用不当,这两种方法都会对性能产生负面影响。通过使用 React Profiler,可以在使用这些方法前后对性能进行测量,从而确保通过进行指定的更改来实际改进性能。

三十一、React 中 key 的重要性是什么?

key 用于识别唯一的 虚拟DOM 元素及其驱动 UI 的相应数据。它们通过回收 DOM 中 当前所有 的 元素 来帮助 React 优化渲染。这些key 必须是唯一的数字或字符串,React 只是重新排序元素而不是重新渲染它们。这可以提高应用程序的性能。

三十二、模块与组件、模块化与组件化的理解?

  • 模块:把同一功能的代码进行封装,形成独立的模块,可以独立运行,独立管理,每个模块有很多接口,可供调用。
  • 组件:把重复的代码提取出来合并成为一个个组件,组件最重要的就是可以复用。
  • 模块化:当应用的js都以模块来编写, 这个应用就是一个模块化的应用。
  • 组件化:当应用是以多组件的方式实现, 这个应用就是一个组件化的应用。

三十三、如何创建refs?

Refs 是使用 React.createRef() 创建的,并通过 ref 属性附加到 React 元素。在构造组件时,通常将 Refs 分配给实例属性,以便可以在整个组件中引用它们。

三十四、React性能优化方案

  1. 重写shouldComponentUpdate来避免不必要的dom操作。
  2. 使用production 版本的react.js。
  3. 使用key来帮助React识别列表中所有子组件的最小变化。

三十五、React怎么阻止事件冒泡?

  1. 阻止合成事件的冒泡用e.stopPropagation()。
  2. 阻止合成事件和最外层document事件冒泡,使用e.nativeEvent.stopImmediatePropogation()。
  3. 阻止合成事件和除了最外层document事件冒泡,通过判断e.target避免。

三十六、React组件通信方式有哪些?

  1. 父组件向子组件通信。
  2. 子组件向父组件通信。
  3. 兄弟组件通信。
  4. 父组件向后代组件通信。
  5. 无关组件通信。

三十七、useState 和 setState 有什么区别?

  1. useState 是一个函数,可以在函数组件中调用,而 setState 是一个方法,必须在类组件中调用。
  2. useState 返回一个数组,包含当前状态和一个更新状态的函数,而 setState 接受一个新状态并将其与当前状态合并。
  3. useState 中的状态可以是任何值,而 setState 中的状态必须是一个对象。

三十八、什么是useEffect?

useEffect 是 React Hooks 中用于在函数组件中添加副作用的 API。副作用指的 是 与组件渲染 无关的操作,比如数据获取、订阅、DOM 操作等。useEffect 会在组件渲染时执行一次,之后在每次组件重新渲染时执行。

三十九、shouldComponentUpdate是什么?

shouldComponentUpdate 是 React 中的一个生命周期方法,用于判断组件是否需要重新渲染(返回为true的时候渲染,否则不渲染)。

四十、shouldComponentUpdate是如何进行优化的?

在 shouldComponentUpdate 方法中进行 props 和 state 的浅比较,判断它们是否发生了变化。

四十一、PureComponent或React.memo是什么?

  • React.PureComponent 是 React 中的一个纯组件,它默认实现了shouldComponentUpdate 方法,可以帮助我们自动判断是否需要更新。React.PureComponent 内部会进行 props 和 state 的浅比较,从而避免不必要的组件更新。
  • React.memo类似于React.PureComponent,只不过用于函数组件而非class组件。

四十二、React路由实现原理。

react-router 的依赖库history:

  1. BrowserHistory:用于支持 HTML5 历史记录 API 的现代 Web 浏览器。
  2. HashHistory:用于旧版Web浏览器。
  3. MemoryHistory:用作参考实现,也可用于非 DOM 环境,如 React Native 或测试。

四十三、React如何做路由监听(也可以说是路由守卫)?

componentDidMount(){
	this.context.router.history.listen((route)=>{
		if(route.pathname==='/xxx'){
			console.log(1);
		}
	});
}

四十四、React中组件如何通信?

  1. 父组件向子组件传递: 父组件在调用子组件的时候,只需要在子组件标签内传递参数,子组件通过props属性就能接收父组件传递过来的参数。
  2. 子组件向父组件传递: 子组件向父组件通信的基本思路是 父组件向子组件传一个函数,然后通过这个函数的回调,拿到子组件传过来的值。
  3. 兄弟组件之间的通信: 兄弟组件之间的传递,是父组件 作为 中间层 来实现数据的互通,通过使用父组件传递。
  4. 父组件向后代组件传递: context提供了组件之间通讯的一种方式,可以共享数据,其他数据都能读取对应的数据 通过使用 React.createContext 创建一个context。
  5. 非关系组件传递: 如果组件之间关系类型比较复杂的情况,建议将数据进行一个全局资源管理,从而实现通信,例如redux。

四十五、说说你对Redux的理解?其工作原理?

理解: redux就是一个实现 集中管理的容器,遵循三大基本原则:

  1. 单一数据源。
  2. state 是只读的。
  3. 使用纯函数来执行修改。

工作原理: redux 要求我们把数据都放在 store 公共存储空间中,当一个组件改变了 store 里的数据内容,其他组件就能感知到 store 的变化,再来取数据,从而 间接 的 实现了这些数据传递的功能。

四十六、说说对Redux中间件的理解?常用的中间件有哪些?实现原理?

中间件: 中间件(Middleware)是介于 应用系统 和 系统软件 之间的一类软件,它使用 系统软件 所提供的基础服务(功能),衔接网络上 应用系统 的各个部分 或 不同的应用,能够达到资源共享、功能共享的目的。
常用的中间件:

  1. redux-thunk:用于异步操作。
  2. redux-logger:用于日志记录。

实现原理: Redux 中间件将会在 action被分发之后、到达 reducer之前执行,若有多个中间件,那么 Redux会结合它们被 “安装” 的先后顺序,依序调用这些中间件。

流程如下:action => middleware 1(中间件1)=> middleware 2(中间件2)=> dispatch => reducer => nextState

四十七、说说你对React Router的理解?常用的Router API 有哪些?

理解: React - router 和前端路由的原理大致相同,可以实现无刷新的条件下切换显示不同的路由页面。本质就是页面的URL发生改变时,页面的显示结果可以根据URL的变化而变化,但是页面不会刷新。因此,可以通过前端路由 实现单页面应用。
常用API:

  • BrowserRouter、HashRouter: BrowserRouter是history模式,HashRouter模式,使用两者作为最顶层组件包裹其他组件。
  • Route: Route用于路径的匹配,然后进行组件的渲染。
  • Link、NavLink: 通常路径的跳转是使用Link组件,最终会被渲染成a元素,其中属性to代替a标题的href属性。NavLink是在Link基础之上增加了一些样式属性,例如组件被选中时,发生样式变化
  • switch: 用于路由的重定向,当这个组件出现时,就会执行跳转到对应的to路径中。
  • redirect: swich组件的作用适用于当匹配到第一个组件的时候,后面的组件就不应该继续匹配。

四十八、说说React Router有几种模式?实现原理?

两种:
  BrowserRouter、HashRouter,这两个组件的使用都十分的简单,作为最顶层组件包裹其他组件。
实现原理:

  1. HashRouter包裹了整应用,通过 window.addEventListener 监听 hash 值的变化,并传递给其嵌套的组件,然后通过 context 将 location 数据往后代组件传递。
  2. Router组件主要做的是通过 BrowserRouter 传 过来的 当前值,通过 props 传 进来的 path 与 context 传进来的 pathname 进行匹配,然后决定是否执行渲染组件。

四十九、说说对React Hooks的理解?解决了什么问题?

理解:
  hooks的出现,使函数组件的功能得到了扩充,拥有了类组件相似的功能,在我们日常使用中,使用hooks能够解决大多数问题,并且还拥有代码 复用 机制,因此优先考虑hooks。

hooks能够更容易解决状态相关的重用的问题:
  每调用 useHook一次 都会生成一份独立的状态,通过自定义hook能够更好的封装我们的功能,编写hooks为函数式编程,每个功能都包裹在函数中,整体风格更清爽,更优雅。

至于为什么引入hook,官方给出的动机是解决长时间使用和维护react过程中常遇到的问题,例如:
  难以重用和共享组件中的与状态相关的逻辑,逻辑复杂的组件难以开发与维护,当我们的组件需要处理多个互不相关的 local state 时,每个生命周期函数中可能会包含着各种互不相关的逻辑在里面,类组件中的this增加学习成本,类组件在基于现有工具的优化上存在些许问题。由于业务变动,函数组件不得不改为类组件等等。在以前,函数组件也被称为无状态的组件,只负责渲染的一些工作。因此,现在的函数组件也可以是有状态的组件,内部也可以维护自身的状态以及做一些逻辑方面的处理。

五十、说说 Real DOM(真实dom) 和 Virtual DOM(虚拟dom) 的区别?优缺点?

真实 DOM:
优点:

  1. 易用。

缺点:

  1. 效率低,解析速度慢,内存占用量过高。
  2. 性能差:频繁操作真实 DOM,容易导致回流与重绘。

虚拟 DOM:
优点:

  1. 简单方便。
  2. 使用 Virtual DOM,能够有效避免真实 DOM 树 的频繁更新,能够提高性能。
  3. React 借助虚拟 DOM,带来了跨平台的能力,一套代码多端运行。

缺点:
  首次渲染大量 DOM 时,由于多了一层虚拟 DOM 的计算,运行速度比正常稍慢。


Vue2-Vue3


一、什么是vue?vue的优缺点?vue的核心?vue的特性?vue的使用场景?

  1. 什么是Vue?:Vue是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,并且还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
  2. 优点:渐进式、组件化、轻量级、虚拟dom、响应式、单页面路由、视图与数据分开。
    缺点:单页面不利于seo,不支持IE8以下,首屏加载时间长。
  3. 核心: 数据驱动与组件化。
  4. 特性:数据驱动视图与双向数据绑定。
  5. 使用场景:单页面应用程序,移动端。

二、什么是vue框架?

  • Vue是一种用于构建 用户界面 的JS框架,它基于Html,css 和 js 构建,并提供了一套 声明式 的 编译模型 ,帮助高效的开发 用户界面。

三、什么是单向数据绑定?什么是双向数据绑定?他们的区别是什么?

  1. v-bind是 单项数据绑定,v-model是 双向数据绑定。
  2. 区别: 单项数据绑定 是通过v-bind把 数据 传递 给其他 需要 使用的组件,然后渲染到 视图 上。 双向 数据绑定 是通过v-model对表单里的 属性 进行绑定,且会自动响应某些变化,视图变数据变,数据变视图变。

四、写一下对MVVM思想的理解?

Model(模型):负责从 数据库 中取数据。View(视图):负责 展示 数据 的地方。VM:也就是View-Model,也是MVVM的核心。
VM它做了两件事达到了数据的双向绑定效果:
  一是将【模型】转化成【视图】,即将 后端 传递的 数据 转化成所看到的页面,实现的方式是:数据绑定。
  二是将【视图】转化成【模型】,即将所看到的页面转化成 后端 的 数据,实现的方式是:DOM 事件监听。
MVVM的设计思想:
  实现了 View 和 Model 的自动同步,也就是当 Model 的属性改变时,我们不用再自己手动操作 Dom 元素,来改变 View 的显示,而是改变属性后 该属性对应的 View 层 也会自动改变。

五、什么是 vue 生命周期?vue 生命周期有几个阶段?第一次页面加载会触发哪几个钩子?

vue生命周期就是一个 vue 实例从创建到销毁的过程。

  • 它可以总共分为 8 个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后

创建阶段:

  1. beforeCreate:实例已经初始化,但不能获取DOM节点。
  2. created:实例已经创建,仍然不能获取DOM节点。

挂载阶段:

  1. beforeMount:模板编译完成,但还没挂载到界面上。
  2. mounted:编译好的模板已挂载到页面中。

更新阶段:

  1. beforeUpdate:数据发生变化立即调用,此时data中数据是最新的,但页面上数据仍然是旧的。
  2. updated:更新结束后执行,此时data中的值和页面上的值都是最新的。

销毁阶段:

  1. beforeDestroy:当要销毁 vue 实例之前执行。
  2. destroyed:在销毁 vue 实例 时 执行。
  3. actived: 在keep-alive中使用,缓存组件激活。
  4. deactived: 在keep-alive中使用,缓存组件不激活。

第一次页面加载会触发4 个钩子,分别是:beforeCreate、created、beforeMount、mounted。

六、在vue开发时,改变数组或者对象的数据,什么情况页面视图没有更新?如何解决?

对于数组,Vue 不能检测以下数组的变动:

  1. 当你利用索引直接设置一个数组项时,例如:vm.items [ indexOfItem ] = newValue
  2. 当你修改数组的长度时,例如:vm.items.length = newLength

对于对象:

  1. Vue 不能检测到给已有对象添加的新属性:例如:vm.obj.age = 18

解决方案:

对于数组:可以使用 Vue.set() 或者 vm.$set()或者splice。例如:
	vue.set(vm.items, indexOfItem, newValue)
	vm.$set(vm.items, indexOfItem, newValue)
	vm.items.splice(indexOfItem, 1, newValue)
对于对象:可以使用Vue.set() 或者 vm.$set()或者Object.assign()。例如:
	1、你可以添加一个新的 age 属性到嵌套的 userProfile 对象:
		Vue.set(vm.userProfile, 'age', 27)
	2、你还可以使用 vm.$set 实例方法,它只是全局 Vue.set 的别名:
		vm.$set(vm.userProfile, 'age', 27)
	3)有时你可能需要为已有对象赋予多个新属性,比如使用
		Object.assign() 或 _.extend()。
		在这种情况下,你应该用两个对象的属性创建一个新的对象。
		vm.userProfile = Object.assign({}, vm.userProfile, {
			age: 27,
 			favoriteColor: 'Vue Green'
		})

七、在vue组件中,data为什么是一个返回对象的函数?

如果data是对象的话,由于对象是引用类型,组件被复用的话,就会创建多个实例。本质上,这些实例用的都是同一个构造函数。这样就会影响到所有的实例,为了保证组件不同 的 实例 之间data不冲突,所以data必须是一个函数。

八、Vue中创建的指令有哪些,分别有什么作用(至少写出10个)

  1. v-model ————多用于表单元素实现双向数据绑定。
  2. v - for —————遍历数组或 json。
  3. v - show ————显示隐藏内容,值为true或false。
  4. v - hide—————隐藏内容。
  5. v - if ——————显示与隐藏,创建或销毁组件,值为true或false。
  6. v - else - if ——— 必须和 v-if 连用。
  7. v - else—————必须和 v-if 连用 不能单独使用 否则报错 模板编译错误。
  8. v - bind—————动态绑定 作用: 及时对页面的数据进行更改。
  9. v-on:click————给标签绑定事件监听函数,可以缩写为@,绑定一个点击函数,函数必须写在 methods 里。
  10. v - text —————解析文本(纯文本)。
  11. v - html—————解析文本(可以解析html标签)。
  12. v - once ———— 进入页面时 只渲染一次 不在进行渲染。
  13. v-cloak—————防止页面闪烁。
  14. v-pre——————把标签内部的元素原位输出。

九、v-if与v-show的区别是什么?

  1. v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
  2. v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
  3. v-show不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
  4. 一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。如果非常频繁地切换,使用 v-show 较好;切换不频繁,使用 v-if 较好。

十、computed和watch的区别是什么?

  1. computed擅长处理的场景:一个数据受多个数据影响;watch擅长处理的场景:一个数据影响多个数据。
  2. 功能上:computed是计算属性,watch是监听一个值的变化,然后执行对应的回调。
  3. 是否调用缓存:computed支持缓存,只有依赖数据发生改变,才会重新进行计算;而watch不支持缓存,数据变,直接会触发相应的操作。
  4. 是否调用return:computed中的函数必须要用return返回,watch中的函数不是必须要用return。
  5. computed不支持异步 ,当computed内有异步操作时无效,无法监听数据的变化;而watch支持异步。
  6. computed默认第一次加载的时候就开始监听;watch默认第一次加载不做监听,如果需要第一次加载做监听,添加immediate属性,设置为true(immediate:true)。

十一、组件之间通信的方式有哪些,是如何通信的?

  1. 父传子 通过 在父组件中 绑定自定义属性,在子组件 通过 props 接收。
  2. 子改父 或者 子传父,在父组件中通过 自定义事件 传递方法,在子组件中通过$emit接收。
 	<children @eventChange = "change"> < / children >
 	this.$emit("eventChange",100)
  1. 兄弟之间通信 通过一个事件总线(eventBus 其实是一个空实例),在A组件中通过$on绑定自定义事件,在B组件中通过$emit接收数据。
  2. 通过$parent /$children/$refs通信,$parent指的是父组件实例 $children/$refs是子组件实例。
  3. $attrs & $listeners通信,$attrs获取父组件中不被 props 接收的自定义属性,并且可以通过 v-bind=“$attrs” 传入内部组件,$listeners获取父组件中的自定义事件。
  4. provide & inject 祖先和后代之间的通信,Provide的值可以是对象或者是返回对象的函数,inject用来就收provide传递的参数。

十二、Vue的v-model双向绑定原理是什么?

双向绑定原理:
  v-model本质就是一个语法糖,可以看成是value + input方法的语法糖。 可以通过 model 属性的 prop 和 event 属性来进行自定义。原生的 v-model,会根据标签的不同生成不同的事件和属性,text 和 textarea 元素使用 value 属性和 input 事件,checkbox 和 radio 使用 checked 属性和 change 事件,select 字段将 value 作为 prop 并将 change 作为事件。
可以将v-model进行如下改写:
<input v-model = "sth" /> 等于 <input :value="sth" @input="sth = $event.target.value" />
这个语法糖必须是固定的,也就是说属性必须为value,方法名必须为:input。

十三、写出对promise的理解?

  1. Promise是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理和更强大。所谓promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。Promise主要用来解决回调地狱的问题,可以有效的减少回调嵌套。真正解决需要配合 async / await 。
  2. 通俗讲,Promise是一个许诺、承诺,是对未来事情的承诺,承诺不一定能完成,但是无论是否能完成都会有一个结果:
    ① Pending 正在做
    ② Resolved 完成这个承诺
    ③ Rejected 这个承诺没有完成,失败了。

十四、Vue是如何实现双向绑定的原理?

vue实现 数据双向绑定 主要是:采用 数据劫持 结合发布者-订阅者模式 的方式,通过 Object.defineProperty() 来劫持各个属性的 setter,getter,在数据 变动 时 发布 消息给 订阅者,触发相应 监听回调。当把一个普通 Javascript 对象传给 Vue实例来作为它的 data 选项时,Vue将遍历它的属性,用 Object.defineProperty() 将它们转为 getter / setter。用户看不到 getter / setter,但是在内部 它们让 Vue 追踪依赖,在 属性 被 访问 和 修改 时 通知 变化。

十五、vuex的有哪些属性?用处是什么?

State: vuex的基本数据,用来存储变量。
Getter: 从基本数据(state)派生的数据,相当于state的计算属性。
Mutation: 处理state里面定义的数据,只能通过mutation来实现变更,不能异步处理。
Action: 用于提交 mutation,间接改变数据,可以异步操作。
Module: 将 Store 拆分为多个 模块, 且同时保存在单一的状态树中。

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

当我们监听一个基本数据类型时可以使用简写形式:

watch: {
    value () {
    // do something
    }
}

当我们监听一个引用数据类型时需要写成对象形式:

watch: {
    obj: {
       handler () {  执行回调
           // do something
       },
       deep: true,  是否进行深度监听
       immediate: true  是否初始执行handler函数
    }
}

十七、写出vue插槽有哪些,如何使用?

插槽就是子组件中的提供给父组件使用的一个占位符,用< slot >< / slot > 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的< slot >< / slot >标签。通俗的说是:slot 是在父组建控制了子组件显示或隐藏相关内容。
插槽又分为三种:普通插槽、具命插槽、作用域插槽

  1. 匿名插槽 : 父组件传递 一个html结构 给子组件
    (1)子组件: < slot > 插槽默认内容 < / slot >
    (2)父组件: <子组件> html结构 </子组件>
  2. 具名插槽 : 父组件传递 多个html结构 给子组件。
    (1)子组件: 给插槽添加一个name(插槽名)   
      < slot name=“插槽名” > 插槽默认内容 < / slot >
    (2)父组件: 使用 v-slot:插槽名 或 #插槽名  
      <子组件>
        < template v-slot : 插槽名 >
          html结构    
         < /template >
      < / 子组件 >
  3. 作用域插槽: 子组件传递 数据 给父组件插槽
    (1)子组件 : 给< slot >内置组件添加自定义属性
    < slot 属性名 = “属性值” > 插槽默认内容 < / slot >
    (2)父组件 : 使用 v-slot = “对象名”

十八、写出nextTick的作用,以及用法。

作用: 获取数据更新之后的dom元素。
用法: 将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。

new Vue({
  methods: {
    example: function () {
      // 修改数据
      this.message = 'changed'
      // DOM 还没有更新
      this.$nextTick(function () {
        // DOM 现在更新了
        // `this` 绑定到当前实例
        this.doSomethingElse()
      })
    }
  }
})

十九、在使用v-for时,为什么需要使用key?

  1. key的作用主要是为了高效的更新虛拟DOM,其原理是vue在patch(补丁)过程中通过key可以精准判断两个节点是否是同一个,从而避免频繁更新不同元素,使得整个patch过程更加高效,减少DOM操作量,提高性能。
  2. 另外,若不设置key还可能在列表更新时引发一些隐蔽的bug。如某行数据不该更新的却更新了。
  3. vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果。

二十、自定义一个指令,实现v-show指令的功能。

<p v-showw = "boo">显示/隐藏</p>
Vue.directive('showw',{
	bind(el,binding){
		el.style.display = binding.value? 'block':'none'
	},
	update(el,binding){
		el.style.display = binding.value? 'block':'none'
	},
})

二十一、单页面应用和多页面应用的区别及优缺点。

区别:

  1. 组成: 单页面由一个主页面和多个页面片段组成,多页面由多个主页面组成。
  2. 刷新方式: 单页面是局部刷新,多页面是整页刷新。
  3. url 模式: 单页面是hash模式,多页面是history。
  4. seo搜索引擎优化: 单页面很难实现,可使用SSR方式改善,多页面应用容易实现。
  5. 数据传递: 单页面传递容易,多页面通过url、cookie、loaclStorage等传递。
  6. 页面切换: 单页面速度快、用户体验好,多页面切换加载资源 速度慢、用户体验差。
  7. 维护成本: 单页面维护容易,成本低。多页面相对复杂,不好维护。

优点:

  1. 具有桌面的应用的即时性、网站的可移植性和可访问性。
  2. 用户体验好、快,内容的改变不需要重新加载整个页面。
  3. 良好的前后端分离,分工更明确。
    缺点:
  4. 不利于搜索引擎的抓取。
  5. 首次渲染速度相对较慢。

二十二、< keep-alive >< / keep-alive >的作用是什么?什么场景使用?

Keep-alive 是 Vue.js 内置的一个抽象组件,用于缓存有状态组件,可以在组件切换时保留组件的状态避免重新渲染。它有以下两个作用:

  1. 缓存有状态的组件,避免组件在切换时被重新渲染;
  2. 在缓存的组件被激活时触发 activated 钩子函数,在缓存的组件被停用时触发 deactivated 钩子函数。

使用 Keep-alive 可以提高组件的性能,尤其是在组件状态比较复杂或需要较长时间计算的情况下,通过缓存组件避免重复渲染,提高应用的性能。

二十三、写出你对vue的mixin的理解,有什么应用场景?

理解:
mixin(混入),提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。 本质其实就是一个js对象,它可以包含我们组件中任意功能选项,如 data、components、methods、created、computed 等等。
我们只要将共用的功能以对象的方式传入 mixins选项中,当组件使用 mixins 对象时所有mixins对象的选项都将被混入该组件本身的选项中来,在Vue中我们可以局部混入跟全局混入。
使用场景:
在日常的开发中,我们经常会遇到在不同的组件中经常会需要用到一些相同或者相似的代码,这些代码的功能相对独立。这时,可以通过Vue的mixin功能将相同或者相似的代码提出来。

二十四、写出vue路由中的导航守卫以及导航守卫回调函数中三个参数的作用。

全局守卫:

  1. beforeEach全局前置守卫
  2. afterEach全局后置钩子

局部守卫:

  1. beforeRouteEnter:因为当守卫执行前,组件实例还没被创建,不能获取组件实例的this。
  2. beforeRouteUpdate:在当前路由改变,但是该组件被复用时调用,可以访问组件实例 this。
  3. beforeRouteLeave:导航离开该组件的对应路由时调用,可以访问组件实例 this。

每个守卫方法接收三个参数:

  1. to:目标路由对象
  2. from:准备要离开的路由
  3. next():进行管道中的下一个钩子。可传递参数有布尔值false,直接写路径’/‘或{path:’/'},回调函数。

注意:后置钩子函数afterEach不会接受next函数也不会改变导航本身。

二十五、写出$ route与$ router的区别。

$route是 “ 路由信息对象 ”,包括 path,params,hash,query,fullPath,matched,name 等路由信息参数。
而 $router是 “ 路由实例 ” 对象包括了路由的跳转方法,钩子函数等。

二十六、vue-router路由传参有哪些方法,如何获取路由参数。

params 方法传参的时候,要在路由后⾯加参数名占位;并且传参的时候,参数名要跟路由后⾯设置的参数名对应。
/user/:id这个路由匹配 /user/111, /user/222 这⾥的 id 就是 params。
query⽅法,就没有这种限制,直接在跳转⾥⾯⽤就可以。

区别:

  1. query 传参配置的是 path,而 params 传参配置的是name,且在 params 中配置 path 无效。
  2. query传递的参数会显示在地址栏中,而params传参不会。
  3. query传参刷新页面数据不会消失,而params传参刷新页面数据回消失。
  4. params 可以使用动态传参,动态传参的数据会显示在地址栏中,且刷新页面不会消失,因此可以使用动态params传参,根据动态传递参数在传递页面获取数据,以防页面刷新数据消失。

二十七、vuex是什么?怎么使用?哪种功能场景使用它?

vuex 就是一个仓库,仓库里放了很多对象。
其中 state 存放的是数据状态,不可以直接修改里面的数据。
getters类似vue的计算属性,主要用来过滤一些数据。
mutations 存放的是动态修改Vuex的state中保存的数据状态的方法。
actions 保存的触发mutations中方法的方法,可以理解为通过将 mutations 里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据。
怎么使用: 在main.js引入store,注入。新建了一个目录store,…export 。
使用场景: 单页应用中,组件 之间的状态、音乐播放、登录状态、加入购物车。

二十八、vue中hash模式和history模式的区别?

区别:

  1. hash模式是依靠onhashchange事件( 监听 location.hash 的改变 )
  2. history模式是主要是依靠的HTML5 history中新增的两个方法,pushState()可以改变url地址且不会发送请求,replaceState()可以读取历史记录栈,还可以对浏览器记录进行修改。
  3. 当真正需要通过URL向后端发送HTTP请求的时候,比如常见的用户手动输入URL后回车,或者是刷新(重启)浏览器,这时候history模式需要后端的支持。因为history模式下,前端的URL必须和实际向后端发送请求的URL一致,例如有一个URL是带有路径path的(例如www.libai.wang/blogs/id),如果后端没有对这个路径做处理的话,就会返回404错误。所以需要后端增加一个覆盖所有情况的候选资源,一般会配合前端给出的一个404页面。

二十九、写出对路由懒加载的理解并写出它的用法

当打包构建应用时,JavaScript
包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就会更加高效。
Vue Router 支持开箱即用的动态导入,这意味着你可以用动态导入代替静态导入:
将 import UserDetails from ’ . / views / UserDetails . vue ’ 替换成
const UserDetails = () => import(’ . / views / UserDetails.vue ’ )
const router = createRouter ( {
 routes: [ { path: ’ / users / : id ', component: UserDetails } ],
})

三十、Vue2和vue3的响应式原理分别是什么,以及vue3为什么要更改实现响应式原理的方式?

Vue2中使用的响应式原理是通过Object.defineProperty方法对数据进行劫持监听,从而实现数据的响应式更新。
而Vue3中使用的响应式原理是基于ES6的Proxy实现的,通过Proxy对象代理数据,可以实现更高效的数据监听和更新,同时也可以监听到数组的变化。

三十一、写一下setup函数的作用。

setup函数是Vue3中引入的新特性,它是组件的一个选项,用于在组件初始化过程中执行一些逻辑操作。setup函数可以返回一个对象,该对象中包含组件中使用的响应式数据、方法等内容,可以通过解构赋值获取其中的内容。

三十二、Vue 3.x所采用的Composition Api 与Vue 2.x使用的Options Api 有什么区别?

Vue 2.x使用的 Options API是通过一个包含组件选项的对象来创建组件,包括 data、methods、computed、watch 等选项。
Vue 3.x采用的Composition API是通过函数的方式来组织组件的代码,可以将一个组件的相关逻辑组织在一起,提高代码的可读性和可维护性。

三十三、Vue 3.x中pinia有哪些核心属性以及在组件的使用?

pinia是Vue3中的状态管理库,具有以下核心属性:
$state:一个ref对象,用于存储状态数据。
$getters:一个包含所有状态的getter函数的对象。
$actions:一个包含所有操作状态的action函数的对象。
在组件中使用pinia,需要通过useStore方法来获取一个与组件相关联的状态管理对象。

三十四、Vue 3.x中生命周期函数相比Vue 2.x 有变化。

Vue 3.x中的生命周期函数相比Vue 2.x发生了一些变化:
beforeCreate 和 created 已经合并成一个新的函数 setup。
deactivated 和 activated 已经被废弃,取而代之的是 beforeMount 和 beforeUpdate。因为在Vue3中,keep-alive组件被完全重写了,其默认行为现在与没有keep-alive一样。

三十五、写出Vue3中watch与watchEffect的区别。

Vue3中的watch和watchEffect都用于监听数据的变化,但是它们之间有以下区别:
watch需要显式地监听数据变化,并且需要指定回调函数。在回调函数中可以处理数据变化的逻辑,也可以手动处理数据,因此灵活性更高。watch可以监听多个数据。
watchEffect则可以自动监听函数内部的响应式数据的变化,只要其内部引用的响应式数据发生变化,回调函数就会被调用。watchEffect不需要显式地声明监听哪些数据,因此代码更简洁,但也意味着它无法监听特定的数据。

三十六、说一下对vue3的理解以及新特性有哪些?

  1. vue2与vue3双向绑定数据的原理不同: vue2 双向数据绑定采用了es5 中 Object.defineProperty() 对数据进行了劫持,结合发布订阅模式实现。 vue3 采用了es6 中的 proxy 代理对象的方式进行数据交互,相较 vue2 来说大大的提高了效率。

  2. 是否支持碎片: vue2 不支持碎片。 vue3 支持碎片,支持多个根节点。

  3. API 类型不同:
    vue2:vue2使用选项类型api,选项型api在代码里分割了不同的属性:data,computed,methods等。
    vue3:vue3使用组合式api,新的合成型api能让我们使用方法来分割,相比于旧的api使用属性来分组,这样代码会更加简便和整洁。

  4. 定义数据变量和方法不同:
    vue2是把数据放入data中,在vue2中定义数据变量是data(){},创建的方法要在methods:{}中。
    vue3就需要使用一个新的setup()方法,此方法在组件初始化构造的时候触发。使用以下三个步骤来建立反应性数据:
    从vue引入reactive;使用reactive() 方法来声明数据为响应性数据;使用setup()方法来返回我们的响应性数据,从而template可以获取这些响应性数据。

  5. 生命周期钩子函数不同:
    vue2中的生命周期:beforeCreate 组件创建之前、created 组件创建之后、beforeMount 组价挂载到页面之前执行、mounted 组件挂载到页面之后执行、beforeUpdate 组件更新之前、updated 组件更新之后、beforeDestroy 组件销毁之前、destroy组件销毁之后。
    vue3中的生命周期:setup 开始创建组件前、onBeforeMount 组价挂载到页面之前执行、onMounted 组件挂载到页面之后执行、onBeforeUpdate 组件更新之前、onUpdated 组件更新之后

  6. 父子传参不同:
    vue2:父传子,用props,子传父用事件 Emitting Events。在vue2中,会调用this$emit然后传入事件名和对象。
    vue3:父传子,用props,子传父用事件 Emitting Events。在vue3中的setup()中的第二个参数content对象中就有emit,那么我们只要在setup()接收第二个参数中使用分解对象法取出emit就可以在setup方法中随意使用了。

  7. 指令与插槽不同:
    vue2:vue2中使用slot可以直接使用slot;v-for与v-if在vue2中优先级高的是v-for指令,而且不建议一起使用。
    vue3:vue3中必须使用v-slot的形式;vue3中v-for与v-if,只会把当前v-if当做v-for中的一个判断语句,不会相互冲突;vue3中移除keyCode作为v-on的修饰符,当然也不支持config.keyCodes;vue3中移除v-on.native修饰符;vue3中移除过滤器filter。

  8. main.js文件不同:
    vue2:vue2中我们可以使用pototype(原型)的形式去进行操作,引入的是构造函数。
    vue3:vue3中需要使用结构的形式进行操作,引入的是工厂函数;vue3中app组件中可以没有根标签。

三十七、vue3新增的响应式相关的函数。

关键词: ref,reactive,readonly,computed,watch,watchEffect

三十八、ref的理解

  1. 功能:接受一个内部值,返回一个响应式的、可更改的 ref 对象,ref对象只有一个属性:value。
  2. 使用ref对象:模板上不需要写 .value 属性(会自动解构),在js中,使用 .value 来完成数据的读写。
  3. ref 接收基本类型和引用类型,ref 可以接收基本类型。当接收的值为引用类型是,会自动将一个 ref 对象转为 proxy 对象。

三十九、reactive的理解:

  1. 功能:接收普通对象数据,返回一个响应式代理对象,这个普通对象可以是多个数据。
  2. 使用:操作属性时,可以直接使用,不需要通过.value获取。
  3. a. 响应式转换是“深层的”会影响对象内部多有嵌套的属性。
    b. 通过代理对象,源对象的内部数据也是响应式的

四十、readonly

  1. 功能:接受一个对象 (不论是响应式还是普通的) 或是一个 ref,返回一个原值的只读代理。
  2. 只读代理是深层的:对任何嵌套属性的访问都将是只读的。它的 ref 解包行为与 reactive() 相同,但解包得到的值是只读的。

四十一、computed

功能:computed是计算属性。和选项式api中的计算属性实现的功能一样。
参数: 可以接受一个 getter 函数,返回一个只读的响应式 ref 对象。该 ref 通过 .value 暴露 getter 函数的返回值。也可以接受一个带有 get 和 set 函数的对象来创建一个可写的 ref 对象。

四十二、watch和watchEffect的区别。

Watch与watchEffect相比,watch是懒执行的。
而watchEffect在首次加载就会执行,watch可以明确知道由哪个依赖引起的侦听,watchEffect不明确,wacth可以访问当前值和初始值,watchEffect则不可以。

四十三、reactive与ref的区别:

  1. Ref用来定义基本数据类型,reactive用来定义引用数据类型,ref也可以定义引用数据类型,内部会自动通过reactive转为代理对象。
  2. ref通过object.defineProperty的get与set来实现响应式,reactive通过使用Proxy来实现响应式,并通过Reflect操作源对象内部的数据。
  3. ref定义的数据操作时需要 .value ,读取时模板中直接读取不需要 .value,Reactive定义的数据操作数据与读取数据都不需要 .value。

四十四、Vue 如何获取到 dom 节点 ?

  1. 事件源
  2. Ref
  3. 自定义全局指令
  4. Vue组件在patch阶段结束时会把this. $ el赋值为挂载的根 dom 元素,我们可以直接使用 $el 的 querySelector, querySelectorAll 等方法获取匹配的元素。

四十五、vuex中有哪些属性(5个)?请说明各属性的特性和作用?

  1. state:状态管理对象,用来存储变量。
  2. getters: 包含多个计算属性方法的对象。
  3. mutations:包含多个直接修改数据状态方法的对象。
  4. actions:包含多个异步方法与间接修改数据状态方法的对象。
  5. modules:模块化vuex,可以让每一个模块拥有自己的 state、mutation、action、 getters 。

四十六、路由如何实现懒加载?

在 定义当前组件路由路径的下面加入: component:() =>import (“组件路径”)。

四十七、vue2和vue3的响应式原理的区别?

Vue2:v2的响应式原理是通过object.defineProperty实现的,通过对 对象属性的读取、修改或对数组的方法 进行拦截(数据劫持),但是存在问题,新增、添加属性 以及 直接通过下标修改数组,界面不会自动更新。
Vue3:v3的响应式原理: 通过Proxy(代理),拦截对象中任意属性的变化,包括:属性值的读写、属性的添加、属性的删除等。 再通过Reflect(反射):对源对象的属性进行操作。

四十八、setup 是什么?作用?执行时机?返回值?

Setup是什么,作用?
setup是一个新的选项,所有的组合API函数都再次使用,只在初始化时执行一次。 Setup如果返回对象,对象中的属性与方法,在模板中可以直接使用 。
执行时机:
1、 在beforeCreate之前执行一次,此时组件对象还没有创建。
2、 This的值是undefined,不能通过this操作data、computed、methods、props。
3、 所有的composition api都不能使用this。

返回值 :

  1. 一般都返回一个对象,用于向模板返回数据,返回的数据模板可以直接使用。
  2. 返回的对象的属性与data返回的数据在组件对象中属性合并 。
  3. 返回的对象的方法与methods返回的数据在组件对象中方法合并。
  4. 切结:
  • ① 如遇相同名字setup优先。
  • ② Methods可以访问setup中属性与方法,setup不可以访问data与methods,不推荐使用。
  • ③ Setup不能是一个异步函数,如果是异步函数返回的是promise,模板不能获取到return返回的对象。

四十九、选项式API和组合式API的区别?

  1. 在逻辑组织和逻辑复用方面,组合式API是优于选项式API的
  2. 因为组合式API几乎都是函数,会有更好的类型推断
  3. 组合式API对tree-shaking友好,代码也更容易压缩
  4. 组合式API中见不到this的使用,减少了this指向不明的情况
  5. 如果是小型组件,可以继续使用选项式API,也是十分友好的

五十、Hash和history的区别?

  1. hash模式带#号比较丑,history模式比较优雅
  2. pushState设置的新的URL可以是与当前URL同源的任意URL,而hash直接修改#后面的部分,故只可设置与当前同文档的URL
  3. pushState设置的新URL可以与当前URL一模一样,这样也会把记录添加到栈中,而hash设置的新值必须与原来不一样才会触发记录添加到栈中。
  4. pushState通过stateObject可以添加任意类型的数据到记录中,而hash只可添加短字符串
  5. pushState可额外设置title属性供后续使用
  6. hash兼容ie8以上,history兼容ie10以上
  7. history模式需要后端配合将所有访问都指向index.html ,否则用户刷新页面,会导致404错误。

五十一、pinia和vuex的区别?

  1. pinia没有mutations,只有state,getters,actions
  2. pinia分模块时不需要modules (之前vuex分模块时需要modules)
  3. pinia体积更小(性能更好)
  4. pinia可以直接修改state数据

五十二、vue3.中pinia有哪些核心属性以及在组件中的使用

pinia是Vue3中的状态管理库,具有以下核心属性:
$state:一个ref对象,用于存储状态数据。
$getters:一个包含所有状态的getter函数的对象。
$actions:一个包含所有操作状态的action函数的对象。
在组件中使用pinia,需要通过useStore方法来获取一个与组件相关联的状态管理对象。

五十三、query和params的区别?

Query:

  1. 是拼接在url后面的参数。
  2. 参数在?后面,且参数之间用&符分隔
  3. query相当于get请求,可以在地址栏看到参数

Params:

  1. 是路由的一部分。以对象的形式传递参数
  2. 使用params传参只能由name引入路由,如果写成path页面会显示警告,说参数会被忽略
  3. params相当于post请求,参数不会再地址栏中显示

五十四、route与router的区别?

$route:获取路由信息 指当前路由实例跳转到的路由对象。
router: 获取路由整个实例指整个路由实例,可操控整个路由通过‘router.push’往其中添加任意的路由对象 钩子函数等。

route对象包括:

$route.path 字符串,等于当前路由对象的路径,会被解析为绝对路径,如/home/news 。
$route.name 当前路由的名字,如果没有使用具体路径,则名字为空。
$route.router 路由规则所属的路由器。
$route.matchd 数组,包含当前匹配的路径中所包含的所有片段对象的配置参数对象。 > $route.query 对象,包含路由中查询参数的键值对。会拼接到路由 url 后面。
$route.params 对象,含路有种的动态片段和全匹配片段的键值对,不会拼接到路由的url 后面。

五十五、Vue3带来了什么改变?

  1. 性能的提升 打包大小减少41%,初次渲染快55%, 更新渲染快133%,内存减少54%
  2. 源码的升级 使用Proxy代替defineProperty实现响应式,重写虚拟DOM的实现
  3. Vue3可以更好的支持TypeScript,新的特性-Composition API(组合API)

五十六、provide和inject的使用(v3)

作用: 实现祖与后代组件之间通信。
套路: 父组件有一个 provide 选项来提供数据,后代组件有一个 inject 选项来开始使用这些数据。

五十七、vue3 中的hooks?

hook本质是一个函数,把setup函数中使用的Composition API进行了封装。类似于vue2.x中的mixin。
自定义hook的优势: 复用代码, 让setup中的逻辑更清楚易懂。

五十八、什么是 teleport ?

Teleport是一种能够将我们的组件html结构移动到指定位置的技术。
Teleport是一个内置组件,它可以将一个组件内部的一部分模板“传送”到该组件的DOM结构外层的位置去。

五十九、toRef与toRefs的区别?

作用: 创建一个 ref 对象,其value值指向另一个对象中的某个属性。
语法: const name = toRef ( person,‘name’ ) 。
应用: 要将响应式对象中的某个属性单独提供给外部使用时。
扩展: toRefs 与 toRef 功能一致,但可以批量创建多个 ref 对象,语法:toRefs(person)。

六十、readonly和shallowReadonly?

readonly:让一个响应式数据变为只读的(深只读)。
shallowReadonly:让一个响应式数据变为只读的(浅只读)。
应用场景: 不希望数据被修改时。

六十一、vue.$nextTick?

Vue.nextTick 简单来说就是一个延迟回调,在下次 DOM 更新循环结束之后执行。在修改数据之后立即使用这个方法,获取更新后的 DOM。
使用场景:

  1. 如果想要在修改数据后立刻得到更新后的DOM结构,可以使用Vue.nextTick() 。
  2. 在created生命周期中进行DOM操作。

六十二、v-if与v-for为什么不建议放在一起使用?

Vue 2 中,v-for的优先级比v-if高,这意味着v-if将分别重复运行于每一个v-for循环中。如果要遍历的数组很大,而真正要展示的数据很少时,将造成很大的性能浪费。
Vue 3 中,则完全相反,v-if的优先级高于v-for,所以v-if执行时,它调用的变量还不存在,会导致异常。

六十三、动态路由?

很多时候,我们需要将给定匹配模式的路由映射到同一个组件,这种情况就需要定义动态路由。例如,我们有一个 User组件,对于所有 ID
各不相同的用户,都要使用这个组件来渲染。 那么,我们可以在 vue-router 的路由路径中使用动态路径参数(dynamic
segment)来达到这个效果:{ path:‘ /user/ : id ’,compenent:User},其中 :id
就是动态路径参数。

六十四、了解哪些vue的性能优化方法?

  1. 路由懒加载。有效拆分应用大小,访问时才异步加载。
  2. keep-alive缓存页面。避免重复创建组件实例,且能保留缓存组件状态。
  3. v-for遍历避免同时使用v-if。实际上在 Vue 3 中已经是一个错误用法了。
  4. 长列表性能优化,可采用虚拟列表。
  5. v-once。不再变化的数据使用v-once。
  6. 事件销毁。组件销毁后把全局变量和定时器销毁。
  7. 图片懒加载。
  8. 第三方插件按需引入。
  9. 子组件分割。较重的状态组件适合拆分。
  10. 服务端渲染。

六十五、你能解释一下什么是vue.js吗?

Vue.js是一种构建用户界面的现代JavaScript框架。
它只在轻松开发可维护和可重用的应用程序。Vue框架具有简洁的API,并且易于集成到现有项目中。

六十六、你认为vue.js有什么优势?

Vue.js的优点包括:

  1. 轻量级, 在网页上加载速度很快
  2. 可以使用模板或者单文件组件结构构建Realtime数据绑定
  3. 组件化和模块化开发
  4. 流畅的API,包括生命周期钩子
  5. 易于学习和使用
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值