首页
友链
导航
影视
壁纸
统计
留言板
Search
1
el-upload自定义触发按钮及触发上传前判断
826 阅读
2
vue配置二级目录以及nginx多网站部署
698 阅读
3
el-cascader选择任意一级搭配懒加载使用,单选框radio不会触发懒加载
574 阅读
4
joe主题自定义导航页面
502 阅读
5
js获取昨天今天明天日期
471 阅读
web前端
vue
react
javascript
nuxt
typescript
indexDB数据库
微信小程序
美文欣赏
心情随笔
技术分享
其他
PHP
nodejs
博客api实战项目
typecho
登录
Search
标签搜索
web
vue
node项目实战
js
javascript
typecho
css
vuex
router
nginx
git
element
joe
utils
leaflet
dateFormat
map
date
axios
reg
辰漪
累计撰写
66
篇文章
累计收到
122
条评论
首页
栏目
web前端
vue
react
javascript
nuxt
typescript
indexDB数据库
微信小程序
美文欣赏
心情随笔
技术分享
其他
PHP
nodejs
博客api实战项目
typecho
页面
友链
导航
影视
壁纸
统计
留言板
搜索到
66
篇与
辰漪
的结果
2022-09-11
joi校验中文文档
介绍joi允许您使用简单、直观和可读的语言描述数据。示例const Joi = require('joi'); const schema = Joi.object({ username: Joi.string() .alphanum() .min(3) .max(30) .required(), password: Joi.string() .pattern(new RegExp('^[a-zA-Z0-9]{3,30}$')), repeat_password: Joi.ref('password'), access_token: [ Joi.string(), Joi.number() ], birth_year: Joi.number() .integer() .min(1900) .max(2013), email: Joi.string() .email({ minDomainSegments: 2, tlds: { allow: ['com', 'net'] } }) }) .with('username', 'birth_year') .xor('password', 'access_token') .with('password', 'repeat_password'); schema.validate({ username: 'abc', birth_year: 1994 }); // -> { value: { username: 'abc', birth_year: 1994 } } schema.validate({}); // -> { value: {}, error: '"username" is required' } // Also - try { const value = await schema.validateAsync({ username: 'abc', birth_year: 1994 }); } catch (err) { }上述模式定义了以下约束:username一个必填字符串只能包含字母数字字符至少3个字符长,但不超过30个字符必须有birth_year字段password字符串必须满足自定义正则表达式模式不能与access_token字段一起出现必须带有repeat_password并与之相等access_token无约束字符串或数字birth_year1900和2013之间的整数email有效的电子邮件地址字符串必须有两个域部分,例如example.comTLD必须是.com或.net一般用法使用过程分为两步:首先,使用提供的类型和约束构造模式:const schema = Joi.object({ a: Joi.string() });请注意,joi模式对象是不可变的,这意味着添加的每个附加规则(例如,.min(5))将返回一个新的模式对象。其次,根据定义的模式验证该值:const { error, value } = schema.validate({ a: 'a string' });如果输入有效,则错误error将未定义。如果输入无效,错误error将被分配一个ValidationError对象,以提供更多信息。模式可以是一个简单的JavaScript对象,其中每个键都被分配了一个joi类型,也可以是直接的joi类型:const schema = Joi.string().min(10);如果模式是joi类型,则该模式,可以直接在类型上调用validate(value)。传递非类型模式对象时,模块将其内部转换为object()类型,等效于:const schema = Joi.object().keys({ a: Joi.string() });验证schema对象时:默认情况下,值(或对象的键)是可选的。Joi.string().validate(undefined); // validates fine要禁止此行为,您可以将schema设置为required(),或者在传递选项时将presence设置为“required”:Joi.string().required().validate(undefined); // or Joi.string().validate(undefined, /* options */ { presence: "required" });默认情况下,字符串是utf-8编码的。规则以相加的方式定义,并按顺序求值,首先是包含规则,然后是独占规则。assert()assert(value, schema, [message], [options]) 根据schema验证值,如果验证失败,则抛出,其中:value-要验证的值。schema-验证模式。可以是joi类型的对象,也可以是使用joi为每个键指定joi类型对象的普通对象。编译(注意重复编译相同模式的成本)。message-在错误消息前面添加的可选消息字符串前缀。也可以是错误对象。options-可选选项对象,传入any.validateJoi.assert('x', Joi.number());attempt()attempt(value, schema, [message], [options]) 根据schema验证值,返回有效对象,并在验证失败时抛出,其中:value-要验证的值。schema-验证模式。可以是joi类型的对象,也可以是使用joi为每个键指定joi类型对象的普通对象。编译(注意重复编译相同模式的成本)。message-在错误消息前面添加的可选消息字符串前缀。也可以是错误对象。options-可选选项对象,传入any.validateJoi.attempt('x', Joi.number()); // throws error const result = Joi.attempt('4', Joi.number()); // result -> 4 cache.provision() cache.provision([options])提供用于缓存简单输入(未定义、空、字符串、数字和布尔)的简单LRU缓存,其中:options-可选设置:max-删除最少使用的项之前要存储在缓存中的项数。默认为1000checkPreferences()checkPreferences(prefs) 检查提供的首选项是否有效,其中:prefs-要验证的首选项对象。如果prefs对象无效,则引发异常。提供该方法以执行any.validate()和any.validateAsync()方法。由于性能原因,不会自动执行验证。相反,手动验证一次传递的首选项并重新使用。compile()compile(schema, [options]) 将文字模式定义转换为joi模式对象(如果已为joi架构对象,则将其返回),其中:schema-要编译的架构定义。options-可选设置:legacy-如果为true,并且提供的架构(或包含部分)使用较旧版本的joi,则将返回与较旧版本兼容的已编译架构。如果为false,则始终使用当前版本编译架构,如果找到较旧的架构组件,则会引发错误。const definition = ['key', 5, { a: true, b: [/^a/, 'boom'] }]; const schema = Joi.compile(definition); // Same as: const schema = Joi.alternatives().try( Joi.string().valid('key'), Joi.number().valid(5), Joi.object({ a: Joi.boolean().valid(true), b: Joi.alternatives().try( Joi.string().pattern(/^a/), Joi.string().valid('boom') ) }) );defaults()defaults(modifier) 创建一个新的joi实例,将提供的修饰符函数应用于每个新模式,其中:modifier-具有签名函数(模式)的函数,必须返回模式对象。const custom = Joi.defaults((schema) => { switch (schema.type) { case 'string': return schema.allow(''); case 'object': return schema.min(1); default: return schema; } }); const schema = custom.object(); // Returns Joi.object().min(1)expression(template, [options]) - aliases: x使用模板字符串生成动态表达式,其中:template-使用模板语法的模板字符串。options-创建内部引用时使用的可选设置。支持与ref()相同的选项。模板语法模板语法使用{}和{{}}封闭公式来引用值,并执行数字和字符串操作。单大括号{}保持公式结果不变,而双大括号{{}}HTML转义公式结果(除非模板用于错误消息且errors.escapeHtml首选项标志设置为false)。如果公式是前缀为:(例如,{:#ref}或{{:#ref}}的单个引用,则其值将根据包装验证设置包装。#label变量始终根据wrap设置包装。公式使用简单的数学语法,如a+b*2,其中命名的公式变量是引用。大多数引用可以按原样使用,但有些引用可能会造成公式语法的歧义,必须用[]大括号括起来(例如[.])。公式只能对空、布尔、数字和字符串进行运算。如果任何操作涉及字符串,所有其他数字将被转换为字符串(因为内部实现使用简单的JavaScript运算符)。支持的运算符有:^、*、/、%、+、-、<、<=、>、>=、==、!=、&&、||和??(按优先顺序)。引用名称可以具有以下前缀之一:# - 表示变量引用本地上下文值。例如,在错误中,这是错误上下文,而在重命名操作中,它是正则表达式匹配组。$ - 指示变量引用上下文首选项对象中的全局上下文值,该对象作为验证函数的选项提供,或使用any.prefs()设置。任何其他变量引用正在验证的当前值中的键。公式语法还支持内置函数:if(condition, then, otherwise) - 当condition条件为真时返回then,否则返回otherwise。length(item) - 返回数组或字符串的长度,对象的键数,否则为null。msg(code) - 嵌入另一个错误代码消息。number(value) - 将值转换为数字。以及以下常数:nulltruefalse
2022年09月11日
392 阅读
0 评论
1 点赞
2022-05-26
js防抖和节流
防抖和节流防抖:在给定时间内没有再次触发,该函数才会执行。节流:先执行一次,在给定时间内该函数不会被再次触发。js两种定时器setTimeOut:该定时器n秒后执行一次函数,只会执行一次。setInterVal:该定时器n秒执行一次函数,循环多次执行。call、apply、bind共同点: call、apply、bind都可以改变this的指向,第一个参数都是this的指向。异同点:call 第二个参数及其以后的参数都是想要传递的参数,他传递的是一个参数列表 例如:fn.call(this, 1,2,3),函数会立即执行。apply 第二个参数传递的是一个参数数组 例如:fn.apply(this, [1,2,3]),函数立即执行。bind 第二个参数及其以后的参数都是想要传递的参数,他传递的是一个参数列表 例如:fn.bind(this, 1,2,3), 会返回一个函数,需要接收并且手动调用。防抖函数和节流函数{tabs}{tabs-pane label="防抖"}// 防抖函数 function debounce(fn, wait) { let timer = null // console.log(this, '1'); // this => window return function () { const e = arguments[0] // arguments[0] => input事件对象 // console.log(this, '2'); // this => input timer && clearTimeout(timer) timer = setTimeout(() => { fn.call(this, e) // 调用fn 并传递input事件对象e }, wait); } }{/tabs-pane}{tabs-pane label="节流"}// 节流函数 function throttle(fn, wait) { let timer = null return function() { const args = arguments if (!timer) { fn.apply(this, args) timer = setTimeout(() => { timer && clearTimeout(timer) timer = null }, wait) } } }{/tabs-pane}{/tabs}小案例测试<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>js防抖和节流</title> </head> <body> <input type="text" id="inp1"> <input type="text" id="inp2"> <script> const $ = function (selector) { return document.querySelector(selector) } // 测试防抖-给定时间里内没有再次触发才会执行 $('#inp1').addEventListener('input', debounce(function (e) { console.log(this, '3'); // this => input console.log(e, '事件对象'); console.log(e.target.value) }, 1000)) // 测试节流-先执行一次 再次执行需要等到时间超过给定时间才会执行 $('#inp2').addEventListener('input', throttle(function (e) { console.log(this, '3'); // this => input console.log(e, '事件对象'); console.log(e.target.value) }, 1000)) </script> </body> </html>
2022年05月26日
130 阅读
2 评论
0 点赞
2022-05-12
js截取字符串长度,添加省略号(...)
{callout color="#f0ad4e"}js处理字符串长度,长度超出,使用‘...’代替超出部分{/callout}/** * @description 根据长度截取先使用字符串,追加… * @param {string} str 对象字符串 * @param {string} len 目标字节长度 * @returns {string} 处理好的字符串 */ export function cutString(str, len = 13) { if (!str) return '' //length属性读出来的汉字长度为1 if(str.length*2 <= len) return str var strlen = 0 var s = "" for(var i = 0;i < str.length; i++) { s = s + str.charAt(i) if (str.charCodeAt(i) > 128) { strlen = strlen + 2 if(strlen >= len){ return s.substring(0,s.length-1) + "..." } } else { strlen = strlen + 1 if(strlen >= len){ return s.substring(0,s.length-2) + "..." } } } return s; }
2022年05月12日
240 阅读
2 评论
0 点赞
2022-05-06
el-cascader选择任意一级搭配懒加载使用,单选框radio不会触发懒加载
1. 问题如图单选按钮点击后,没有进行懒加载,直接显示空数据2. 解决给el-cascader绑定change事件,手动调用lazyLoad方法<!-- 选择文件夹 --> <el-dialog title="选择文件夹" :visible.sync="dialogVisible" width="30%" append-to-body > <div class="" v-if="dialogVisible"> <span>文件夹:</span> <el-cascader class="cyupload-cascader" ref="folder-cascader-ref" :props="props" :show-all-levels="false" @change="change" clearable > </el-cascader> </div> <span slot="footer" class="dialog-footer"> <el-button @click="dialogVisible = false">取 消</el-button> <el-button type="primary" @click="sureBtn">确 定</el-button> </span> </el-dialog>// 级联状态变化 change (val) { // console.log(val); console.log(this.$refs['folder-cascader-ref'], 'ref'); this.folderId = val[val.length - 1] // this.$refs['folder-cascader-ref'].dropDownVisible = false // 关闭面板 const selectNode = this.$refs['folder-cascader-ref'].getCheckedNodes()[0] // node节点 if (selectNode && !selectNode.loaded) this.$refs['folder-cascader-ref'].$refs['panel'].lazyLoad(selectNode) // 选中加载 },3. 成功效果图
2022年05月06日
574 阅读
0 评论
1 点赞
2022-04-08
后端数据大数字精度缺失问题
1. 使用json-bigintnpm i json-bigint2. 如何使用import axios from 'axios' import jsonBig from 'json-bigint' // create an axios instance const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url // withCredentials: true, // send cookies when cross-domain requests timeout: 5 * 1000, // request timeout // 在响应数据前处理该数据 transformResponse: [function (data) { try { // 如果转换成功则返回转换的数据结果,会将大数字转换为bigint console.log(jsonBig.parse(data), 888); return jsonBig.parse(data) } catch (err) { // 如果转换失败,则包装为统一数据格式并返回 return { data } } }] })2. 使用时,将该字段转换为字符串res.data.pid.toString() // 4125411516516488
2022年04月08日
76 阅读
0 评论
0 点赞
2022-04-07
el-input type="number" 去掉上下箭头
先来看一下原图,会有一个上下箭头::v-deep input { &::-webkit-outer-spin-button, &::-webkit-inner-spin-button { -webkit-appearance: none !important; } }去掉之后
2022年04月07日
356 阅读
0 评论
0 点赞
2022-03-22
js根据字节自动转化KB或MB或GB
getFileSize(limit) { // 字节 // bytes --> KB --> MB -->GB var size = ""; if(limit < 0.1 * 1024){ //小于0.1KB,则转化成B size = limit.toFixed(2) + "B" }else if(limit < 0.1 * 1024 * 1024){ //小于0.1MB,则转化成KB size = (limit/1024).toFixed(2) + "KB" }else if(limit < 0.1 * 1024 * 1024 * 1024){ //小于0.1GB,则转化成MB size = (limit/(1024 * 1024)).toFixed(2) + "MB" }else{ //其他转化成GB size = (limit/(1024 * 1024 * 1024)).toFixed(2) + "GB" } var sizeStr = size + ""; //转成字符串 var index = sizeStr.indexOf("."); //获取小数点处的索引 var dou = sizeStr.substr(index + 1 ,2) //获取小数点后两位的值 if(dou == "00"){ //判断后两位是否为00,如果是则删除00 return sizeStr.substring(0, index) + sizeStr.substr(index + 3, 2) } return size; }
2022年03月22日
322 阅读
0 评论
1 点赞
2022-03-22
如何在vue中优雅的使用svg
1. svg-sprite-loadernpm install svg-sprite-loader --save2. 在src中新建文件夹iconsicons/svg 存放svg图标icons/index.js 全局注册svg组件,导入所有svg图标// icons/index.js import Vue from 'vue' import SvgIcon from '@/components/SvgIcon/index.vue'// svg component // register globally Vue.component('SvgIcon', SvgIcon) const req = require.context('./svg', false, /\.svg$/) const requireAll = requireContext => requireContext.keys().map(requireContext) requireAll(req)3. 创建svg组件// src/components/ScgIcon/index.vue <template> <svg :class="svgClass" aria-hidden="true" v-on="$listeners"> <use :xlink:href="iconName" /> </svg> </template> <script> export default { name: 'SvgIcon', props: { iconClass: { type: String, required: true }, className: { type: String, default: '' } }, computed: { iconName () { return `#icon-${this.iconClass}` }, svgClass () { if (this.className) { return 'svg-icon ' + this.className } else { return 'svg-icon' } } } } </script> <style scoped> .svg-icon { width: 1em; height: 1em; vertical-align: -0.15em; fill: currentColor; overflow: hidden; } </style> 4. 在vue.config.js中使用loaderconst path = require('path') function resolve (dir) { return path.join(__dirname, dir) } module.exports = { devServer: { port: 8080, open: true }, chainWebpack (config) { // set svg-sprite-loader config.module .rule('svg') .exclude.add(resolve('src/icons')) .end() config.module .rule('icons') .test(/\.svg$/) .include.add(resolve('src/icons')) .end() .use('svg-sprite-loader') .loader('svg-sprite-loader') .options({ symbolId: 'icon-[name]' }) .end() } }5. 在main.js中导入icons/index.js// main.js import '@/icons/index' // svg6. 在页面中使用组件<SvgIcon iconClass="eye-open"></SvgIcon>直接使用svg文件名作为iconClass
2022年03月22日
364 阅读
1 评论
0 点赞
2022-03-11
el-upload自定义触发按钮及触发上传前判断
1. 在页面中引用el-upload组件<!-- 自定义按钮div --> <div v-if="routerList.length !== 1" class="action upload" :class="{action_upload_radius: routerList.length === 1}" @click="uploadHandler" > <i class="el-icon el-icon-upload"></i>上传 </div> <!-- hidden upload --> <el-upload v-show="false" class="upload-demo" :action="uploadUrl" :on-success="actionUploadSucc" :show-file-list="false" :headers="headers" :data="actUploadParams" :multiple="false" :file-list="fileList"> <el-button ref="file-home-uploadBtnRef" v-show="false"> <i class="el-icon-upload"></i>上传文件 </el-button> </el-upload>使用一个div模拟一个上传按钮,使用v-show隐藏upload组件,在upload组件的触发按钮el-button上绑定ref2. 触发前条件判断及触发upload上传方式 // action bar 上传btn uploadHandler () { console.log(this.routerList); const len = this.routerList.length if(this.routerList.length === 1) return this.$message.info('请先进入文件夹!') const currFolderId = this.routerList[len-1].folderId // 当前操作的文件夹id this.actUploadParams.folderId = currFolderId // 触发upload组件上传 this.$refs['file-home-uploadBtnRef'].$el.click() },获取到upload触发按钮el-button的ref,在获取到ref上的$el,调用click()自点击触发upload上传
2022年03月11日
826 阅读
3 评论
3 点赞
2022-02-08
ArrayBuffer和base64字符串互相转化
1. ArrayBuffer转base64function translateArrayBufferToBase64(buffer){ const bytes = new Uint8Array(buffer).reduce((data, byte) => data + String.fromCharCode(byte), '') return window.btoa(bytes); }2. base64转ArrayBufferfunction translateBase64ToArrayBuffer(base64){ const binaryStr = window.atob(base64); const byteLength = binaryStr.length; const bytes = new Uint8Array(byteLength); for(let i=0;i<byteLength;i++){ bytes[i] = binaryStr.charCodeAt(i); } return bytes.buffer; }
2022年02月08日
303 阅读
3 评论
1 点赞
1
2
3
...
7