1、vue3+ts如果使用props参数要使用什么函数
TypeScript
interface Search {
background : string
color : string
}
//defineProps 通过泛型参数来定义 props 的类型,给 props 设置默认值,需要使用 withDefaults 函数
const props = withDefaults(defineProps<Search>(), {
background: '#fff',
color: '#000',
})
2、vue内置的类型对象(不太清楚)
内置类型:Vue实例的生命周期钩子,指令,过滤器等。
内置对象:el、refs、attrs等
3、?.和||和??的区别
使用 ?? 时,只有第一个为 null 或者 undefined 时才会返回 第二个。
使用 || 时,第一个会先转化为布尔值判断,为true时返回第一个, false 返回第二个。
javascript
const obj = { a: { b: [{ name: 'obj' }] } }
// 原本的写法
console.log(obj && obj.a && obj.a.b.length && obj.a.b[0].name)
// 可选链写法
console.log(obj?.a?.b?.[0]?.name); // obj
console.log(obj?.b?.c?.d) // undefined
使用?. 判断的对象是null 或者 undefined,表达式就会短路,不再往后执行,返回 undefined
4、上下两个div的margin重叠怎么处理
触发 BFC:
1.浮动,float 除 none 以外的值
2.绝对定位,position(absolute,fixed)
3.display为以下其中之一,inline-block、table-cell、table-caption、 inline-flex、inline-grid等
4.overflow 除了 visible以外的值(hidden,auto,scroll)
5、BFC 是什么
BFC (块级格式化上下文),BFC 可以看作是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,从而防止出现高度塌陷的问题。
6、flex:1是什么意思
flex-grow、flex-shrink和flex-basis都为1。
flex-grow: 1 如果存在剩余空间,项目将等比例放大以占用这些空间。
flex-shrink: 1 如果空间不足,项目将等比例缩小以适应可用空间。
flex-basis: auto 这使得项目的默认大小是auto,即项目将根据内容决定大小。在使用 flex: 1
时,flex-basis
被设置为 0%
,表示初始大小为 0。
7、flex:1挤压其他元素怎么处理
被挤压的元素flex-shrink: 0;
8、reflect常见api和使用场景
api:Reflect.apply()、Reflect.construct()、Reflect.deleteProperty()等。
使用场景:
1、使用 Proxy 对象,Reflect
的方法可以使你的代码更简洁、易读。
2、在函数式编程中操作对象。
9、antd tab常见属性和方法
常见属性:
- TabPane:TabPane 是 Tab 的子组件,用于展示每个 Tab 的内容。
- activeKey:当前激活的 TabPane 的 key。
- defaultActiveKey:初始激活的 TabPane 的 key,如果没有设置 activeKey,则使用 defaultActiveKey。
- destroyInactiveTabPane:销毁未激活的 TabPane,在需要频繁切换 Tab,且每个 TabPane 内容较大时,可以设置为 true 来减少内存占用。
方法:
- onChange:切换 Tab 时触发的回调函数,参数为当前激活的 TabPane 的 key。
10、ts中any unknown never 区别
any 表示任意类型,它允许变量可以被赋予任何值,不进行类型检测。
unknown 表示未知类型,当使用 unknown 类型时,需要进行类型检查或类型断言才能将其赋值给其他类型的变量。
never 表示永远不会返回的类型,通常在函数的返回类型注解中使用 never 类型,表示该函数抛出异常、进入无限循环或者直接终止程序。
11、vue2和vue3的区别
12、vue3 hooks函数怎么写
TypeScript
export const useTheme = () => {
const test = () => {
console.log('test');
}
return { test };
}
//使用方法
import { useTheme } from "@/hooks";
const { test } = useTheme()
13、webpack loader和plugin区别
Loader 是 Webpack 中的一个核心概念,它用于处理源代码文件,将它们转换成 Webpack 可处理的模块。例如,处理 CSS 文件需要使用 css-loader,处理图片需要使用 file-loader 等。
Plugin 是用于扩展 Webpack 的功能。
14、webpack tree-shaking原理
原理:
1、ES6 模块化静态特性:ES6 模块化的特性使得模块之间的依赖关系在编译阶段就能确定,因此编译器能够在静态分析阶段识别哪些模块被实际引用,哪些模块没有被引用。
2、标记未使用代码:webpack 在对代码进行打包时,会通过静态分析标记每个模块中的导出和导入,并将未使用的模块标记为"未使用"。
3、剔除未使用代码:在标记完未使用代码后,webpack 会通过工具(如 UglifyJS)进行压缩和优化,剔除标记为未使用的代码,从而减小最终打包文件的体积。
4、依赖图优化:webpack 还会优化模块之间的依赖关系,移除没有被引用的代码路径,以进一步减少最终打包文件的大小。
15、display中的grid和flex区别
flex是一维布局 ,grid是二维布局也就是说grid布局可以更好的操作行和列。flex布局和grid布局是现在的主流的两种布局方式。
16、vue3不能使用require怎么动态引入图片
TypeScript
//方法一
import aaImg from '@/static/images/aa.png'
//然后再组件里边images标签里边使用,例如
<image class="img" :src="aaImg"></image>
//方法二 new URL('静态路径', import.meta.url).href
<img :src="aaImg">
// 导入两张图片
const aaImg = new URL('@/assets/images/aa.png', import.meta.url).href
17、强缓存和协商缓存
强缓存是指浏览器在请求资源时,先检查本地缓存是否存在该资源的副本,并且该副本是否有效。如果有效,浏览器直接从本地缓存中获取资源,不会发送请求到服务器。
强缓存策略有两种:
Expires 是HTTP/1.0协议中的字段,它告诉浏览器资源的过期时间。
Cache-Control 是HTTP/1.1协议中的字段,它可以设置多个指令来控制缓存行为。max-age 指令告诉浏览器资源的有效期,no-cache 指令告诉浏览器不使用强缓存,而是使用协商缓存。
协商缓存是指当强缓存失效时,浏览器发送请求到服务器,通过与服务器进行协商来确定是否可以使用缓存的副本。如果命中强制缓存,我们无需发起新的请求,直接使用缓存内容,如果没有命中强制缓存,如果设置了协商缓存,这个时候协商缓存就会发挥作用。
协商缓存策略有两种:
Last-Modified 是服务器响应头中的字段,它表示资源的最后修改时间。当浏览器再次请求该资源时,会携带 If-Modified-Since 字段,将资源的最后修改时间发送给服务器。如果服务器判断该资源的最后修改时间与 If-Modified-Since 字段相同,则返回 304 Not Modified 状态码,告诉浏览器可以使用缓存的副本。
ETag 是服务器响应头中的字段,它是一个唯一标识符,表示资源的版本号。当浏览器再次请求该资源时,会携带 If-None-Match 字段,将资源的 ETag 值发送给服务器。如果服务器判断该资源的 ETag 值与 If-None-Match 字段相同,则返回 304 Not Modified 状态码,告诉浏览器可以使用缓存的副本。
18、http 302和304 区别
302代表临时重定向,新的url地址可以从响应标头的Location字段获取,在地址栏可以看到输入的A地址变为B地址,不同点为301表示旧地址A的资源已经被永久移除了,302表示旧地址A的资源还存在。
状态码304:当浏览器请求未改变且已缓存的资源时,服务器会返回304状态码;告知浏览器,该资源从某个时间段之后没有改变,可以用在浏览器端缓存的资源
19、git merge 和 rebase区别
merge 是一个合并操作,会将两个分支的修改合并在一起,默认操作的情况下会提交合并中修改的内容, merge 的提交历史忠实地记录了实际发生过什么,关注点在真实的提交历史上面。
rebase 并没有进行合并操作,只是提取了当前分支的修改,将其复制在了目标分支的最新提交后面 rebase 的提交历史反映了项目过程中发生了什么,关注点在开发过程上面。
20、ref和reactive区别
-
数据类型不同:ref用于包装JavaScript基本类型的数据(如字符串、数字、布尔值等),而reactive可以用于包装JavaScript对象和数组等复杂类型的数据。
-
使用方式不同:ref需要通过在模板中使用ref指令以及在JavaScript代码中使用ref函数进行创建和使用,而reactive则需要通过调用Vue.js提供的reactive函数进行包装和创建。
-
访问方式不同:对于通过ref函数创建的响应式数据,我们可以通过.value属性来访问其实际值;而对于通过reactive函数创建的响应式对象,我们可以直接访问其属性或调用其方法。
-
设计理念不同:ref主要是为了解决单一元素/数据的响应式问题,而reactive则是为了解决JavaScript对象和数组等复杂数据结构的响应式问题。
21、watch和computed区别
- 缓存机制。`computed`属性支持缓存,只有在其依赖的数据发生变化时才会重新计算,否则会使用缓存的结果;`watch`不支持缓存,数据变化时会直接触发相应的操作。
- 异步操作。`computed`属性不支持异步操作,其计算结果基于同步代码;`watch`可以支持异步操作,适用于需要进行异步处理的数据变化。
- 使用场景。`computed`适用于从现有数据中派生出新值的情况,比如复杂的计算或过滤操作,并且适合在模板中直接使用;`watch`更适合监听特定数据的变化以执行特定的业务逻辑,比如处理用户输入或网络请求的响应。
- 性能影响。由于`computed`的缓存特性,它在多次访问相同值时可以提供更好的性能;而`watch`由于需要持续监控数据变化,可能会对性能产生更大的影响。
22、teleport和suspense区别
官方说明:在正确渲染组件之前进行一些异步请求是很常见的事。suspense允许将等待过程提升到组件树中处理,而不是在单个组件中。
进入页面,显示 Loading,3秒后,显示为 Hello,World!
TypeScript
//vue2实现
<template>
<div class="pager">
<div v-if="loading">Loading</div>
<div v-else>{{data}}</div>
</div>
</template>
<script>
export default {
data() {
return {
loading: true,
data: ''
}
},
created() {
this.load();
},
methods: {
load() {
this.loading = true;
return new Promise((resolve) => {
setTimeout(()=>{
this.data= 'Hello,World!'
this.loading = false;
resolve('hello')
}, 3000)
})
}
}
}
</script>
//vue3实现
//父组件
<script setup>
import HelloWorld from './components/HelloWorld.vue'
</script>
<template>
<suspense>
<template #default>
<HelloWorld/>
</template>
<template #fallback>
Loading
</template>
</suspense>
</template>
//子组件 - HelloWorld
<script setup>
import { ref } from 'vue';
const data = ref('');
const load = function() {
return new Promise((resolve) => {
setTimeout(()=>{
data.value = 'Hello,World!'
resolve('Hello,World!')
}, 3000)
})
}
await load();
</script>
<template>
{{data}}
</template>
官方说明:Teleport 提供了一种干净的方法,允许我们控制在 DOM 中哪个父节点下渲染了 HTML,而不必求助于全局状态或将其拆分为两个组件。
优点:添加组件的灵活性,原先由于布局、层级等原因【类似按钮和触发弹窗等】,需要拆分到不同位置【不同组件】的相关联操作,也可以更好的封装起来。
TypeScript
//vue2实现
<template>
<div class="pager">
<div class="pager__left">
<button @click="inx++">click</button>
</div>
<div class="pager__right">
{{inx}}
</div>
</div>
</template>
//vue3
//父组件
<template>
<Pager />
<teleport to=".pager__left">
<button @click="inx++">click</button>
</teleport>
<teleport to=".pager__right">
<span>{{inx}}</span>
</teleport>
</template>
//子組件 - Pager
<template>
<div class="pager">
<div class="pager__left"></div>
<div class="pager__right"></div>
</div>
</template>