前端之公共知识点

文章探讨了前端开发中React和Vue的异同,包括数据绑定和视图处理。接着讨论了JavaScript的循环语法,数组和对象的处理,以及排序算法。提到了Webpack在前端工程化中的角色和模块化开发。此外,文章还涉及了闭包、作用域、事件总线(eventBus)的使用,以及大屏适配的多种解决方案,包括rem、分辨率缩放和百分比布局。
摘要由CSDN通过智能技术生成

公共知识点

前端面试和工作中遇到的常见问题

React和Vue 异同

vue:双向绑定,不完全的MVVM(因为vue能$ref操作dom)
react:单项绑定(一般用hooks),MVVM中的第二个V(View环节)

for 和 for in 和 for of 区别

  • for in遍历对象,返回的是对象的key;遍历数组/字符串(字符串也可以当成数组)返回的是数组的下标
  • for of 只能遍历的是数组、遍历数组对象,返回单个对象;遍历数组元素/字符串,返回单个元素for of不能遍历对象
    ES6提出的语句,在可迭代对象(Array(数组),Map(字典),Set(集合),String(字符串),
    TypedArray(一组构造函数),arguments(类似数组的全局对象))
  • 速度对比:
    for 循环在遍历值为 let 时快于 while 快于 forEach
    for in 循环速度是最慢的
    for of 比 for in快点但是没有for循环快
  • 结论
    for 循环常用且效率会高一些
    for in 用来循环对象,因为循环出来的是对象的key,用key直接操作对象
    for of 用来循环数组,循环出来的是value,元素值。不能循环对象
    各有各的用处

数组及对象 值处理(对比,排序)

  • 排序:
    const sortedColumnData = columnData.sort((a, b) => b - a);
    a-b就是升序,b-a就是降序

JavaScript的Array.sort()方法使用的是快速排序(Quick Sort)算法,它的平均时间复杂度是 O(n log n)。快速排序是一种高效的排序算法,通过分治的思想将数组分解为较小的子数组,然后对子数组进行排序并合并,以达到整体排序的目的。

然而,需要注意的是,Array.sort()方法的具体实现可能因浏览器或JavaScript引擎的不同而有所差异。在某些情况下,它可能会使用其他排序算法,如归并排序(Merge Sort)或插入排序(Insertion Sort),以优化特定情况下的性能。

  • 判断:
    (一个数组对象里面的某一个对象是否有包含某一个值)
const containsString = [{name:1,value:1},{name:2,value:2},{name:3,value:3}].some(obj =>
        Object.values(obj).some(
          value => typeof value === "string" && value.includes(1)
        )
      );
      //返回的是true或者false

前端工程化(webpack)

WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。

  1. 模块化开发:Webpack 支持使用模块化的开发方式,可以将代码拆分成多个模块,提高代码的复用性和维护性。

  2. 资源打包和优化:Webpack 可以将项目中的各种资源进行打包和优化,例如将多个 JavaScript 文件合并成一个文件,将 CSS 进行提取和压缩,处理图片和字体等。

  3. 代码转换和编译:Webpack 支持使用不同的 loader 对不同类型的文件进行处理,例如将 ES6/ES7 代码转换为 ES5,将 SCSS 转换为 CSS,对 TypeScript 进行编译等。

  4. 开发环境优化:Webpack 提供了开发服务器(DevServer)和热模块替换(Hot Module Replacement)等功能,可以实现实时预览、自动刷新和模块热更新,提高开发效率。

  5. 构建和部署:Webpack 可以通过配置多个不同的构建环境(如开发环境、生产环境),将项目打包成可部署的静态资源,减小文件体积,优化加载速度

闭包

原型,原型链,作用域

new运算符

Promise Async/Await

nextTick/setTimeOut

有两种方法,一种是JavaScript的setTimeOut方法,一种是this.$nextTick(function(){})方法。
两种的区别是setTimeOut可以设置时间后再进行渲染,this.$nextTick(function(){})可以在vue组件自动渲染后调用。

setTimeOut
//在3000毫秒后跳出弹窗

setTimeout("alert('123123123213')", 3000 )

this.$nextTick(function(){})
//在页面dom渲染完成后弹出弹窗

this.$nextTick(function () {
            this.$refs.message.success('渲染完成')
          })

插槽

