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%;
}
}

缺点:

  1. 页面上所有的元素都得在不同的 @media 中定义一遍不同的尺寸,代价有点高。

  2. 如果再多一种屏幕尺寸,就得多写一个 @media 查询块。

2 rem适配

remCSS3 新增的一个相对单位,它是一个相对于页面根元素 htmlfont-size 的一个单位。

假如设置了根元素 htmlfont-size18px,那么 1rem 等于 18pxrem 的大小会随着根元素 htmlfont-size 的改变而改变。rem 方案就是利用了这一点,根据不同的屏幕尺寸,来设置不同的根元素 htmlfont-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-dev

webpack 配置:

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属性,它们可以影响元素的层级:

  1. z-index:用于设置元素的层级。具有较高z-index值的元素将覆盖具有较低z-index值的元素。

  2. position:用于设置元素的定位方式。具有position属性的元素可以通过z-index属性来设置层级。

  3. transform:用于设置元素的变换效果。具有transform属性的元素可以创建一个新的层叠上下文,从而影响元素的层级。

  4. opacity:用于设置元素的透明度。具有较低透明度的元素将位于较高透明度的元素下方。

需要注意的是,这些属性只会影响具有定位或变换效果的元素。对于没有定位或变换效果的元素,它们的层级将由它们在HTML文档中的位置决定。

另外,还有一些属性可以创建新的层叠上下文,从而影响元素的层级。这些属性包括:

  1. overflow:用于设置元素的溢出处理方式。具有overflow属性的元素可以创建一个新的层叠上下文。

  2. display:用于设置元素的显示方式。具有display属性值为flexgridtableinline-block等的元素可以创建一个新的层叠上下文。

需要注意的是,创建新的层叠上下文并不一定会影响元素的层级。具体的影响效果还需要根据具体情况来判断。

四 清除浮动的方式
  1. 使用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>
  1. 使用空的块级元素:

  • 方式:在包含浮动元素的父元素内部添加一个空的块级元素,并为其设置clear: both

  • 示例:

     <div class="container">
      <div class="float-left">浮动元素1</div>
      <div class="float-left">浮动元素2</div>
      <div style="clear: both;"></div>
    </div>
  1. 使用overflow属性:

  • 方式:在包含浮动元素的父元素上设置overflow: autooverflow: hidden

  • 示例:

    .container {
      overflow: auto;
    }
    <div class="container">
      <div class="float-left">浮动元素1</div>
      <div class="float-left">浮动元素2</div>
    </div>
  1. 使用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源代码中的换行符和空格所导致的。这些空白字符会被解析为文本节点,从而在行内块元素之间产生空白间隙。下面是一些解决行内块元素之间空白的方式及其示例:

  1. 使用注释:

  • 方式:在行内块元素之间添加注释,将注释放在换行符和空格之间。

  • 示例:

    <div class="inline-block">元素1</div><!--
    --><div class="inline-block">元素2</div>
  1. 使用负的字体间距:

  • 方式:在行内块元素的父元素上设置负的字体间距(letter-spacing)。

  • 示例:

    .container {
      letter-spacing: -0.5em;
    }
    <div class="container">
      <div class="inline-block">元素1</div>
      <div class="inline-block">元素2</div>
    </div>
  1. 使用浮动:

  • 方式:将行内块元素设置为浮动元素。

  • 示例:

    .inline-block {
      float: left;
    }
    <div class="inline-block">元素1</div>
    <div class="inline-block">元素2</div>
  1. 使用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数组常用的方法
  1. push(): 向数组末尾添加一个或多个元素,并返回新数组的长度。

  2. pop(): 删除并返回数组的最后一个元素。

  3. shift(): 删除并返回数组的第一个元素。

  4. unshift(): 向数组开头添加一个或多个元素,并返回新数组的长度。

  5. concat(): 连接两个或多个数组,并返回新数组。

  6. slice(): 返回一个从指定位置开始到指定位置结束的新数组,不修改原数组。

  7. splice(): 从指定位置删除或替换元素,并返回被删除的元素组成的数组。

  8. indexOf(): 返回指定元素在数组中第一次出现的索引,如果不存在则返回-1。

  9. lastIndexOf(): 返回指定元素在数组中最后一次出现的索引,如果不存在则返回-1。

  10. includes(): 判断数组是否包含指定元素,返回布尔值。

  11. join(): 将数组的所有元素连接成一个字符串。

  12. reverse(): 反转数组中的元素顺序。

  13. sort(): 对数组进行排序,默认按照字符串的Unicode码点进行排序。

  14. filter(): 根据指定条件筛选数组中的元素,返回一个新数组。

  15. map(): 对数组中的每个元素进行操作,返回一个新数组。

  16. reduce(): 从左到右对数组中的元素进行累积操作,返回一个值。

  17. forEach(): 对数组中的每个元素执行指定操作,没有返回值。

  18. every(): 检测数组中的所有元素是否满足指定条件,返回布尔值。

  19. some(): 检测数组中是否至少有一个元素满足指定条件,返回布尔值。

  20. find(): 返回数组中满足指定条件的第一个元素,如果不存在则返回undefined。

