组件中的 data 为什么是一个函数?
如果 data 是对象的话,当数据改动时就会影响到所有的实例,可能会造成一些数据的冲突。
HTTP
http:以安全为目标的http通道,HTTPs是以安全为目标的https通道(使用SSL进行加密)
v-model 是什么,有什么用?
v-model 是一个常用的表单指令,也是唯一一个双向绑定指令。双向的含义是:状态的变化能更新到视图上;用户在表单中的修改也能更新到状态中。
Vue 的双向数据绑定是如何实现的
通过 Object.defineProperty() 来给各个属性添加 setter,getter 方法并劫持监听,在数据变动时发布消息给订阅者,触发相应的监听回调。
为什么 Vue3 用 proxy 代替了 Vue2 中的 Object.defineProperty
1.Object.defineProperty 不能监控数组下标的变化,导致通过数组下标添加的元素不能实时响应
2.Object.defineProperty 只能监听对象的属性,导致需要对每个对象、每个属性都进行遍历,如果属性值也是对象,则需要进行深度遍历。
Vue3.x 中使用了 proxy 代替了 Object.defineProperty,因为它是对整个对象进行代理,所以可以监听对象某个属性值的变化,还可以监听对象属性的新增和删除,而且还可以监听数组
父子组件通信
props 用于在子组件中接收父组件传递的数据。emit 用于子组件调用父组件中的方法和传值。子组件不能直接改变父组件的值
但是子组件可以通过其他方式改变父组件的值。可以通过触发一个自定义事件,在父组件中通过事件监听器接收到子组件传递的数据,然后修改父组件的值。
平行组件通信
子组件1先调用 emit 方法将参数传给父组件,父组件再通过 props 传递给子组件2。
Vuex
Vuex 的构成有以下几个部分:
state : Vuex 的基本数据,用来存储变量。
mutations : 提交更改数据,同步更新状态。
actions : 提交 mutations ,可异步操作。
getters :是 store 的计算属性。
modules : 模块,每个模块里面有四个属性。
工作流程:
1.在组件中,用一个 this.$store.dispath 这个方法触发 actions 提交修改数据的操作。
2.Actions 用 commit 来触发 mutations 来修改数据。
3.mutations 接收到 commit 的请求,就会自动通过 Mutate 来修改 state 里面的数据,也只有 Mutations 可以操作 state 中的状态数据,状态一改变,组件中就重新渲染。
4.最后由 store 触发每一个调用它的组件更新。
Vue2 和 Vue3 的区别
1.性能提升:Vue 3.x 在性能方面进行了大量优化,比Vue 2.x 更快,更顺畅。
2. 更好的TypeScript支持
3.Composition API:Vue 3.x 引入了 Composition API,通过使用函数而不是对象的方式来定义组件,使得代码更易于维护和测试。
4.Vue 3.x 引入了一些新功能,例如 Teleport
数据响应式原理
Vue2 的数据响应式原理是通过 Object.defineProperty() 对数据进⾏劫持并结合发布订阅模式的⽅式来实现的。
Vue3 中使⽤了 ES6 的 ProxyAPI 对数据代理,通过 reactive() 函数给每⼀个对象都包⼀层 Proxy,通过 Proxy 监听属性的变化,从⽽实现对数据的监控。
v-if 和 v-show 的区别
v-show:元素始终被渲染到 HTML,当元素不满足条件时,其样式被设置为 style=“display:none”,这种方法是通过修改元素的的 CSS 属性(display)来决定实现显示还是隐藏。
v-if:满足条件是会渲染到 HTML 中,不满足条件时是不会渲染到 HTML 中的,是通过操纵 DOM 元素来进行切换显示,所以 v-if 有更高的切换消耗。
如果是在需要频繁切换组件的场景中,使用 v-show 较好,如果在运行时条件很少改变,使用 v-if 较好。
slot(插槽)的作用
当子组件渲染该插槽时,可以讲子组件内部的数据传递给父组件,由父组件决定如何渲染该插槽。
computed(计算属性)和 watch(监听属性)的区别
-
监听的数据不同:computed 监听的是数据的计算结果,通常是多个数据的综合运算结果;而 watch 监听的是具体的数据,可以在数据变化时进行特定的操作。
-
执行时间不同: computed 支持缓存,当依赖数据发生改变,会重新进行计算。而 watch 不支持缓存,数据变化时会直接触发相应的操作。
-
是否支持异步: computed 不支持异步,当其内部有异步操作时失效,无法监听数据的变化。watch 支持异步操作。
-
是否需要return: computed 中的函数必须要用 return 返回,watch 中的函数不是必须要用 return。
-
适用场景不同:如果需要对某些数据进行复杂的计算,并将计算结果用于模板渲染,则应该使用 computed;如果需要在数据发生变化时执行特定的操作,例如发起异步请求或执行动画效果等,则应该使用 watch。
Vue 实现路由跳转的方法
1.安装 Vue Router
2.在创建VueRouter时,需要传入routes配置项
路由的 hash 模式和 history 模式的区别
- 在显示上,hash 路由会在 url 中添加 “#”,而 history 路由没有。
-
底层的实现方式不同,hash 模式是通过 onhashChange 事件监听 location.hash 来实现的。而 history 模式是通过 pushState(或者 replaceState)和监听 popState 事件实现的。pushState 可以改变 url 地址实现跳转,而且页面不会刷新
Vue 的性能优化
- 应尽量减少 data 中绑定的数据
- 避免 v-for 和 v-if 一起使用
- 在组件切换比较多的场景使用keep-alive缓存组件
- 第三方模块按需导入
用户体验
- PWA 骨架屏
- 使用缓存(本地缓存、回话缓存等)
- 开启 gzip 压缩
- 预渲染服务端渲染 SSR
- 长列表虚拟滚动
- 图片懒加载
CSS面试:
CSS 属性分为非继承属性和 继承属性,继承属性的默认值为父元素的该属性的 计算值,非继承属性和根元素的继承属性的默认值为初始值。
对于非继承属性,可以显示的声明属性值为 inherit,让子元素的属性继承父元素。
块盒子:display:block
换行
width和height生效
竖直方向padding和margin生效
内联盒子:display:inline
不换行
width和height无效
竖直方向padding和margin无效
内联块盒子:display:inline-block
不换行
width和height生效
竖直方向padding和margin生效
如何实现安卓打包:
1.依赖相关的平台和工具:可以装Android Studio,Gradle和SDK,然后
用uni-app的命令行工具打包。打包之前要做一些配置,权限配置,比如配置他
的目标版本,依赖版本,应用名称,logo之类的,还有权限,依赖的jdk版本
如何打包成app?:
(HTML5套壳、uniapp原生)
我uniapp只写了一个webview组件,把H5的应用打包之后地址放到webview里
web和原生app的通讯方式:
1.全局挂载的函数
2.JSbridge
3.schema url
TS:
是·JS的扩展,提供了更加友好的类型支持和推导,避免在代码书写过程出现不必要的
错误。
HTML5新特性:
语义化标签(Header,footer)
多媒体支持(audio,video)
地理位置
webSockets: 引入了 Web Sockets 协议,比传统HTTP请求更高效
HTTP状态码:
1xx:指示信息类,表示请求已接受,继续处理(临时响应)
2xx:指示成功类,表示请求已成功接受
3xx:指示重定向,表示要完成请求必须进行更近一步的操作
- 403 - Forbidden:客户端没有权限访问该资源。(【服务器拒绝执行客户端的请求】)
- 404 - Not Found:服务器无法找到请求的资源。
5xx:服务器在处理请求的过程中发生了错误。(服务器错误)
数组的常用方法有哪些?
join(separator):将数组的元素组起一个字符串
push():将参数添加到原数组末尾
pop():删除原数组最后一项
shift():删除原数组第一项
unshift(): 将参数添加到原数组开头
slice(start,end):可以截取出数组某部份的元素为一个新的数组 结束位置( 操作时数字减1 )
splice(start,deleteCount,val1,val2,…):从start位置开始删除deleteCount项,并从该位置起插入
fill():使用特定值填充数组中的一个或多个元素(修改原数组)
filter():过滤,数组中的每一项运行给定函数
concat():可以将两个数组合并在一起
indexOf():返回当前值在数组中第一次出现位置的索引
lastIndexOf():返回查找的字符串最后出现的位置,如果没有找到匹配字符串则返回 -1。
includes():判断一个数组是否包含指定的值
sort(orderfunction):按指定的参数对数组进行排序(修改原数组)
reverse():将数组反序(修改原数组)
forEach():循环遍历数组每一项(没有返回值)
map():循环遍历数组的每一项(有返回值)
find(): 返回第一个匹配的值,并停止查找
findIndex(): 返回第一个匹配值的索引,并停止查找
toLocaleString()、toString():将数组转换为字符串
entries() 、keys() 、values():遍历数组
CSS 选择器及优先级
-
!important
-
内联样式(1000)
-
ID选择器(0100)
-
类选择器/属性选择器/伪类选择器(0010)
async
async
是异步的意思,await
则可以理解为 async wait
。所以可以理解async
就是用来声明一个异步方法,而 await
是用来等待异步方法执行
async
函数返回一个promise
对象
async function f() {
const p = new Promise((resolve,reject)=>{
resolve(100)
})
const a = 1
// await 等待promise的状态变化完成(pending->resolved, pending->rejected)
// 取出promise的值
const b = await p
console.log(a,b)//(1,100)
}
f()
这段代码是一个异步函数 f
,它包含了一个 Promise 对象 p
和一个普通变量 a
。在代码的后半部分,使用了 await
关键字来等待 Promise 对象 p
的状态变化完成,并将其结果赋值给变量 b
,最后将 a
和 b
的值输出到控制台上。
不管await
后面跟着的是什么,await
都会阻塞后面的代码
async function fn1 (){
console.log(1)await fn2()
console.log(2) // 阻塞
}async function fn2 (){
console.log('fn2')
}fn1()
console.log(3)
CSS3 新特性
- 过渡:transition:all,.5s
- 动画:animation: logo2-line 2s linear;
- 形状转换:/transform-origin:转换元素的位置(围绕那个点进行转换)。默认(x,y,z):(50%,50%,0)
弹性布局
媒体查询
Filter(滤镜)
加密算法
对称加密:加密和解密都用相同的密钥。(DES\AES)
优缺点:效率高,算法简单,系统开销小,适合加密大量数据。安全性差。
由于RSA算法的加密解密速度要比对称算法速度慢很多,在实际应用中,通常数据本身的加密和解密使用对称加密算法(AES)。
非对称加密:采用公钥和私钥两种不同的密码来进行加解密。公钥和私钥是成对存在,公钥是从私钥中提取产生公开给所有人的,如果使用公钥对数据进行加密,那么只有对应的私钥(不能公开)才能解密,反之亦然。
DSA:数字签名算法,仅能用于签名,不能用于加解密。
DSS:数字签名标准,可用于签名,也可以用于加解密。
JS 中的 8 种数据类型及区别
Number类型:String类型:Boolean类型:
undefined类型:
只有一个值undefined,没有赋值的变量的默认值.
null类型:
不知向任何地址,手动赋值,清空内容等....
object / Symbol:
Symbol在ES6中新定义,符号类型是唯一的并且不可修改。Symbol 指的是独一无二的值。
position 属性的值有哪些及其区别
-
static
(默认值):元素按照普通文档流排列,不受top
、right
、bottom
和left
属性的影响。 -
relative
:元素按照普通文档流排列,并在原有的位置上相对移动,不脱离文档流,其他元素的位置也不会受到影响。设置top
、right
、bottom
和left
属性可以改变元素相对于其初始位置的偏移量。 -
absolute
:元素脱离文档流,不占据空间,并相对于其最近的已定位祖先元素或文档的 viewport 定位,通过设置top
、right
、bottom
和left
属性可以指定元素相对于定位父元素或 viewport 的偏移量。如果不存在已定位的祖先元素,则元素相对于文档的顶部和左侧定位。 -
fixed
:元素脱离文档流,不占据空间,并相对于文档的 viewport 定位,通过设置top
、right
、bottom
和left
属性可以指定元素相对于 viewport 的偏移量。当页面滚动时,元素的位置固定不变。 -
sticky
:元素按照普通文档流排列,不脱离文档流。随着页面滚动,当元素到达指定的位置时,它会固定在这个位置。可以通过设置top
、right
、bottom
和left
属性来指定元素吸附的位置。注意,sticky
的效果只在被设置为relative
或absolute
的父元素内生效。
GET 与 POST 的区别
1.操作不同:GET对数据进行查询,POST主要对数据进行增删改
2.Post的传输没有限制
3.Get通过URL传递,不安全。POST放在Request Body中,相对更安全
4.GET在浏览器回退时是无害的,而POST会再次提交请求
5. GET请求地址会被浏览器主动缓存,而POST不会,除非手动设置
var, cosnt, let 三者之间的区别
-
变量提升:在使用
var
声明变量时,变量会被提升至作用域顶部,因此可以在声明前访问该变量,但值为undefined
。而使用let
和const
声明的变量不会被提升,不能在声明前访问。 -
作用域:在全局作用域中使用
var
声明的变量是全局的,而使用let
和const
声明的变量是块级作用域的。块级作用域是指花括号{}
内的作用域,语句块中的变量在语句块范围内有效,语句块之外无法访问。 -
重复声明:在同一作用域内,使用
var
声明可以重复声明同一变量,后续声明会覆盖前面的声明。而使用let
和const
声明时,不能重复声明同一变量,否则会报错。 -
可变性:使用
var
和let
声明的变量的值可以被重新赋值,而使用const
声明的变量不能被重新赋值
CSS 盒子模型
CSS 盒模型本质上是一个盒子,它包括:边距,边框,填充和实际内容。
标准盒模型: 一个块的总宽度 = width+margin(左右)+padding(左右)+border(左右)
怪异盒模型: 一个块的总宽度 = width+margin(左右)(既 width 已经包含了 padding 和 border 值)
inherit:继承父元素的 box-sizing 值。
WebSocket
实现原理: 实现了客户端与服务端的双向通信,只需要连接一次,就可以相互传输数据,很适合实时通讯、数据实时更新等场景。
Websocket 协议与 HTTP 协议没有关系,它是一个建立在 TCP 协议上的全新协议,为了兼容 HTTP 握手规范,在握手阶段依然使用 HTTP 协议,握手完成之后,数据通过 TCP 通道进行传输。
Websoket 数据传输是通过 frame 形式,一个消息可以分成几个片段传输。这样大数据可以分成一些小片段进行传输,不用考虑由于数据量大导致标志位不够的情况。也可以边生成数据边传递消息,提高传输效率。
优点: 双向通信。客户端和服务端双方 都可以主动发起通讯。 没有同源限制。客户端可以与任意服务端通信,不存在跨域问题。 数据量轻。第一次连接时需要携带请求头,后面数据通信都不需要带请求头,减少了请求头的负荷。 传输效率高。因为只需要一次连接,所以数据传输效率高。