最常见的el-table插槽

 <el-table-column
                  fixed="left"
                  prop="date"
                  label="产业分类"
                  align="center"
                  width="120"
                >
                  <template slot-scope="scope">
                    <div>
                      <img src="../../assets/images/tableColList1.png" alt="" />
                      <span>{{ scope.row.province }}</span>
                    </div>
                  </template>
                </el-table-column>

服务端/客户端渲染

React/Vue视图刷新问题

eventBus

直接上代码 粘就完事了

  1. utils工具类 命名bus.js 最好放在components或者utils目录下
import Vue from "vue";
const bus = new Vue();
export default bus;
  1. 加入到mian方法中(我用的是vue2)
import Bus from "./utils/bus";
Vue.prototype.$bus = Bus;
  1. 使用方法
//发消息
let _this = this;
_this.$bus.$emit("areaChangs", [参数1, 数据2]);
//收消息
let _this = this;
  this.$bus.$on("areaChangs", function(data) {
  //这个是匿名函数哦,不饿能直接用this
  _this.data= data;
  });

大屏适配解决方案

1. rem开发

方案1:整体适配
使用px2rem,自动实现px对rem的转换
npm install px2rem-loader --save-dev
在vue2下新增一个配置文件postcss.config.js

const autoprefixer = require("autoprefixer");
const pxtorem = require("postcss-pxtorem");
module.exports = () => ({
  plugins: [
    autoprefixer(),
    pxtorem({
      rootValue: 192.0,
      propList: ["*"],
      mediaQuery: false,
      unitPrecision: 3
    })
    // // autoprefixer 自动补齐 CSS3 前缀,适配不同浏览器
    // require('autoprefixer')({
    //   overrideBrowserslist: [
    //     "last 10 versions", // 所有主流浏览器最近10版本用
    //   ],
    // }),
    // require('postcss-pxtorem')({
    //   rootValue: 192.0, //设计稿元素尺寸/10,这里设计稿宽度为1920
    //   propList: ["*"], //是一个存储哪些将被转换的属性列表,这里设置为['*']全部,假设需要仅对边框进行设置,可以写['*', '!border*']
    //   unitPrecision: 3, //保留rem小数点多少位
    //   selectorBlackList: ['el-input', 'el-step', 'no-'],//则是一个对css选择器进行过滤的数组,比如你设置为['el-'],那所有el-类名里面有关px的样式将不被转换,这里也支持正则写法。
    //   replace: true,
    //   mediaQuery: false, //媒体查询( @media screen 之类的)中不生效
    //   // minPixelValue: 3, //px小于3的不会被转换
    // })
  ]
});

方案2:单页适配(门户首页,单个大屏)

//首先设置单页的fontsize大小,根据1920适配
document.documentElement.style.fontSize = document.documentElement.clientWidth / 1920 + 'px';
//然后把css文件中相关与px的内容全部改为rem就可以了
//这个方法可以解决背景图会自动拉伸的情况可以写算法动态写死背景图的宽高

2. 强制分辨率缩放(Bom始终保持一个分辨率,使用控制transform)

控制浏览器的显示,一直保持着1k,2k,4k的屏幕大小,问题是对于每个不同的分辨率都需要开发一套样式文件
控制屏幕的缩放比,当bom层面的分辨率发生变化transform:scale也跟着变化

//vue2.x
  mounted() {
    let _this = this;
    _this.setRem();
    window.onresize = function() {
      _this.setRem();
    };
  },
  methods: {
    setRem() {
      // if (!window.frameElement) {
      // 当前页面屏幕分辨率相对于 1920宽的缩放比例,可根据自己需要修改
      let w = document.documentElement.clientWidth,
        h = document.documentElement.clientHeight;
      const scale = w / h > 1920 / 1080 ? h / 1080 : w / 1920;
      document.querySelector("#mapbox").style.transform = `scale(${scale})`; 控制屏幕的缩放比
      document.querySelector("#mapbox").style[
        "transform-origin"
      ] = `center center`;
      // } else {
      //   $("#app").addClass("iframBox");
      // }
    },
  }
  //注意 上面代码是只控制倒了1k的分辨率下,如果需要适配其他的分辨率就需要判断其他的宽度
   let w = document.documentElement.clientWidth,
        h = document.documentElement.clientHeight,
   if (nameList.includes(name) && w > 6000) {
        scale = w / h > 6880 / 2000 ? h / 2000 : w / 6880;
      } else if (nameList.includes(name) && w > 3800) {
        scale = w / h > 3840 / 1290 ? h / 1290 : w / 3840;
      } else {
        scale = w / h > 1920 / 1080 ? h / 1080 : w / 1920;
      }
  //整个页面需要限制宽和高
  width: 1920px;
  height: 1080px;

