前端学习遇到的各种小问题

对数组进行乱序
// 对数组进行乱序
function randomSort(arr: string[]) {
    let idx = arr.length;
  while (idx > 0) {
    // 生成一个随机索引
    const randomIdx = Math.floor(Math.random() * (idx -= 1));
    // 交换元素
    [arr[randomIdx], arr[idx]] = [arr[idx], arr[randomIdx]];
  }
  return arr;
}

function shuffleArray(array: string[]): string[] {
  for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
  return array;
}
初始化横屏
// 样式	
	html,
    body {
        margin: 0;
        width: 100%;
        height: 100vw;
        -webkit-transform-origin: 50vw 50vw;
        transform-origin: 50vw 50vw;
        background-color: #000;
    }
// 初始化横屏
// 利用 CSS3 旋转 对根容器逆时针旋转 90 度
var detectOrient = function() {
    var width = document.documentElement.clientWidth,
        height = document.documentElement.clientHeight,
        $wrapper = document.getElementsByTagName('body')[0],
        style = "";
    if (width >= height) { // 横屏
        style += "width:" + width + "px;"; // 注意旋转后的宽高切换
        style += "height:" + height + "px;";
        style += "-webkit-transform: rotate(0); transform: rotate(0);";
        style += "-webkit-transform-origin: 0 0;";
        style += "transform-origin: 0 0;";
        console.log(1)
    } else { // 竖屏
        style += "width:" + height + "px;";
        style += "height:" + width + "px;";
        style += "-webkit-transform: rotate(90deg); transform: rotate(90deg);";
        // 注意旋转中点的处理
        style += "-webkit-transform-origin: " + width / 2 + "px " + width / 2 + "px;";
        style += "transform-origin: " + width / 2 + "px " + width / 2 + "px;";
        console.log(2)
    }
    $wrapper.style.cssText = style;
}
window.onresize = detectOrient;

日期格式化

Date.prototype.Format = function(fmt) { //author: meizz
	var o = {
		"M+": this.getMonth() + 1, //月份
		"d+": this.getDate(), //日
		"h+": this.getHours(), //小时
		"m+": this.getMinutes(), //分
		"s+": this.getSeconds(), //秒
		"q+": Math.floor((this.getMonth() + 3) / 3), //季度
		"S": this.getMilliseconds() //毫秒
	};
	if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
	for (var k in o)
		if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : ((
			"00" + o[k]).substr(("" + o[k]).length)));
	return fmt;
}

// 格式化时间
		getDate(timestamp) {
			const date = new Date(timestamp);
			let time = '';
			let year = date.getFullYear();
			let month = date.getMonth() + 1;
			let day = date.getDate();
			let hours = date.getHours();
			let min = date.getMinutes();
			let sec = date.getSeconds();
			month = month > 9 ? month : '0' + month;
			day = day > 9 ? day : '0' + day;
			hours = hours > 9 ? hours : '0' + hours;
			min = min > 9 ? min : '0' + min;
			time = `${year}-${month}-${day} ${hours}:${min}:00`;
			return time;
		}
  • 把秒转化成时分秒
           
           //把秒转化成时分秒
           formatSeconds(value) {
				var secondTime = parseInt(value);// 秒
				var minuteTime = 0;// 分
				var hourTime = 0;// 小时
				if(secondTime > 60) {//如果秒数大于60,将秒数转换成整数
					//获取分钟,除以60取整数,得到整数分钟
					minuteTime = parseInt(secondTime / 60);
					//获取秒数,秒数取佘,得到整数秒数
					secondTime = parseInt(secondTime % 60);
					//如果分钟大于60,将分钟转换成小时
					if(minuteTime > 60) {
						//获取小时,获取分钟除以60,得到整数小时
						hourTime = parseInt(minuteTime / 60);
						//获取小时后取佘的分,获取分钟除以60取佘的分
						minuteTime = parseInt(minuteTime % 60);
					}
				}
				var result = "" + parseInt(secondTime) + "秒";
		
				if(minuteTime > 0) {
					result = "" + parseInt(minuteTime) + "分" + result;
				}
				if(hourTime > 0) {
					result = "" + parseInt(hourTime) + "小时" + result;
				}
				return result;
			},
  • 年月日时分秒 转化为 时间戳 Date.parse(“2022-11-22 10:20:43”)

