178期题目
1. vuex中的重要核心属性有哪些?
2. TCP和UDP的区分是什么?分别有什么应用场景?
3. vuex刷新页面状态丢失,如何防止?
上面问题的答案会在第二天的公众号(程序员每日三问)推文中公布
也可以小程序刷题,已收录500+面试题及答案
177期问题及答案
1. vue双向绑定的原理是什么?
Vue.js的双向绑定是通过其核心特性之一的"响应式系统"来实现的。下面我将从多个角度详细解释Vue双向绑定的原理。
数据劫持(Data Observation): Vue使用Object.defineProperty()方法来劫持(拦截)数据对象的属性。当你创建一个Vue实例时,Vue会遍历数据对象的每个属性,使用Object.defineProperty()将它们转换为getter和setter。这样一来,当数据发生变化时,Vue能够检测到,并通知视图更新。
<div id="app"> <input v-model="message"> <p>{{ message }}</p> </div> <script> var vm = new Vue({ el: '#app', data: { message: '' } }); </script>
编译过程: 在编译阶段,Vue会解析模板,找到所有带有
v-model
指令的元素。然后,它会为每个v-model
创建一个观察者(Watcher)。这个观察者会监听对应数据属性的变化。事件监听: 对于
v-model
绑定的表单元素,Vue通过监听输入事件(input)来捕获用户输入。当用户在输入框中输入文本时,触发的输入事件将触发数据的更新。<input v-model="message" @input="updateMessage">
在Vue实例中需要定义
updateMessage
方法:methods: { updateMessage: function(event) { this.message = event.target.value; } }
双向绑定的本质: 当数据发生变化时,
setter
会被触发,通知相关的观察者,而这些观察者负责通知视图进行更新。反之,当用户在输入框中输入内容时,input
事件触发,调用updateMessage
方法,更新数据,触发setter
,再次实现数据驱动视图的更新。
这就是Vue双向绑定的基本原理。通过数据劫持、编译过程和事件监听的协同作用,Vue能够实现数据与视图的双向绑定。
2. 添加原生事件不移除,为啥会内存泄漏?
在前端开发中,如果你添加了原生事件而没有适当地移除,可能会导致内存泄漏。这是因为事件绑定会创建一个对函数的引用,而这个引用可能在后续的代码执行中一直存在,即使你认为不再需要这个引用了。下面从几个角度解释为什么添加原生事件不移除可能导致内存泄漏:
循环引用: 当你在JavaScript中使用事件监听器时,如果事件监听器中引用了DOM元素,而该DOM元素又引用了事件监听器,就会形成循环引用。这时,即使你认为你已经不再需要这个DOM元素,由于循环引用,它和相关的事件监听器都无法被垃圾回收机制释放,导致内存泄漏。
闭包: 如果你在事件监听器中使用了闭包,并且这个闭包引用了一些外部的变量,这些变量可能在事件监听器被移除之前一直存在于内存中。即使你认为事件监听器不再需要,闭包中引用的外部变量可能会阻止垃圾回收器回收相关的内存。
function addEventListener() { var someVar = 'example'; element.addEventListener('click', function() { console.log(someVar); }); }
忘记移除事件监听器: 在开发中,经常会动态创建或销毁DOM元素,但如果你忘记在元素销毁前移除相关的事件监听器,这些监听器将一直存在于内存中。这种情况尤其容易发生在单页应用(SPA)中,因为页面不会完全刷新,而是通过JavaScript动态更新。
为了避免内存泄漏,务必在不需要事件监听器时手动移除它们。可以使用removeEventListener
方法,或者在使用框架(如React、Vue)时,确保在组件销毁前取消所有事件监听器。及时的移除事件监听器有助于释放不再需要的内存,避免潜在的性能问题。
3. 上下固定,中间滚动布局如何实现?
实现上下固定、中间滚动的布局,可以使用flexbox或grid布局来简化代码。以下是一种使用flexbox的方法:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
height: 100vh;
}
.header, .footer {
background-color: #333;
color: #fff;
text-align: center;
padding: 10px;
}
.header {
flex-shrink: 0;
}
.footer {
flex-shrink: 0;
margin-top: auto;
}
.content {
flex-grow: 1;
overflow-y: auto;
padding: 20px;
}
</style>
<title>Fixed Header/Footer, Scrollable Content</title>
</head>
<body>
<div class="header">Header</div>
<div class="content">
<!-- Your scrollable content goes here -->
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. ...</p>
</div>
<div class="footer">Footer</div>
</body>
</html>
在这个布局中,.header
和.footer
使用了flex-shrink: 0;
,这样它们不会缩小,而是固定在页面的顶部和底部。.content
使用了flex-grow: 1;
,使其占据剩余的空间,同时设置overflow-y: auto;
来允许内容超出屏幕高度时出现纵向滚动条。
这种方式更加简洁,灵活,同时适用于响应式设计。你可以根据实际需求调整header、footer的样式,或者使用grid布局进行类似的实现。
因为微信公众号修改规则,如果不标星或点在看,你可能会收不到我公众号文章的推送,原创不易,请大家将本公众号星标,看完文章后记得点下赞或者在看,谢谢各位!
学习不打烊,充电加油只为遇到更好的自己,每天早上9点纯手工发布面试题,每天坚持花20分钟来学习与思考,在千变万化,类库层出不穷的今天,不要等到找工作时才狂刷题,提倡每日学习。