七 比较对象的两个键值是不是一样的最快的方法

使用严格相等运算符可以最快的比较

const obj1 = { key: 'value' };
const obj2 = { key: 'value' };

if (obj1.key === obj2.key) {
console.log('键值相同');
} else {
console.log('键值不同');
}
八 es6用的最多的
  1. 块级作用域(Block Scope):使用letconst关键字声明变量,可以在块级作用域中定义变量,避免了变量提升和全局变量污染的问题。

  2. 箭头函数(Arrow Functions):使用箭头函数语法可以更简洁地定义函数,同时还继承了父级作用域的this值。

  3. 解构赋值(Destructuring Assignment):可以从数组或对象中提取值,并赋给对应的变量,使得代码更简洁易读。

  4. 模板字符串(Template Strings):使用反引号(`)包裹字符串,可以在字符串中插入变量或表达式,更方便地拼接字符串。

  5. 扩展运算符(Spread Operator):使用三个点(...)可以将数组或对象展开,方便地进行数组合并、复制或对象属性的拷贝。

  6. 模块化(Modules):使用importexport关键字可以进行模块的导入和导出,使得代码更易于组织和维护。

  7. Promise:引入了Promise对象,用于处理异步操作,解决了回调地狱的问题,使得异步代码更易于编写和理解。

  8. Array.from():将类数组对象或可迭代对象转换为数组。

  9. Array.prototype.find():查找数组中符合条件的第一个元素,并返回该元素。

  10. Array.prototype.findIndex():查找数组中符合条件的第一个元素的索引,并返回该索引。

  11. Array.prototype.includes():判断数组中是否包含指定的元素,返回布尔值。

  12. Object.assign():将多个对象合并为一个对象,并返回合并后的对象。

  13. Object.keys():返回对象中所有可枚举属性的键名组成的数组。

  14. 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中的路由守卫

全局守卫、路由独享守卫和组件内守卫。

  1. 全局守卫:全局守卫会在整个应用的路由切换过程中被触发。Vue Router提供了三个全局守卫函数:

  • beforeEach(to, from, next):在路由切换之前调用,可以用来进行权限验证或其他前置逻辑。

  • afterEach(to, from):在路由切换之后调用,可以用来进行一些后置操作,如页面统计等。

  • beforeResolve(to, from, next):在路由切换之前调用,与beforeEach类似,但在导航被确认之前会被调用。

  1. 路由独享守卫:路由独享守卫只会在特定的路由配置中被触发。可以在路由配置对象中使用beforeEnter属性来定义路由独享守卫函数。

  2. 组件内守卫:组件内守卫是在组件内部定义的路由守卫函数。

  • 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的形式显示在页面上。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱猪头的程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值