### uniapp 关于video的poster视频封面不显示问题:
  • 1、controls属性必须为true(默认);

    2、poster路径必须是网络资源地址,即https;

    3、视频加载完才行(这个官方没说,所以问题就出在这里);

    4、视频获取第一帧作为封面** :poster=“item.url+‘?vframe/jpg/offset/0’”** 或者**:poster=“item.url+'?x-oss-process=video/snapshot,t_0,f_jpg”**;

uniapp在线预览文件

  • //uni.openDocument:新开页面打开文档,支持格式:doc, xls, ppt, pdf, docx, xlsx, pptx 。
    
    //注意图片预览不能用这个,其次,要预览文件必须先下载文件 uni.downloadFile 。
    
    uni.downloadFile({
      url: 'https://example.com/somefile.pdf',
      success: function (res) {
        var filePath = res.tempFilePath;
        uni.openDocument({
          filePath: filePath,
          showMenu: true,
          success: function (res) {
            console.log('打开文档成功');
          }
        });
      }
    });
    

uniapp 打包app时注意:

  • 同一个公司的多款APP使用同一份证书签名的好处
  • 应用无缝升级,不同证书需要卸载旧版本应用。
  • 应用模块化,同一份证书签名的多个应用可以运行在同一个进程里,有利于多个应用的部署模块化、插件化,这些应用可以独立升级。
  • 代码复用和数据共享。当多个APP之间调用时,系统验证权限是基于签名的。使用同一份证书,有利于多个应用之间进行安全地互操作。
  • keytool -genkey -alias 别名 -keyalg RSA -keysize 2048 -validity 36500 -keystore 别名.keystore 创建证书
  • keytool -list -v -keystore test.keystore 查看证书信息
  • 别名:test 密码123456

uniapp 打包app时出现的问题

  • 资源包配置的权限设置无法生效,需要打整包

  • 检查打包的版本号

  • 若出现打包版本不一致的情况,需要重新打整包

解决方法在配置manifest填写上

