前端面试题
- 总结一些前端面试中常问的面试题
- 原生js操作dom的方法有哪些?
- Ajax的优点?
- javascript中`==`与`===`的区别?
- 描述一下css盒模型?
- Vue如何检测数组变化?
- Spa单页面应用是什么?
- Exports和module exports区别?
- 介绍css的em和rem单位,两者有什么不同?
- 闭包的理解以及优缺点?
- 介绍js的基本数据类型?
- 什么是面向对象编程及面向过程编程,他们的异同和优缺点?
- 简单描述什么是事件冒泡机制?如何阻止事件冒泡?
- 什么是同源策略?解决同源策略实现跨域的几种方式?
- Vue生命周期的哪个阶段才能访问操作dom?
- Let和var区别?
- 什么是同源策略,为什么要有同源策略?
- Vue生命周期什么时候可以ajax请求
- for in 和for of的区别
- 如何用css让一个元索不可见,请提供三种方法并比较不同点
- v-model 原理?
总结一些前端面试中常问的面试题
答案是自己查询,有问题欢迎指出。
原生js操作dom的方法有哪些?
- getElementById:通过元素的id属性获取DOM元素。
- getElementsByTagName: 通过元素的标签名获取DOM元素的集合。
- getElementsByClassName: 通过元素的class属性值获取DOM元素的集合。
- querySelector: 通过CSS选择器获取匹配的第一个元素。
- querySelectorAll: 通过CSS选择器获取所有匹配的元素的集合。
- createElement:创建新的DOM元素。
- appendChild:将一个新的子元素插入到一个已有的父元素中。
- removeChild:从一个父元素中移除一个子元素。
- cloneNode:复制一个DOM元素。
- setAttribute:设置一个DOM元素的属性。
- getAttribute:获取一个DOM元素的属性。
- removeAttribute:移除一个DOM元素的属性。
- innerHTML:获取或设置元素的HTML内容。
- style:获取或设置元素的样式。
- classList: 获取或设置元素的className属性。
Ajax的优点?
Ajax (Asynchronous JavaScript and XML) 是一种在不重新加载整个页面的情况下,通过使用异步的 HTTP 请求页面部分更新的技术。Ajax 的优点如下:
-
增强用户体验:Ajax 可以让 Web 页面快速、动态地更新部分页面内容,为用户提供更加流畅、无刷新的体验,减少了页面的闪烁和卡顿。
-
减少服务器负担:在 Ajax 中,整个页面不需要重新刷新,只有需要更新的数据才会进行异步请求,减少了不必要的数据传输,降低了服务器的负担,提高了 Web 应用程序的响应速度。
-
优化网络传输:Ajax 可以在后台使用更小的数据集进行服务器交互,能够避免重复下载无用的页面元素,减小了网络传输的负载,提高了网络传输的效率。
-
提高 Web 应用程序的可维护性:使用 Ajax 技术可以让 Web 应用程序具有更加清晰的架构,更具可维护性和可扩展性。
-
支持多种数据格式:Ajax 不仅可以支持 XML 数据格式,还支持多种数据格式的处理,比如 JSON、纯文本等。
-
轻量级,易学易用:Ajax 技术通过简单的 JavaScript 代码实现,能够轻松地实现跨浏览器的异步请求和响应,而且其代码量少,容易学习、使用和维护。
javascript中==
与===
的区别?
JavaScript中,== 与 === 的区别在于:
-
== 运算符会进行类型转换后再比较,而 === 运算符不会进行类型转换,需要类型和值都相等才会返回true。
-
== 运算符的类型转换规则相对复杂,会将两个操作数转换成某种共同类型进行比较,而 === 操作符则仅比较两个操作数的类型和值是否相等。
例如:
0 == false // true
0 === false // false
"" == false // true
"" === false // false
null == undefined // true
null === undefined // false
在第一个示例中,0 与 false 进行比较,由于 JavaScript 中 0 被视为 false,因此返回 true。而在第二个示例中,0 和 false 的类型不同,因此返回 false。
在第三个示例中,空字符串 “” 与 false 进行比较,由于 JavaScript 中空字符串被视为 false,因此返回 true。而在第四个示例中,空字符串和 false 的类型不同,因此返回 false。
在最后一个示例中,null 和 undefined 被视为相等的两个值,因此返回 true。但是,由于它们的类型不同,因此使用 === 运算符会返回 false。
描述一下css盒模型?
CSS盒模型是CSS中一个重要的概念,用于描述网页中所有元素在页面上所占用的空间。
CSS盒模型包括以下几个部分:
-
内容区域(Content Box):元素的实际内容区域,包括文本、图片等。
-
内边距(Padding):元素边框内部与实际内容之间的区域,用于控制内容与边框之间的距离。内边距可以包含背景色或背景图像。
-
边框(Border):包围元素的边框,用于控制元素占据的空间的大小、形状和样式。
-
外边距(Margin):元素边框与周围元素之间的距离,用于控制元素之间的间距。
CSS盒模型分为两种,分别是标准盒模型和IE盒模型。它们的区别在于如何计算元素的宽度和高度。在标准盒模型中,元素的宽度和高度包括了内容区域、内边距、边框的大小,而在IE盒模型中,元素的宽度和高度还包括了元素的外边距。
在CSS中,可以使用box-sizing属性来控制盒模型的类型。默认的box-sizing属性值为content-box,表示使用标准盒模型,可以设置为border-box来使用IE盒模型。
Vue如何检测数组变化?
Vue 可以使用 watch
监听数组变化,但 watch
监听数组时要注意以下两点:
-
因为 JavaScript 数组的原生方法不支持响应式,Vue 会通过拦截这些方法来实现数组的响应式更新。因此,我们应该使用使用修改数组的响应式方法(如
push()
、pop()
、shift()
、unshift()
、splice()
、sort()
、reverse()
),而不是直接使用数组的原生方法进行修改。 -
当通过下标直接修改数组元素时,Vue 无法检测到数组的变化,因此应该使用
Vue.set()
或者vm.$set()
方法来进行修改。
下面是一个使用 watch
监听数组变化的示例:
var vm = new Vue({
data: {
items: ['item1', 'item2', 'item3']
},
watch: {
items: function(newValue, oldValue) {
// newValue 为数组改变后的值,oldValue 为改变前的值
console.log('数组变化了', newValue);
}
}
});
vm.items.push('item4'); // 控制台输出 "数组变化了 ['item1', 'item2', 'item3', 'item4']"
除此之外,Vue 还提供了 Vue.set()
或 vm.$set()
方法来修改数组元素,示例如下:
// 在数组末尾添加一个新元素
vm.items.push('item4');
// 在数组下标为1的位置插入一个新元素
vm.items.splice(1, 0, 'item5');
// 通过Vue.set() 修改数组元素
Vue.set(vm.items, 2, 'item6');
总之,通过以上方法可以轻松地检测到数组变化。
Spa单页面应用是什么?
SPA(Single Page Application),单页面应用程序,是一种现代的Web应用程序开发方式,它通过动态加载HTML、CSS、JavaScript等资源,在同一个页面中实现应用程序的逻辑与界面的更新。
传统的多页面应用程序,在用户与应用程序交互时,通常需要重新加载整个页面,这样会导致应用程序的性能、响应速度和用户体验都会有所下降。而SPA单页面应用则避免了这个问题,通过在同一个页面内动态更新内容,让用户可以更快地浏览和完成操作。
SPA单页面应用的特点包括:
-
只有一个HTML页面,所有的内容都通过一些列AJAX请求动态加载,不需要刷新页面。
-
前后端分离,前端负责渲染页面,后端负责提供API接口。
-
路由通过前端来控制,在前端实现跳转页面的功能。
-
优化用户体验,前端通过预加载技术或缓存技术提高用户体验。
-
复杂的SPA应用需要使用框架(如Vue、React、Angular等)来帮助管理状态、路由、组件等。
在SPA单页面应用中,所有的数据都是在前端渲染,所以一些敏感信息(如API key、数据库密码等)需要处理好,以免泄漏给不法分子。同时,由于SPA单页面应用通常需要通过AJAX请求与后端进行沟通,因此需要注意一些常见的网络安全问题,如跨站脚本攻击(XSS)、跨站请求伪造(CSRF)等。
Exports和module exports区别?
-
在 Node.js 中,用于模块化的方法有
exports
和module.exports
两个,它们的区别如下:-
exports
实际上是module.exports
的引用,即exports === module.exports
为true
。如果我们想要向外部暴露一个对象,可以直接将需要暴露的对象赋值给module.exports
或exports
,如exports.foo = 'foo'
、module.exports.bar = 'bar'
。 -
exports
的相对值不能为其他值类型,即exports = ...
会改变exports
的引用,而不在是module.export
的引用,这样exports
就不再是module.exports
的引用,不能向外部暴露对象。 -
对于
exports.foo
和module.exports.foo
来说,效果是相同的,都可以向外部暴露一个对象。但当module.exports
被重新赋值时,exports
将不再指向module.exports
,也就不能再通过exports.foo = 'foo'
的方式向外部暴露对象了。
综上所述,当需要暴露一个模块时,建议直接使用
module.exports
,因为它是最终被导出的对象。只有在需要给module.exports
添加属性或方法时,才需要使用exports
。例如:// 导出一个对象 module.exports = { foo: 'foo', bar: function() { console.log('bar'); } }; // 给 module.exports 添加属性 module.exports.baz = 'baz';
-
介绍css的em和rem单位,两者有什么不同?
em
和 rem
是 CSS 中用于设置字体大小的相对单位。
-
em
相对于其父元素的字体大小设置大小,如果在一个p
元素中设置font-size: 2em;
,那么该p
元素的字体大小将为其父元素字体大小的两倍。若父元素没有设置字体大小,则em
相对于浏览器默认字体大小。 -
rem
相对于根元素(即html
元素)的字体大小设置大小,如果根元素设置了font-size: 16px;
,那么一个div
元素中设置font-size: 2rem;
,将会得到div
元素字体大小为32px
的效果。
em
和 rem
的区别在于,em
是相对与其父元素的字体大小设置大小,而 rem
则是相对于根元素的字体大小设置大小。因此,em
会随着父元素的字体大小而变化,而 rem
的大小只与根元素的字体大小有关。
使用 em
和 rem
的好处是,可以快速改变整个网站的字体大小,让网站的字体大小适应不同的屏幕大小。另外需要注意的是,某些浏览器不支持 rem
,因此在使用时需要做好兼容性处理。
闭包的理解以及优缺点?
闭包是指有权访问另一个函数作用域中的变量的函数。闭包可以在外部函数的作用域内访问内部函数的变量和参数,也可以在外部函数返回后访问它们。因此,闭包可以用来创建私有变量和私有方法,为函数式编程提供了有力的支持。
闭包的优点:
- 可以访问外部函数的作用域和变量,使得函数可以访问它不直接拥有的变量和参数。
- 可以实现私有变量和私有方法,从而实现信息隐藏和封装。闭包中的变量和方法在外部无法直接访问,从而保证了代码的安全性和可靠性。
- 可以在外部函数执行完之后,仍然可以访问闭包中的变量和方法。
闭包的缺点:
- 可能会导致内存泄漏。如果闭包持有对外部变量的引用,且这个引用不需要了,但没有释放,就会导致内存泄漏。
- 闭包会增加代码的复杂度和理解难度。由于闭包可以访问外部函数的变量和参数,可能会出现多重嵌套的情况,导致代码难以理解和调试。
总之,闭包是一种强大的编程技巧,可以实现许多有用的功能。但是,需要注意闭包可能会导致内存泄漏和代码复杂度增加等问题,因此在使用闭包时需要谨慎。
介绍js的基本数据类型?
JavaScript 的基本数据类型有六种,分别为:
number
(数字):可以是整数或浮点数,例如1
、1.5
等。string
(字符串):用单引号'
或双引号"
包裹的文本,例如'hello'
、"world"
等。boolean
(布尔值):只有两个值true
或false
。null
(空值):表示一个空对象指针,通常用于初始化一个变量为“空”的状态。undefined
(未定义):表示一个未初始化的变量,或者一个不存在的属性或变量。symbol
(符号):ES6 新增的一种数据类型,表示唯一的标识符。
JavaScript 也有一种复杂数据类型 object
(对象),对象是由一组属性(键值对)组成的无序集合,例如:
var person = {
name: 'John',
age: 35,
isMarried: false
}
上面的代码定义了一个名为 person
的对象,包含了 name
、age
和 isMarried
三个属性,分别对应字符串、数字和布尔值类型的数据。对象的属性可以是任意类型的数据,也可以是函数等复杂数据类型。
什么是面向对象编程及面向过程编程,他们的异同和优缺点?
面向对象编程(Object-Oriented Programming,OOP)和面向过程编程(Procedure-Oriented Programming,POP)是两种常见的编程范式。
面向对象编程是一种以类或对象为基础,通过抽象、封装、继承和多态等概念,将数据和操作封装在一起的编程模型。面向对象编程的主要目标是提高代码的复用性、可维护性和可扩展性,使代码更易于理解和维护。
面向过程编程是一种以函数为基础,按照逻辑顺序执行一系列操作的编程模型,强调解决问题的步骤和过程,将大问题分解成一些小问题,并依次解决。面向过程编程以数据为中心,通过函数对数据进行加工处理,最终得到解决方案。
面向对象编程的特点:
- 抽象性:能够对真实世界中的问题进行更加准确的描述和抽象,提高模型的可靠性和适应性。
- 封装性:将数据和方法封装在一起,保护数据的安全性和独立性,使得代码更加清晰和易于维护。
- 继承性:能够通过继承机制实现代码的重用性和扩展性,减少代码的重复编写和维护成本。
- 多态性:能够根据对象的不同状态和行为,实现代码的灵活性和可扩展性,使得代码更易于理解和维护。
面向过程编程的特点:
- 步骤性:按照逻辑顺序执行一系列操作,强调解决问题的步骤和过程。
- 数据中心:以数据为中心,通过函数对数据进行加工处理,最终得到解决方案。
- 可读性:代码通常比较简单明了,易于理解和阅读。
- 效率性:面向过程的代码通常比面向对象的代码更加高效,因为它避免了额外的封装和继承开销。
面向对象编程和面向过程编程各有优缺点,具体如下:
面向对象编程的优点:
- 提高代码的复用性、可维护性和可扩展性,使得代码更易于理解和维护。
- 提高程序的可靠性和安全性,通过封装和继承等机制保护数据和操作的安全性。
- 使代码更易于组织和管理,面向对象编程使得代码分层清晰,提高了代码的可读性和可维护性。
面向对象编程的缺点:
- 面向对象编程需要更高的抽象和设计能力,需要考虑更多的模型和类的设计,对初学者来说较为困难。
- 由于面向对象编程更注重代码的组织和设计,对代码的执行效率有一定的影响。
面向过程编程的优点:
- 代码编写比较简单明了,易于理解和阅读,对于小型项目来说比较适合。
- 由于面向过程编程比较直接,代码执行效率比较高。
面向过程编程的缺点:
- 随着项目规模的增大,代码的复杂性也会增加,难以维护和扩展。
- 代码的重复率比较高,代码重用性较低。
简单描述什么是事件冒泡机制?如何阻止事件冒泡?
事件冒泡机制是指当一个元素上的事件被触发时,该事件会从最内层的元素开始逐层向外层元素传递,直到传递到最外层元素。例如,当一个子元素被点击时,该元素的点击事件不仅会被触发,而且所有父级元素的点击事件也会被依次触发。
阻止事件冒泡可以使用 stopPropagation()
方法,该方法可以阻止事件的继续传播,即事件只会在当前元素中处理,不会继续向外传播。例如,当一个子元素被点击时,可以在该元素上调用 stopPropagation()
方法阻止事件继续传播到父级元素,例如:
element.addEventListener('click', function(event) {
event.stopPropagation();
// 点击子元素的操作
});
需要注意的是,使用 stopPropagation()
方法可能会导致一些问题,例如无法执行其他事件处理程序,或者在多级嵌套的元素中无法正确识别事件的源头。因此,在使用 stopPropagation()
方法时需要谨慎,确保不会影响其他代码的执行。
什么是同源策略?解决同源策略实现跨域的几种方式?
同源策略是一种安全策略,是浏览器最核心也最基本的安全功能之一。同源策略的要求是,两个页面如果想要互相访问彼此的文档、Cookie 和其他资源,必须要满足以下三个条件:
- 两个页面具有相同的协议(protocol,如 http 或 https)。
- 两个页面具有相同的主机名(host,如 www.example.com)。
- 两个页面具有相同的端口号(port,如 80 或 443)。
如果两个页面不满足以上三个条件中的任一个,就被视为跨域,浏览器将拒绝后续操作。这种安全策略可以有效防止恶意攻击者利用网站漏洞进行跨站请求伪造(CSRF)攻击、跨站脚本攻击(XSS)等安全问题,保护了用户的信息安全。
跨域是指在一个域名、协议或端口与当前页面不同的情况下,从一个网页访问另一个网页的行为。解决跨域问题的常见方式有以下几种:
- JSONP:利用
<script>
标签可以跨域的特性,通过在请求地址中添加回调函数参数,服务器返回一段执行回调函数的 JavaScript 代码,从而实现跨域访问。 - CORS(跨域资源共享):CORS 是一种标准的解决跨域资源访问的方案,通过在服务器端设置响应头部,允许指定源或一组源可以访问该资源,从而实现跨域访问。
- 代理服务器:通过在同一域名下,利用服务器端发送请求来实现跨域访问。前端应用将请求发送到服务器端,由服务器端将请求转发到目标地址,并返回接收到的响应结果给前端应用。
- WebSocket:建立 WebSocket 连接,通过 WebSocket 协议进行通信,不受同源策略限制。
需要注意的是,跨域访问可能会带来一定的安全风险,因此需要谨慎使用,确保跨域访问不会影响用户的信息安全和隐私。
Vue生命周期的哪个阶段才能访问操作dom?
在 Vue 的生命周期中,只有在 mounted
钩子函数被调用后,才能访问和操作 Vue 组件所在的 DOM。这是因为 mounted
钩子函数是在 Vue 实例挂载到 DOM 上后被调用的,此时 Vue 组件已经渲染完成,DOM 节点已经生成并插入到页面中,可以进行 DOM 操作。
在 beforeMount
钩子函数中虽然也能访问到渲染生成的 DOM,但是此时 DOM 还没有真正被渲染到页面中,所以进行 DOM 操作并不能真正地显示在页面上,只是可以对 DOM 进行修改。
需要注意的是,在操作 DOM 时,需要使用 Vue 提供的 $refs
或 $el
属性,而不是直接操作 DOM。因为 Vue 对 DOM 做了数据双向绑定,直接操作 DOM 可能会破坏 Vue 实例的数据状态,导致一些意想不到的问题。使用 $refs
或 $el
属性可以保证操作 DOM 的安全性和可靠性。
Let和var区别?
JavaScript 中,let
和 var
都是用来声明变量的关键字,但是两者有以下几个区别:
-
变量作用域:
var
声明的变量作用域是函数作用域或全局作用域,使用var
声明的变量可以在整个函数内部使用。let
声明的变量作用域是块级作用域({}
中的代码块),使用let
声明的变量只能在代码块内部使用,并且不存在变量提升。
-
变量重复声明:
- 使用
var
声明的变量,可以重复声明同名的变量,后续声明会覆盖前面的声明。 - 使用
let
声明的变量,在同一个作用域中不能重复声明同名的变量,如果重复声明会导致语法错误。
- 使用
-
全局声明:
- 使用
var
声明的变量会挂载在全局对象(Window
)上,可以通过全局对象访问。 - 使用
let
声明的变量不会挂载在全局对象上,不能通过全局对象访问。
- 使用
-
临时死区:
- 使用
let
声明的变量存在临时死区,即只要变量在定义之前被引用,就会抛出错误。 - 使用
var
声明的变量不存在临时死区,但是存在变量提升,即变量可以在声明之前使用,值为 undefined。
- 使用
综上,let
与 var
的主要区别在于作用域、变量重复声明和全局声明。使用 let
声明的变量更加安全,避免了变量提升和重复声明的问题,建议在需要使用局部变量时使用 let
。而 var
声明的变量是早期 JavaScript 版本中的语法,虽然仍然有效,但是在较新的 JavaScript 版本中,推荐使用 let
和 const
。
什么是同源策略,为什么要有同源策略?
同源策略是一种安全机制,用于限制不同源(协议、域名、端口)之间的交互。同源策略要求文档或脚本只能在与其来源相同的域中读取和执行,否则就会受到浏览器的安全限制,这样可以防止恶意的网站窃取用户数据或者攻击受害者的计算机。
同源策略的作用主要有以下几点:
-
防止数据泄露:同源策略可以阻止网站间的恶意攻击,如跨站脚本(XSS)或跨站请求伪造(CSRF)等攻击方式,从而能够保证用户数据在安全的环境中运行。
-
保护用户隐私:同源策略可以防止其他网站窃取用户的个人数据,如 cookie、LocalStorage、SessionStorage 等。
-
提高安全性:同源策略可以保证不同网站之间的数据和代码不能互相干扰,从而能够提高Web浏览器的安全性和稳定性。
虽然同源策略提高了 Web 应用的安全性,但同时也会带来一些限制。比如,同源策略会阻止跨域 Ajax 请求,限制了开发人员的 Web 应用的访问范围。为了解决这个问题,产生了一些常见的跨域解决方案,如 JSONP、CORS、IFrame 等。
Vue生命周期什么时候可以ajax请求
在 Vue 的生命周期中,可以在 created
钩子函数中进行 Ajax 请求。created
钩子函数是在实例被创建时调用的,此时实例已经完成数据观测、属性和方法的运算,可以访问数据、组件实例和 DOM 等内容。因此,在 created
钩子函数中发起 Ajax 请求可以获取到组件所需的数据,并进行初始化操作。
需要注意的是,使用 Ajax 请求需要考虑一些异步请求的问题,比如请求失败、请求超时等情况,通常可以使用 Promise 或 async/await 进行异步处理。另外,在组件销毁时需要及时终止所有未完成的 Ajax 请求,以避免出现意想不到的问题和网络负载。
另外,如果需要在组件渲染完成后进行 Ajax 请求,可以在 mounted
钩子函数中进行请求。mounted
钩子函数是在组件挂载到 DOM 后调用的,此时 DOM 已经渲染完成,可以进行 DOM 操作和 Ajax 请求。不过在数据请求期间,页面可能会出现数据加载中的状态,需要注意用户体验的问题。
for in 和for of的区别
for...in
和 for...of
是两种 JavaScript 的循环语句,它们有以下主要区别:
-
for...in
循环是遍历对象或数组的所有可枚举属性,包括继承的属性,并且返回的是属性名;而for...of
循环是遍历可迭代对象(如数组、Map、Set 等)的值,不包括对象的属性,并且返回的是属性值。 -
for...in
循环是适用于对象及其原型链的遍历,而for...of
循环是适用于迭代器对象(Iterable)的遍历方式。 -
for...in
循环不保证顺序,而for...of
循环保证按照迭代器对象中的顺序进行遍历。
以下是 for...in
和 for...of
的示例:
const arr = [1, 2, 3, 4]
// for...in 循环遍历数组的索引
for (const index in arr) {
console.log(index) // 输出:0, 1, 2, 3
}
// for...of 循环遍历数组的值
for (const value of arr) {
console.log(value) // 输出:1, 2, 3, 4
}
总之,for...in
适用于遍历对象的属性,而 for...of
适用于遍历迭代器对象的值。
- 可以在for in中修改数组的值吗
在 for...in
循环中修改数组的值是不推荐的,因为这可能会导致意想不到的后果,并且会破坏循环的行为。其中的原因是因为 for...in
循环遍历一个对象的所有可枚举属性,包括原型链上的属性,可能会遍历到数组原型上的属性,而不仅仅是数组的索引。如果在 for...in
循环中修改数组的值,则可能会修改原型上的属性或者修改循环索引的值,导致出现问题。
相反,我们应该使用 for...of
循环来遍历数组的值,或者使用传统的 for
循环,而不是 for...in
循环,因为这两种循环可以确保只遍历到数组的索引。以下是 for...of
和传统的 for
循环的示例:
// 使用 for...of 循环遍历数组的值
const arr = [1, 2, 3, 4]
for (const value of arr) {
console.log(value) // 输出:1, 2, 3, 4
}
// 使用传统的 for 循环遍历数组的值
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]) // 输出:1, 2, 3, 4
}
// 不要使用 for...in 循环来遍历数组
for (const index in arr) {
console.log(arr[index]) // 不推荐这样做
}
总之,我们不应该在 for...in
循环中修改数组的值,而应该使用 for...of
循环或者传统的 for
循环来遍历数组的值。
如何用css让一个元索不可见,请提供三种方法并比较不同点
可以通过以下三种方式让一个元素不可见:
- display: none
该 CSS 属性可让元素不可见,同时不会占据页面的空间。
.element {
display: none;
}
- visibility: hidden
该 CSS 属性可让元素不可见,但仍然占据页面的空间。
.element {
visibility: hidden;
}
- opacity: 0
该 CSS 属性可让元素不可见,但仍然占据页面的空间。该方式与 visibility
不同的地方在于,元素的占位不会改变,所以其他元素在布局时,仍然会按照元素的大小预留空间。
.element {
opacity: 0;
}
不同点:
display: none
方式让元素不可见的同时不占据页面空间,而visibility: hidden
和opacity: 0
方式让元素不可见,但仍然占据页面的空间。display: none
方式会改变元素的布局,相当于元素消失了。而其他两种方式不会改变元素的布局,相当于元素仍然存在,但是不可见。因此,使用display: none
方式会导致其他元素在布局时重新排列,而其他两种方式不会改变布局。opacity: 0
可以实现元素的渐变消失效果,而其他方式无法实现这种效果。
v-model 原理?
v-model
是 Vue.js 提供的一个指令,用于实现表单元素与数据之间的双向绑定。它背后的实现原理是使用了对象的 getter
和 setter
。
在 Vue.js 中,数据都是存储在 data
对象中的。当使用 v-model
指令绑定表单元素时,Vue.js 会生成一个对象,这个对象由表单元素的值作为属性值,由 getter
和 setter
函数作为属性方法。
当表单元素的值发生改变时,会调用 setter
方法,将表单元素的新值更新到数据对象中,然后 Vue.js 又会重新渲染视图,把更新后的数据显示在文本框中。
当数据对象发生改变时,会调用 getter
方法,将最新的数据值绑定到表单元素中,同时 Vue.js 也会重新渲染视图,把最新的数据值显示在文本框中。
简单来说,v-model
就是在表单元素和数据对象之间建立了一个双向绑定的关系,表单元素的值和数据对象的值始终保持同步。它的实现原理是利用了 JavaScript 对象的 getter
和 setter
,以及 Vue.js 的响应式数据系统,来实现数据的动态绑定和更新。