1.深拷贝和浅拷贝
设想一个场景,需要把pinia里的json对象a赋值给变量b,b=a;这时对b进行遍历,遍历完后发现变量a的值也跟着变化了。原因是对b的赋值是浅拷贝,地址还是指向变量a,浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。所以这时就要用到深拷贝,深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象,是“值”而不是“引用”。用法也很简单只需要b=json.parse(json.stringfy(a))
2.监听pinia里变量的方法和区别
监听可以用订阅$subscribe,也可以用监听watch。区别是当用$patch改变pinia里的数据时,无论值改没改变,$subscribe都能监听到。而watch只能是当值改变以后才能监听到
3.异步如何转同步
当一个api是异步的时候,我们需要先得到异步的结果再往下执行代码。这时promise 就发挥了作用。可以定义一个函数
a(){
return new Promise((resolve,reject)=>{
//api
//成功以后把结果抛出去resolve(res)
})
}
然后在原代码的函数前加上async,在函数a()前加上await
async b(){
await a()
//.........
}
Promise.reject(err)
const p = Promise.reject('出错了');
// 等同于
const p = new Promise((resolve, reject) => reject('出错了'))
4.闭包,防抖和节流
闭包:当内部函数引用外部函数的内部变量,那么这个内部函数和外部函数的内部变量就形成一个闭包。
防抖适用场景,输入框,避免输入一个字就发送一次请求。节流使用场景,避免点击按钮一次就执行一次请求。解决办法,加上定时器setTimeout。还需要一个变量记录状态,如果正在请求就给个状态true,请求结束就把状态改成false。以此来节流
5.原型和原型链
每个函数都有prototype属性,叫原型,其值是一个对象,叫原型对象
每个对象都有_proto_属性,指向这个对象的原型对象,而原型对象也是一个对象,也有_proto_属性,指向原型对象的原型对象,这样一层一层的往上找的链式结构叫原型链,找不到属性方法就返回null
6.data为什么是函数而不是一个对象
每个组件都是vue的实例,组件共享data属性,组件复用的时候,如果是对象,改变其中一个会影响其它。
7.vue3 中 isRef, unref, toRef, toRefs, toRaw
isRef 判断是不是ref
unref 返回原数据,不是ref就返回其值,只针对ref
toRef, toRefs, toRaw 只针对reactive
8.插槽
默认插槽
//组件child
<div>
<slot></slot>
</div
//父组件
<div>
<child>哈哈哈</child>
</div
具名插槽
//子组件child
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
//父组件child
<child>
<template #header></template> //v-slot:header = #header
<template #default>
<p>A paragraph for the main content.</p>
</template>
//隐式的默认插槽 可以直接写 <p>A paragraph for the main content.</p>
<template #footer></template>
</child>
作用域插槽:使得父组件可以访问子组件的数据
//子组件child
<div>
<header>
<slot name="header" :text='greetingMessage' ></slot>
</header>
<main>
<slot :count='1' text='你好'></slot>
</main>
<footer>
<slot name="footer" :count='1' text='你好'></slot>
</footer>
</div>
<script>
data() {
return {
greetingMessage:'你好'
}
},
</script>
//父组件
<child>
<template #header="headerProps">
{{ headerProps}}
</template>
<template #default="defaultProps">
{{ defaultProps.text}}
</template>
<template #footer="{count,text}">
{{ count}}
</template>
</child>
9.watch和watcheffect的区别
watch
- 只有数据变化的时候才会执行,想要立即执行,就添加第三个参数 immediate: true
- 参数可以拿到当前值和原始值
- 需要传递要侦听的内容
- 可以侦听多个数据的变化,用一个侦听起承载
watchEffect
- 立即执行,页面的首次加载就会执行。
- 没有过多的参数,只有一个回调函数
- 不需要传递要侦听的内容,会自动感知代码依赖
- 无法获取到原值,只能得到变化后的值
- 异步的操作放在这里会更加合适
10.计算属性和监听器的区别
计算属性返回一个值,有缓存,如果依赖值不变直接读缓存的值,依赖值改变则重新计算。监听可以做逻辑代码
11.provide 和 inject
简单理解,类似于事件总线,组件间的通信,组件a provide一个值,组件b injiect 一个值
12.无感刷新
当token过期,后端返回401,于是拦截调用刷新token的接口,获取到新的token然后覆盖缓存,再把失败的config再执行一遍。从而达到无感刷新
13.vue双向绑定
通过object.defineproprety()来劫持各个属性的的getter,setter,触发监听回调
14.盒子模型:标准盒子模型,IE盒子模型
IE盒子模型中,宽高包含边框和padding
15.js/ts基本类型
概述
JavaScript 语言(注意,不是 TypeScript)将值分成 8 种类型。
- boolean
- string
- number
- bigint
- symbol
- object
- undefined
- null