"app-plus": {  
"compatible": {  
    "ignoreVersion": true //true表示忽略版本检查提示框,HBuilderX1.9.0及以上版本支持  
},  
    
    或者

//...  
"app-plus": {  
"compatible": {  
    "runtimeVersion": "1.7.0", //根据实际情况填写  
    "compilerVersion": "1.7.1" //根据实际情况填写  
},  

"runtimeVersion"字段值表示应用兼容的uni-app运行环境版本号,可以配置多个版本号(使用英文字符,分隔)
"compilerVersion"字段值表示编译环境版本号,通常配置当前HBuilderX的版本号或cli编译器版本即可(不可以配置多个)

uniapp 状态栏字体颜色

  • ​ 在package.json中 找到相应页面 添加
"style" :{
    "navigationStyle":"custom",//样式透明
    "navigationBarTextStyle": "white" //用于配置状态栏颜色
} 

关于uview u-input在app(真机运行)上不能动态切换type的问题(显隐密码)

  • 找到组件 /uni_modules/uview-ui/components/u-input/u-input.vue 文件
  • 将password属性改为如下方式:
:password="password===undefined ? undefined : password ? true : type==='password' ? true : false"

render渲染函数&jsx详见

  • 在element 的el-table中 使用 render 函数创建 组件库 里的标签 ,必须用引号"QdImg" 括起来, 例如:
 render: (h, params) => {
     // console.log("在render()中params可以拿到单行的所有数据===>",params)
     return h('QdImg', {
         //组件的属性,(需要传入的值/props接收的)
         attrs: {
             imgList: [params.row.qrcode],
             w:"60%",
             h: "`60px",
             fit:"cover"
         }	
     	}
 	)
 },

vue 动态路由

//在路由守护方法router.beforeEach中如果有使用动态路由,注意此时的路由对当前的router无效,下次路由时才起效。

//导致的问题是---- 当页面刷新或重新打开页面时,无法找到当前路由(跳转404)

//为了解决此问题,将跳转next()改为

if (store.getters.routeList.length == 0) {
      list.push({
                path: '/404',
                component: () =>
                    import ('@/views/404'),
                hidden: true
            })
    //404路由必须放在最后
            router.addRoutes(list)
  next({...to, replace: true }) //去找目标路径
} else {
  next() //必须要有放行的出口
}

vue-router

  • this.$router.push({
      name: 'NotFound',
      // 保留当前路径并删除第一个字符,以避免目标 URL 以 `//` 开头。
      params: { pathMatch: this.$route.path.substring(1).split('/') },
      // 保留现有的查询和 hash 值,如果有的话
      query: this.$route.query,
      hash: this.$route.hash,
    })
    
  • 跳转路由打开新窗口

     let routeUrl = _this.$router.resolve({path:'/site/home',query: {projectId:pid}})
    window.open(routeUrl.href, '_blank')
    
  • 路由表是闭包维护的,可以通过chrome的console找到

  • 查看路由列表 包含动态路由和静态路由,直接打印router实例
    在这里插入图片描述

promise的用法

  1. this.userInfo = await new Promise((resolve,reject)=>{
    					userApi.getUserInfo()?resolve(userApi.getUserInfo()):reject()
    				 }).then(res=>{
    				 	return res.data
    				 },
    				 rej=>{
    				 	console.log(rej)
    				 })
    				
    
  2. this.userInfo = (await userApi.getUserInfo()).data

  3. userApi.getUserInfo().then(res=>{this.userInfo = res.data; })

  4. const list = Promise.all([userApi.getUserInfo()])
    this.userInfo = list[0].data
    

vue中<component></component>引入页面组件

<transition name="transition_router">
			<component v-bind:is="component" 				class="component"></component>
</transition>
//引入页面组件
let path = require('path')
let files = require.context('@/views/shushuoly', false, /\.vue$/)
let components = {}
files.keys().forEach(key => {
	let name = path.basename(key, '.vue')
	components[name] = files(key).default || files(key)
})

//-------------------
const componentFiles = require.context('./组件文件夹', true, /\index.vue$/)

const components = componentFiles.keys().reduce((files, filePath) => {
  const fileName = filePath.replace(/^\.\/(.*)\/index\.\w+$/, '$1')
  const value = componentFiles(filePath)
  files[fileName] = value.default
  return files
}, {})

//可以直接注册到组件中,组件名和文件夹名称一样
console.log(components)


其他

1.data-set 自动把字符串转数字

返回数据为string,通过data-name绑定到行内,然后再次从行内取值 $(‘.dom’).data(‘name’)会转换成number类型,

data-Xxx 会自动把Xxx转成小写

2.使用$nextTick获取更新后的DOM

使用场景:

  1. 在Vue生命周期的 created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中。

  2. 在数据变化后要执行的某个操作,例如数据变化后立刻操作DOM

3.js为什么需要放在body

1.浏览器的渲染引擎和js解析引擎的冲突,

2.js是单线程执行也没问题,

**4.js如何执行(even Loop(事件循环/事件轮询)/宏任务、微任务,事件队列,promise,async/await)? **
  1. 宏任务: setTimeout、setInterval、ajax、DOM事件
  2. 微任务: promise 、async/await
  3. 微任务执行时机要比宏任务早
  4. 宏任务和微任务的区别?
  5. 宏任务: DOM渲染后触发, 如setTimeout
  6. 微任务: DOM渲染前触发, 如promise
  7. 从event loop解释,为何微任务执行更早: 微任务是es6语法规定,而宏任务是由浏览器规定
5.操作DOM为什么是昂贵的?

操作DOM对象时,会触发浏览器的布局(layout) 和 绘制(paint) 行为,这两个罪魁祸首会导致DOM卡慢,占用内存较高等,从而影响用户体验。

浏览器渲染引擎工作流程
  1. 创建DOM树 HTML分析器,分析HTML元素,构建一颗DOM树
  2. 创建StyleRules CSS分析器,分析CSS文件,构建Rules树
  3. 创建Render树 将DOM树和Rules树关联起来,构建一颗Render树
  4. 布局Layout 分析布局信息,计算坐标位置
  5. 绘制Painting 开始绘制
6.什么是BFC
1.BFC的概念
Block Formatting Context 块级格式上下文,它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。

BFC是一个独立的布局环境,我们可以理解为一个箱子(实际上是看不见摸不着的),箱子内部的元素无论如何翻江倒海,都不会影响到外部。转换为BFC的理解则是:BFC中的元素的布局是不受外界的影响(我们往往利用这个特性来消除浮动元素对其非浮动的兄弟元素和其子元素带来的影响。)并且在一个BFC中,块盒与行盒(行盒由一行中所有的内联元素所组成)都会垂直的沿着其父元素的边框排列。
2 .BFC布局规则
1.  在BFC下,内部的Box会在垂直方向,一个接一个地放置。
    2.  Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box    的margin会发生重叠
    3.  在BFC中,每一个盒子的左外边缘(margin-left)会触碰到容器的左边缘(border-left)(对于从右到左的格式来说,则触碰到右边缘),即使存在浮动也是如此。
    4.  BFC的区域不会与float box重叠。
    5.  计算BFC的高度时,浮动元素也参与计算
7. 从输入URL到页面展示发生了什么
  1. 浏览器主进程提交url给网络进程
  2. 网络进程请求服务器,返回响应头行体,判断是否需要重定向
  3. 网络进程将页面类型的响应资源提交给渲染进程
  4. 渲染进程渲染结束,加载完毕

分步骤简单说一下就是:

  1. 首先是域名解析
  2. 建立TCP链接
  3. 建立Http请求
  4. 服务器处理Http请求
  5. 关闭TCP连接
  6. 浏览器解析资源
  7. 浏览器渲染页面
8.clear:both;可以清除浮动(前两个div必须都有float)
overflow:hidden;

也可以清除浮动,假如第一个浮动,给第二个div加overflow:hidden;

工具

1.关于 git
  1. 初始化本地仓库 git init

  2. 所有文件暂存到 本地 git add .

  3. 关联远程仓库 git remote add origin http://xxxxxx.git

  4. 查看远程仓库 git remote -v

  5. 查看状态 git status

  6. 提交新的子分支 git push -u origin 子分支

    注意 (第一次需要加 -u)

  7. 新建分支与合并

    ​ (1).创建子分支 git checkout -b 子分支名

    ​ 创建后 默认到子分支(注意查看当前分支 git branch)

    ​ (2).切换到 主分支 git checkout master

    ​ (3).合并子分支到主分支 git merge 子分支

    ​ (4).提交到远程仓库 git push

    8.两个分支没有取得关系,版本不同

    错误: fatal: refusing to merge unrelated histories

    git pull origin master --allow-unrelated-histories

关于layui

表格的on监听事件是跟着lay-filter的,

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
u-avatar-cropper是一个头像裁剪组件,它是在Vue框架下使用的。可以通过安装vue-avatar-cropper插件来使用它,安装命令为npm i vue-avatar-cropper。在使用时,可以在代码中添加<button>标签来选择图片,然后使用<avatar-cropper>标签来展示头像裁剪功能。当图片上传完成后,可以通过监听@uploaded事件来处理上传后的结果。 此外,也可以使用u-View组件库中的AvatarCropper来实现头像裁剪功能。具体使用方法详细介绍在u-View官网上,可以访问 https://www.uviewui.com/components/avatarCropper.html 来查看详细的使用说明。 如果要在项目中使用u-avatar-cropper组件,还需要在page.json文件中引入u-avatar-cropper的路径,并在style字段中设置导航栏标题和背景颜色等样式。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [vue-avatar-cropper:一个简单而优雅的头像裁剪和上传插件](https://download.csdn.net/download/weixin_42132359/15108564)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [微信小程序AvatarCropper 头像裁剪](https://blog.csdn.net/qq_30136729/article/details/119932010)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [#uni-app# u-avatar-cropper实现选择图片裁剪,设置用户头像uview (附源码)](https://blog.csdn.net/ZHENGCHUNJUN/article/details/120764543)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值