3. 百分比布局

用的很少,平时只是控制单页的适配问题

动画使用和基本配置

动画
 .bodersLine {
      animation-name: likes; // 动画名称
      animation-duration: 1.5s; // 动画完成时间
      animation-timing-function: linear; // 动画执行方式,linear:匀速;ease:先慢再快后慢;ease-in:由慢速开始;ease-out:由慢速结束;ease-in-out:由慢速开始和结束;
      animation-delay: 0s; // 动画延迟时间
      animation-iteration-count: infinite; //  动画播放次数,infinite:一直播放
      // animation-direction: alternate; // 动画在奇数次(1、3、5...)正向播放,在偶数次(2、4、6...)反向播放。
    }

    @keyframes likes {
      0% {
        transform: translateY(0px)
      }
      25% {
        transform: translateY(5px)
      }
      50% {
        transform: translateY(10px)
      }
      75% {
        transform:translateY(15px)
      }
      100% {
        transform: translateY(0px)
      }
    }

项目开发公用样式及功能

1滚动条样式修改

/**设置关于el-table的滚动条*/
//滚动条长宽
::v-deep .el-table__body-wrapper::-webkit-scrollbar {
  width: 3px;
  height: 3px;
}
//滚动条样式
::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb {
  border-radius: 0px;
  background-color: rgba(0, 138, 255, 1);
}
//滚动条悬浮
::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb:hover {
  background-color: rgba(0, 138, 255, 1);
}
//滚动条背景
::v-deep .el-table__body-wrapper::-webkit-scrollbar-track {
  background-color: rgba(77, 178, 255, 0.38);
  border-radius: 0px;
}
//滚动条交合处
::v-deep .el-table__body-wrapper::-webkit-scrollbar-corner {
  // display: none;
  background-color: rgba(77, 178, 255, 0.38);
}

2. el-table样式整体修改,

  1. 去掉自有的边框,合并单元格
    在这里插入图片描述
//html代码
<div
            class="city-content"
            v-loading="loading"
            element-loading-background="rgba(24, 41, 88, 0)"
          >
            <el-table :data="tableData" style="width: 98%" max-height="250">
              <el-table-column
                prop="date"
                label="日期"
                align="center"
                width="120"
              >
              </el-table-column>
              <el-table-column label="配送信息" align="center">
                <el-table-column
                  prop="name"
                  label="姓名"
                  width="190"
                  align="center"
                >
                </el-table-column>
                <el-table-column
                  prop="name"
                  label="姓名"
                  width="190"
                  align="center"
                >
                </el-table-column>
              </el-table-column>
              <el-table-column label="配送信息" align="center">
                <el-table-column
                  prop="name"
                  label="姓名"
                  width="190"
                  align="center"
                >
                </el-table-column>
                <el-table-column
                  prop="name"
                  label="姓名"
                  width="190"
                  align="center"
                >
                </el-table-column>
              </el-table-column>
              <el-table-column label="配送信息" align="center">
                <el-table-column
                  prop="name"
                  label="姓名"
                  width="190"
                  align="center"
                >
                </el-table-column>
                <el-table-column
                  prop="name"
                  label="姓名"
                  width="190"
                  align="center"
                >
                </el-table-column>
              </el-table-column>
              <el-table-column label="配送信息" align="center">
                <el-table-column
                  prop="name"
                  label="姓名"
                  width="190"
                  align="center"
                >
                </el-table-column>
                <el-table-column
                  prop="name"
                  label="姓名"
                  width="190"
                  align="center"
                >
                </el-table-column>
              </el-table-column>
            </el-table>
      
          </div>
