2023年12月25日
一 移动端适配
1 媒体查询 @media css3中的媒体查询属性,可以为不同的屏幕尺寸编写不同的css样式。
/* <375px */ @media screen and (max-width:375px) { .box { width: 100%; } } /* >=375px and <450px */ @media screen and (min-width:375px) and (max-width:450px) { .box { width: 90%; } } /* >=450px */ @media screen and (min-width:450px) { .col{ width: 80%; } }缺点:
页面上所有的元素都得在不同的
@media
中定义一遍不同的尺寸,代价有点高。如果再多一种屏幕尺寸,就得多写一个
@media
查询块。
2 rem适配
rem
是CSS3
新增的一个相对单位,它是一个相对于页面根元素html
的font-size
的一个单位。假如设置了根元素
html
的font-size
为18px
,那么1rem
等于18px
,rem
的大小会随着根元素html
的font-size
的改变而改变。rem
方案就是利用了这一点,根据不同的屏幕尺寸,来设置不同的根元素html
的font-size
的大小,以此来达到适配不同屏幕尺寸的目的。
2-1 使用flexble
flexible
方案是阿里早期开源的一个移动端适配解决方案,引用flexible
后,我们在页面上统一使用rem
来布局。需要创建rem.js
文件:// 封装一个根据屏幕尺寸自动改变 html 的 font-size 大小的函数 const init = function () { let clientWidth = document.documentElement.clientWidth || document.body.clientWidth; // 设计图尺寸是 750px,这样 *20 之后,1rem 就等于 20px; const fontSize = (clientWidth / 750 * 20); document.documentElement.style.fontSize = fontSize + "px"; }; ? init(); ? window.addEventListener("resize", init); export default init;在
mian.js
中引入就能够使用了,需要自己手动将px
转换为rem
2-2 postcss-pxtorem 插件
3 viewport 适配
viewport
是指视窗、视口,即浏览器用来显示网页的那部分区域。
viewport
方案使用 vw/vh 作为样式单位。vw/vh 将viewport
分成了一百等份,1vw
等于视口1%
的宽度,1vh
等于视口1%
的高度。当我们的设计稿宽度是 750px 时,1vw
就等于7.5px
。3-1 设置meta标签
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes">
initial-scale
:初始缩放比例,即当浏览器第一次加载页面时的缩放比例。maximum-scale
:允许浏览者缩放到的最大比例,一般设为1.0。user-scalable
:浏览者是否可以手动缩放,yes或no。3-2 px自动转换vw
使用插件 postcss-px-to-viewport 进行相关配置,就可以帮助我们将
px
自动转化为vw
,提高开发效率。使用 npm 或 yarn 安装:
npm install postcss-px-to-viewport --save-devwebpack 配置:
module.exports = { plugins: { // ... 'postcss-px-to-viewport': { // options unitToConvert: 'px', ? ?// 需要转换的单位,默认为"px" viewportWidth: 750, ? ? // 设计稿的视窗宽度 unitPrecision: 4, ? ? ? // 单位转换后保留的精度 propList: ['*', '!font-size'], ? ? ? ?// 能转化为 vw 的属性列表 viewportUnit: 'vw', ? ? // 希望使用的视窗单位 fontViewportUnit: 'vw', // 字体使用的视窗单位 selectorBlackList: [], ?// 需要忽略的 CSS 选择器,不会转为视窗单位,使用原有的 px 等单位 minPixelValue: 1, ? ? ? // 设置最小的转换数值,如果为 1 的话,只有大于 1 的值会被转换 mediaQuery: false, ? ? ?// 媒体查询里的单位是否需要转换单位 replace: true, ? ? ? ? ?// 是否直接更换属性值,而不添加备用属性 exclude: undefined, ? ? // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件 include: /\/src\//, ? ? // 如果设置了include,那将只有匹配到的文件才会被转换 landscape: false, ? ? ? // 是否添加根据 landscapeWidth 生成的媒体查询条件 landscapeUnit: 'vw', ? ?// 横屏时使用的单位 landscapeWidth: 1125, ? // 横屏时使用的视窗宽度 }, }, };3-3 标注不需要转换的属性
在项目中,如果设计师要求某一场景不做适配,需为固定的宽高或大小,这时我们就需要利用
postcss-px-to-viewport
插件的ignoring
特性,对不需要转换的属性进行标注,如下所示:/* example input: */ .box { /* px-to-viewport-ignore-next */ width: 100px; padding: 20px; height: 100px; /* px-to-viewport-ignore */ } ? /* example output: */ .box { width: 100px; padding: 2.6667vw; height: 100px; } 复制代码
二 不设置宽高垂直居中
1.定位+margin ? 2.定位+transform ? 3.flex布局 ? 4.grid布局 ? 5.table布局
<!DOCTYPE html> <html> <head> <title>定位 + margin</title> <style> #box { position: absolute; top: 50px; left: 100px; margin: 20px; width: 200px; height: 100px; background-color: #f00; } </style> </head> <body> <div id="box"></div> </body> </html><!DOCTYPE html> <html> <head> <title>定位 + transform</title> <style> #box { position: absolute; top: 50px; left: 100px; transform: translate(200px, 150px); width: 200px; height: 100px; background-color: #f00; } </style> </head> <body> <div id="box"></div> </body> </html><!DOCTYPE html> <html> <head> <title>flex布局</title> <style> #box { display: flex; flex-direction: row; justify-content: center; align-items: center; height: 500px; background-color: #f00; } </style> </head> <body> <div id="box"></div> </body> </html><!DOCTYPE html> <html> <head> <title>grid布局</title> <style> #box { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr); grid-gap: 10px; height: 200px; background-color: #f00; } </style> </head> <body> <div id="box"></div> </body> </html><!DOCTYPE html> <html> <head> <title>table布局</title> <style> #box { display: table; height: 200px; background-color: #f00; } #box div { display: table-cell; width: 25%; height: 150px; } </style> </head> <body> <div id="box"> <div></div> <div></div> <div></div> <div></div> </div> </body> </html>
三 css属性影响元素的层级
在CSS中,有一些属性可以影响元素的层级,即元素在层叠上下文中的位置。下面是一些常见的CSS属性,它们可以影响元素的层级:
z-index
:用于设置元素的层级。具有较高z-index
值的元素将覆盖具有较低z-index
值的元素。
position
:用于设置元素的定位方式。具有position
属性的元素可以通过z-index
属性来设置层级。
transform
:用于设置元素的变换效果。具有transform
属性的元素可以创建一个新的层叠上下文,从而影响元素的层级。
opacity
:用于设置元素的透明度。具有较低透明度的元素将位于较高透明度的元素下方。需要注意的是,这些属性只会影响具有定位或变换效果的元素。对于没有定位或变换效果的元素,它们的层级将由它们在HTML文档中的位置决定。
另外,还有一些属性可以创建新的层叠上下文,从而影响元素的层级。这些属性包括:
overflow
:用于设置元素的溢出处理方式。具有overflow
属性的元素可以创建一个新的层叠上下文。
display
:用于设置元素的显示方式。具有display
属性值为flex
、grid
、table
、inline-block
等的元素可以创建一个新的层叠上下文。需要注意的是,创建新的层叠上下文并不一定会影响元素的层级。具体的影响效果还需要根据具体情况来判断。
四 清除浮动的方式
使用clearfix:
方式:在包含浮动元素的父元素上应用clearfix类,通过添加伪元素来清除浮动。
示例:
.clearfix::after { content: ""; display: table; clear: both; } .container { /* 应用clearfix类 */ overflow: auto; zoom: 1; }<div class="container clearfix"> <div class="float-left">浮动元素1</div> <div class="float-left">浮动元素2</div> </div>
使用空的块级元素:
方式:在包含浮动元素的父元素内部添加一个空的块级元素,并为其设置
clear: both
。示例:
<div class="container"> <div class="float-left">浮动元素1</div> <div class="float-left">浮动元素2</div> <div style="clear: both;"></div> </div>
使用overflow属性:
方式:在包含浮动元素的父元素上设置
overflow: auto
或overflow: hidden
。示例:
.container { overflow: auto; }<div class="container"> <div class="float-left">浮动元素1</div> <div class="float-left">浮动元素2</div> </div>
使用CSS网格布局:
方式:使用CSS网格布局来创建一个包含浮动元素的网格容器,浮动元素将自动被网格容器包裹。
示例:
.container { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); grid-gap: 10px; }<div class="container"> <div class="float-left">浮动元素1</div> <div class="float-left">浮动元素2</div> </div>这些是一些常见的清除浮动的方式和示例。
五 解决两个行内块之间的空白
在HTML中,行内块元素之间的空白是由于HTML源代码中的换行符和空格所导致的。这些空白字符会被解析为文本节点,从而在行内块元素之间产生空白间隙。下面是一些解决行内块元素之间空白的方式及其示例:
使用注释:
方式:在行内块元素之间添加注释,将注释放在换行符和空格之间。
示例:
<div class="inline-block">元素1</div><!-- --><div class="inline-block">元素2</div>
使用负的字体间距:
方式:在行内块元素的父元素上设置负的字体间距(
letter-spacing
)。示例:
.container { letter-spacing: -0.5em; }<div class="container"> <div class="inline-block">元素1</div> <div class="inline-block">元素2</div> </div>
使用浮动:
方式:将行内块元素设置为浮动元素。
示例:
.inline-block { float: left; }<div class="inline-block">元素1</div> <div class="inline-block">元素2</div>
使用flexbox布局:
方式:将行内块元素的父元素设置为flex容器,并使用
justify-content: space-between
来分散元素。示例:
.container { display: flex; justify-content: space-between; }<div class="container"> <div class="inline-block">元素1</div> <div class="inline-block">元素2</div> </div>
六 js数组常用的方法
push(): 向数组末尾添加一个或多个元素,并返回新数组的长度。
pop(): 删除并返回数组的最后一个元素。
shift(): 删除并返回数组的第一个元素。
unshift(): 向数组开头添加一个或多个元素,并返回新数组的长度。
concat(): 连接两个或多个数组,并返回新数组。
slice(): 返回一个从指定位置开始到指定位置结束的新数组,不修改原数组。
splice(): 从指定位置删除或替换元素,并返回被删除的元素组成的数组。
indexOf(): 返回指定元素在数组中第一次出现的索引,如果不存在则返回-1。
lastIndexOf(): 返回指定元素在数组中最后一次出现的索引,如果不存在则返回-1。
includes(): 判断数组是否包含指定元素,返回布尔值。
join(): 将数组的所有元素连接成一个字符串。
reverse(): 反转数组中的元素顺序。
sort(): 对数组进行排序,默认按照字符串的Unicode码点进行排序。
filter(): 根据指定条件筛选数组中的元素,返回一个新数组。
map(): 对数组中的每个元素进行操作,返回一个新数组。
reduce(): 从左到右对数组中的元素进行累积操作,返回一个值。
forEach(): 对数组中的每个元素执行指定操作,没有返回值。
every(): 检测数组中的所有元素是否满足指定条件,返回布尔值。
some(): 检测数组中是否至少有一个元素满足指定条件,返回布尔值。
find(): 返回数组中满足指定条件的第一个元素,如果不存在则返回undefined。
七 比较对象的两个键值是不是一样的最快的方法
使用严格相等运算符可以最快的比较
const obj1 = { key: 'value' }; const obj2 = { key: 'value' }; if (obj1.key === obj2.key) { console.log('键值相同'); } else { console.log('键值不同'); }
八 es6用的最多的
块级作用域(Block Scope):使用
let
和const
关键字声明变量,可以在块级作用域中定义变量,避免了变量提升和全局变量污染的问题。箭头函数(Arrow Functions):使用箭头函数语法可以更简洁地定义函数,同时还继承了父级作用域的
this
值。解构赋值(Destructuring Assignment):可以从数组或对象中提取值,并赋给对应的变量,使得代码更简洁易读。
模板字符串(Template Strings):使用反引号(`)包裹字符串,可以在字符串中插入变量或表达式,更方便地拼接字符串。
扩展运算符(Spread Operator):使用三个点(...)可以将数组或对象展开,方便地进行数组合并、复制或对象属性的拷贝。
模块化(Modules):使用
import
和export
关键字可以进行模块的导入和导出,使得代码更易于组织和维护。Promise:引入了Promise对象,用于处理异步操作,解决了回调地狱的问题,使得异步代码更易于编写和理解。
Array.from():将类数组对象或可迭代对象转换为数组。
Array.prototype.find():查找数组中符合条件的第一个元素,并返回该元素。
Array.prototype.findIndex():查找数组中符合条件的第一个元素的索引,并返回该索引。
Array.prototype.includes():判断数组中是否包含指定的元素,返回布尔值。
Object.assign():将多个对象合并为一个对象,并返回合并后的对象。
Object.keys():返回对象中所有可枚举属性的键名组成的数组。
Object.values():返回对象中所有可枚举属性的键值组成的数组。
九 说一说对promise的理解
Promise 是异步编程的一种解决方案,它是一个对象,可以获取异步操作的消息,他的出现大大改善了异步编程的困境,避免了地狱回调,它比传统的解决方案回调函数和事件更合理和更强大。所谓 Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。 (1)Promise 的实例有三个状态: Pending(进行中) Fulfilled(已完成) Rejected(已拒绝) 当把一件事情交给 promise 时,它的状态就是 Pending,任务完成了状态就变成了 Fulfilled、没有完成失败了就变成了 Rejected。 (2)Promise 的实例有两个过程: pending -> fulfilled : Resolved(已完成) pending -> rejected:Rejected(已拒绝) 注意:一旦从进行状态变成为其他状态就永远不能更改状态了。
Promise 的特点: 对象的状态不受外界影响。promise 对象代表一个异步操作,有三种状态,pending(进行中)、fulfilled(已成功)、rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态,这也是 promise 这个名字的由来——“承诺”;
一旦状态改变就不会再变,任何时候都可以得到这个结果。promise对象的状态改变,只有两种可能:从 pending 变为 fulfilled,从pending 变为 rejected。这时就称为 resolved(已定型)。如果改变已经发生了,你再对 promise 对象添加回调函数,也会立即得到这个结果。这与事件(event)完全不同,事件的特点是:如果你错过了它,再去监听是得不到结果的。
Promise 的缺点: 无法取消 Promise,一旦新建它就会立即执行,无法中途取消。如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部。当处于 pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
总结: Promise 对象是异步编程的一种解决方案,最早由社区提出。Promise是一个构造函数,接收一个函数作为参数,返回一个 Promise 实例。一个 Promise 实例有三种状态,分别是 pending、fulfilled和rejected,分别代表了进行中、已成功和已失败。实例的状态只能由pending 转变 fulfilled或者 rejected 状态,并且状态一经改变,就凝固了,无法再被改变了。状态的改变是通过 resolve() 和 reject() 函数来实现的,可以在异步操作结束后调用这两个函数改变 Promise 实例的状态,它的原型上定义了一个 then 方法,使用这个 then 方法可以为两个状态的改变注册回调函数。这个回调函数属于微任务,会在本轮事件循环的末尾执行。
注意:在构造 Promise 的时候,构造函数内部的代码是立即执行的
十?登录、token、登录的权限设置
1登录
根据自己的项目进行回答:
密码账号登录,首先需要判断用户的账号密码是否存在,不存在去到注册页面进行注册在进行登录;存在,后端进行验证返回token,并且对token进行存储(vuex、pinia等结合持久化存储工具来存储,也可以保存到本地存储)。
2 权限设置
我的项目中基本都是基于vue编写的,使用路由守卫(Route Guards)来实现登录的权限设置。
十一?vue中的路由守卫
全局守卫、路由独享守卫和组件内守卫。
全局守卫:全局守卫会在整个应用的路由切换过程中被触发。Vue Router提供了三个全局守卫函数:
beforeEach(to, from, next)
:在路由切换之前调用,可以用来进行权限验证或其他前置逻辑。
afterEach(to, from)
:在路由切换之后调用,可以用来进行一些后置操作,如页面统计等。
beforeResolve(to, from, next)
:在路由切换之前调用,与beforeEach
类似,但在导航被确认之前会被调用。
路由独享守卫:路由独享守卫只会在特定的路由配置中被触发。可以在路由配置对象中使用
beforeEnter
属性来定义路由独享守卫函数。组件内守卫:组件内守卫是在组件内部定义的路由守卫函数。
beforeRouteEnter(to, from, next)
:在路由进入组件之前调用,无法访问组件实例,可以通过回调函数访问组件实例。
beforeRouteUpdate(to, from, next)
:在当前路由复用组件时调用,例如从/user/1
切换到/user/2
。
beforeRouteLeave(to, from, next)
:在路由离开组件时调用,可以用来询问用户是否保存未保存的表单数据等。// 全局前置守卫 router.beforeEach((to, from, next) => { // 在这里进行权限验证或其他前置逻辑 if (to.meta.requiresAuth && !isAuthenticated()) { // 如果需要登录才能访问,并且用户未登录,则跳转到登录页面 next('/login'); } else { next(); // 继续导航 } }) // 路由独享守卫 const router = new VueRouter({ routes: [ { path: '/admin', component: Admin, beforeEnter: (to, from, next) => { // 在这里进行特定路由的前置逻辑 if (!isAdmin()) { // 如果不是管理员,则跳转到其他页面 next('/home'); } else { next(); // 继续导航 } } } ] }) // 组件内守卫 export default { beforeRouteEnter(to, from, next) { // 在这里进行组件内的前置逻辑 if (to.params.id === '1') { // 如果参数id为1,则跳转到其他页面 next('/home'); } else { next(); // 继续导航 } }, beforeRouteUpdate(to, from, next) { // 在这里进行组件内的前置逻辑 if (to.params.id !== from.params.id) { // 如果参数id发生变化,则跳转到其他页面 next('/home'); } else { next(); // 继续导航 } }, beforeRouteLeave(to, from, next) { // 在这里进行组件内的前置逻辑 if (hasUnsavedData()) { // 如果有未保存的数据,则弹出确认框 if (confirm('您有未保存的数据,确定要离开吗?')) { next(); // 继续导航 } else { next(false); // 取消导航 } } else { next(); // 继续导航 } } }
十二?正则规则
记一下常用的吧 手机号码验证:
function checkTelephone(telephone) { var reg=/^[1][3,4,5,7,8][0-9]{9}$/; if (!reg.test(telephone)) { return false; } else { return true; } }
十三?PDF的预览下载 图片压缩
vue项目中用相关的插件和库
PDF预览和下载:可以使用
pdf.js
库来实现PDF的预览和下载功能。pdf.js
是一个开源的JavaScript库,可以在网页上渲染和操作PDF文件。首先,你需要在Vue项目中安装
pdf.js
库。可以使用npm或yarn命令进行安装:npm install pdfjs-dist然后,在需要预览和下载PDF的组件中,你可以使用以下代码来实现:
<template> <div> <canvas ref="pdfCanvas"></canvas> <button @click="downloadPDF">下载PDF</button> </div> </template> <script> import pdfjsLib from 'pdfjs-dist' export default { mounted() { // 获取canvas元素 const canvas = this.$refs.pdfCanvas // 加载PDF文件 pdfjsLib.getDocument('/path/to/pdf/file.pdf').promise.then(pdf => { // 获取第一页 pdf.getPage(1).then(page => { const viewport = page.getViewport({ scale: 1.5 }) const context = canvas.getContext('2d') canvas.height = viewport.height canvas.width = viewport.width // 渲染PDF到canvas page.render({ canvasContext: context, viewport: viewport }) }) }) }, methods: { downloadPDF() { // 下载PDF文件 const link = document.createElement('a') link.href = '/path/to/pdf/file.pdf' link.download = 'file.pdf' link.click() } } } </script>我们首先在
mounted
钩子函数中加载PDF文件,并将第一页渲染到canvas元素中。然后,我们在downloadPDF
方法中创建一个下载链接,用户点击按钮时可以下载PDF文件。
图片压缩:可以使用
compressorjs
库来实现图片的压缩。compressorjs
是一个轻量级的JavaScript图片压缩库,可以在浏览器中压缩图片。首先,你需要在Vue项目中安装
compressorjs
库。可以使用npm或yarn命令进行安装:npm install compressorjs然后,在需要压缩图片的组件中,你可以使用以下代码来实现:
<template> <div> <input type="file" @change="compressImage"> <img :src="compressedImage" alt="压缩后的图片"> </div> </template> <script> import Compressor from 'compressorjs' export default { data() { return { compressedImage: '' } }, methods: { compressImage(event) { const file = event.target.files[0] // 使用Compressor库压缩图片 new Compressor(file, { quality: 0.6, // 压缩质量 success: result => { const reader = new FileReader() reader.onload = () => { this.compressedImage = reader.result } reader.readAsDataURL(result) }, error: error => { console.log(error.message) } }) } } } </script>在
compressImage
方法中使用Compressor
类来压缩用户选择的图片文件。压缩成功后,我们将压缩后的图片以Base64的形式显示在页面上。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!