159期
1. Proxy 能够监听到对象中的对象的引用吗?
2. 前端如何实现文字的2端对齐?
3. 页面加载的过程中,JS 文件是不是一定会阻塞 DOM 和 CSSOM 的构建?
上面问题的答案会在第二天的公众号(程序员每日三问)推文中公布
也可以小程序刷题,已收录500+面试题及答案
158期问题及答案
1. Vue中还有其他方法实现 v-model 双向绑定吗?
在 Vue.js 中,v-model
指令通常用来创建表单输入和应用状态之间的双向数据绑定。然而,如果我们需要实现类似 v-model
的自定义双向绑定,可以通过组合 v-bind
和 v-on
来实现。
在一个自定义组件的情境中,实现双向绑定通常需要以下步骤:
使用
v-bind
或简写:
,将父组件的数据传递给子组件的 prop。在子组件内监听输入事件 (如
input
或change
),并在数据变化时触发一个事件,用于通知父组件更新数据。在父组件中使用
v-on
或简写@
监听由子组件触发的事件,并更新数据。
下面是如何不使用 v-model
,而是手动实现双向绑定的示例:
首先是父组件的模板:
<template>
<div>
<custom-input :value="message" @update:value="message = $event"></custom-input>
<p>Message: {{ message }}</p>
</div>
</template>
<script>
import CustomInput from './CustomInput.vue';
export default {
components: {
CustomInput
},
data() {
return {
message: "初始文本"
};
}
};
</script>
在此示例中,custom-input
是一个自定义组件,我们通过 :value="message"
把父组件的 message
数据传递给子组件。同时,使用 @update:value="message = $event"
在子组件触发 update:value
事件时,更新父组件的 message
数据。
接下来是子组件的实现:
<template>
<input :value="value" @input="onInput">
</template>
<script>
export default {
props: ['value'],
methods: {
onInput(event) {
// 当输入框的值发生变化时,发出一个自定义的事件来通知父组件
this.$emit('update:value', event.target.value);
}
}
};
</script>
在子组件中,我们定义了一个 prop value
用于接收来自父组件的值。我们还定义了一个 onInput
方法,当输入框的值发生变化时,通过 this.$emit
触发一个 update:value
事件,并将新的输入值作为参数传递。
这种方法的灵感来源于 Vue.js 的 .sync
修饰符,它在一定程度上是 v-model
的一个语法糖。在 Vue 2.3+ 版本中,对 prop 进行双向绑定的 .sync
修饰符可以作为 v-model
的替代方案。例如:
<custom-input :value.sync="message"></custom-input>
需要注意的是,v-model
在不同的表单元素和组件上可能会有不同的行为,例如在一个 checkbox 上,v-model
会自动处理勾选状态和布尔值之间的转换。因此,在使用 v-bind
和 v-on
手动双向绑定时,你可能需要根据不同的输入类型进行适当的处理。
2. vue 的响应式开发比命令式有哪些优势?
Vue 的响应式开发指的是框架通过数据的响应式系统自动追踪依赖和管理更新。当应用状态变化时,它能够智能地计算哪些组件需要被重新渲染,以确保DOM与数据保持一致。与之相对的命令式开发,开发者需要直接操作 DOM 来响应数据的变化,通过编写具体的逻辑来控制应用的行为。
Vue的响应式开发具有以下优势:
声明式代码: 响应式开发通常是声明式的,开发者只需声明数据与视图之间的关联,不需要编写实现细节。Vue会自动处理依赖追踪和更新,减少了手动DOM操作的代码,使得代码更易读和易维护。
减少bug和错误: 手动DOM操作容易造成错误,而且在复杂的应用中管理所有的状态变化非常困难。Vue的响应式系统可以保证当数据变化时,相关的DOM更新是准确的,从而减少了bug的产生。
高效更新: Vue利用虚拟DOM来避免不必要的DOM操作。响应式系统仅仅更新实际变化的部分,而不是重新渲染整个视图,这样可以提高性能,尤其是在大型应用中更为明显。
易于理解和预测: 因为Vue中数据驱动视图,这使得应用的数据流动和状态变化更加一目了然。开发者可以更容易地推断出给定的数据状态可能产生的UI界面。
组件化: Vue通过组件系统促进了UI的模块化。每个组件拥有自己的状态,模板和行为,可以独立更新,让大型应用的开发变得更加模块化和组织化。
工具生态系统: Vue及其响应式系统的流行还带动了一个丰富的工具链生态系统,如 Vuex 状态管理库和 Vue Devtools 调试工具,它们可以提供高级的状态管理、时间旅行调试等功能,进一步提高开发效率。
可维护性: 随着应用规模的扩大,命令式代码可能导致维护成本急剧增加,而在Vue的声明式和组件化的设计下,可大幅降低维护成本。
可测试性: 响应式编程能更清晰地定义应用的数据流和逻辑,相比于命令式编程更容易实现代码的单元测试。
综上所述,Vue的响应式开发提供了一个高效、可维护且可测试的框架,使得开发者可以更加专注于应用的状态管理,而不是繁琐的DOM操作和更新逻辑。
3. React.memo() 和 useMemo() 的用法是什么,有哪些区别?
React 提供了多种优化工具,其中 React.memo()
和 useMemo()
是两种用于提高组件渲染性能的工具。尽管它们的目的相似,但它们在使用方式和场景上有所不同。
React.memo()
React.memo()
是一个高阶组件,用于对函数组件进行性能优化。它仅检查组件的 props 是否发生变化,如果 props 没有变化,则不会重新渲染组件。React.memo()
适用于纯组件(即给定相同的 props,总是渲染相同结果的组件)。
使用 React.memo()
的基本语法如下:
const MyComponent = React.memo(function MyComponent(props) {
// 渲染逻辑
});
你还可以传递第二个参数,一个比较函数,用于自定义比较算法:
const MyComponent = React.memo(
function MyComponent(props) {
// 渲染逻辑
},
(prevProps, nextProps) => {
// 返回 true 以跳过更新;返回 false 以继续更新
return prevProps.someValue === nextProps.someValue;
}
);
useMemo()
useMemo()
是一个钩子(Hook),它用于缓存计算结果,以避免在每次渲染时进行重复计算。当你需要根据依赖项进行昂贵的计算时,useMemo()
可以帮助你避免不必要的计算,只有当依赖项发生变化时才重新计算。
useMemo()
的基本语法如下:
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
这里的 computeExpensiveValue
是一个函数,a
和 b
是它的依赖项。只有当 a
或 b
改变时,computeExpensiveValue
才会被重新计算。
区别
用途和目标不同:
React.memo()
是针对组件整体是否重新渲染进行优化的,而useMemo()
是用来缓存计算结果,避免重复计算。作用范围不同:
React.memo()
对整个组件生效,影响组件的渲染行为;useMemo()
仅在渲染过程中对其内部的函数调用和返回值生效,并不直接控制组件的渲染。声明方式不同:
React.memo()
是一个组件包装器,它包裹整个组件;useMemo()
是一个钩子,它在组件内部被调用。
简单地说,如果你想避免因为父组件的渲染而导致的无关紧要的子组件重渲染,那么你应该使用 React.memo()
。如果你需要缓存复杂的计算结果,应该使用 useMemo()
。两者正确使用时都能提升应用性能,但要注意不要过度使用以避免引入不必要的复杂性。
我要提问
如果你遇到有趣的面试题,或者有想知道的前端面试题,可以在下面的小程序提问,收到问题后会在第一时间为你解答。
我要出题
学习不打烊,充电加油只为遇到更好的自己,每天早上9点纯手工发布面试题,每天坚持花20分钟来学习与思考,在千变万化,类库层出不穷的今天,不要等到找工作时才狂刷题,提倡每日学习。