//css样式
.city-content {
  ::v-deep .el-table th,
  ::v-deep .el-table tr,
  ::v-deep .el-table td {
    background-color: transparent !important;
    border: 0; //去除表格
  }
  /*去除底边框*/
  ::v-deep.el-table td.el-table__cell {
    border: 0;
  }
  /* 表格内背景颜色 */
  ::v-deep .el-table thead {
    background: rgba(11, 87, 252, 0.38);
    box-shadow: inset 0 0 20px rgba(11, 87, 252, 1);
  }
  ::v-deep.el-table th.el-table__cell.is-leaf {
    border: 0;
  }
  ::v-deep .el-table--border th.gutter:last-of-type {
    border-bottom-width: 0px;
  }
  ::v-deep .no-border.el-table__header-wrapper {
    border: 0;
  }
  ::v-deep .no-border.el-table__body-wrapper {
    border: 0;
  }
  ::v-deep .el-table::before {
    background: none;
  }
  ::v-deep .el-table::after {
    background: none;
  }
  ::v-deep .el-table--border,
  .el-table--group {
    border: 0;
  }
  // ::v-deep td,
  // th {
  //   border: 1px solid rgba(141, 149, 165, 0.4);
  // }

  ::v-deep thead {
    font-size: 16px;
    font-family: Microsoft YaHei;
    font-weight: 400;
    color: #ffffff;
    tr:nth-child(1) {
      th:nth-child(1) {
        border-right: 1px solid rgba(141, 149, 165, 0.4);
      }
    }
    tr:nth-child(1) {
      th {
        border-bottom: 1px solid rgba(141, 149, 165, 0.4);
        border-right: 1px solid rgba(141, 149, 165, 0.4);
      }
      th:nth-child(1) {
        border-bottom: 0;
      }
    }
    tr:nth-child(2) {
      th:nth-child(2n) {
        border-right: 1px solid rgba(141, 149, 165, 0.4);
      }
    }
    tr {
      th {
        border-right: 0;
      }
    }
  }
  ::v-deep .el-table__row {
    font-size: 16px;
    font-family: Microsoft YaHei;
    font-weight: 400;
    color: #ffffff;
    td {
      border-top: 0;
      border-bottom: 0;
    }
    td:nth-child(2n + 1) {
      border-right: 1px solid rgba(141, 149, 165, 0.4);
    }
    // td:last-of-type {
    //   border-right: 0;
    // }
  }
}

页面元素全屏组件vue-fullscreen

  1. npm install vue-fullscreen
  2. main.js引入
    import VueFullscreen from ‘vue-fullscreen’
    Vue.use(VueFullscreen)
  3. 使用
//html
<template>
  <fullscreen
    :page-only="true"
    v-model="fullscreen"
    :exit-on-click-wrapper="false"
    fullscreen-class="big-view bg-white"
  >
    <div>放大的内容</div>
    <el-button @click="toggle"
                >{{ fullscreen ? "退出" : "进入" }}全屏</el-button
              >
  </fullscreen>
</template>
//js
export default {
  data() {
    return {
      fullscreen: false,
      BomHeights :350//因为需要设置el-table的最大高度
    }
  },
  methods: {
    toggle() {
      this.fullscreen = !this.fullscreen;
      this.BomHeights = this.fullscreen ? window.innerHeight - 50 : 350;
    },
  },
}
 
//css
.big-view {
  z-index: 999;
}

监听页面窗口大小变化

监听并给元素设置宽度

window.onresize = function() {
      _this.BomHeights = _this.fullscreen ? window.innerHeight - 50 : 350;
};

npm操作

npm 安装插件:npm install xxxx;

npm安装插件并写入package.json的"dependencies"中:npm install xxx --save

npm全局安装插件:npm install -g xxxx ;

npm删除插件 :
npm删除插件:npm uninstall xxx(同时删除package.json的"dependencies"的记录)

npm全局删除插件:npm uninstall -g xxxx

el组件遇到的问题

  1. 获取el-select选中的label值
//也是用$ref,需要注意的是双向绑定问题,注意视图第一次刷新是没有的
this.$refs.cylflSelect.selected.label
  1. 获取el-cascader选中的label值
//使用 $ref
let arr = this.$refs["cascaderHandle"].getCheckedNodes()[0].pathLabels;
      this.CitysName = arr.toString();

文件流下载

import axios from "axios";
 axios({
        url: `接口?token=${getToken()}`,
        method: "POST",
        responseType: "blob" // 设置响应类型为二进制流
      }).then(response => {
        const url = window.URL.createObjectURL(new Blob([response.data]));
        const link = document.createElement("a");
        link.href = url;
        link.setAttribute("download", "文件名.csv"); // 设置下载文件名
        document.body.appendChild(link);
        link.click();
      });

doc文件下载并预览

//第二种方案,实现较为简单,但只支持.docx .xlsx .pptx 格式的文件预览

const pptxFile = '***/file.pptx';//必须是域名 
const viewerUrl = `https://view.officeapps.live.com/op/view.aspxsrc=${encodeURIComponent(pptxFile)}`; 
window.open(viewerUrl, '_blank');
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值