首页
友链
导航
影视
壁纸
统计
留言板
Search
1
el-upload自定义触发按钮及触发上传前判断
909 阅读
2
vue配置二级目录以及nginx多网站部署
713 阅读
3
el-cascader选择任意一级搭配懒加载使用,单选框radio不会触发懒加载
600 阅读
4
joe主题自定义导航页面
599 阅读
5
js获取昨天今天明天日期
499 阅读
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
篇文章
累计收到
126
条评论
首页
栏目
web前端
vue
react
javascript
nuxt
typescript
indexDB数据库
微信小程序
美文欣赏
心情随笔
技术分享
其他
PHP
nodejs
博客api实战项目
typecho
页面
友链
导航
影视
壁纸
统计
留言板
搜索到
40
篇与
web前端
的结果
2022-01-10
移动端适配(rem)
1. postcss-pxtorem该插件可以将项目中的px值转化为rem,注意:行内样式不会转化npm install postcss-pxtorem -D在项目根目录创建文件 .postcssrc.js 或 postcss.config.js// postcss.config.js module.exports = { plugins: { // 用到的插件都配置在这里 'postcss-pxtorem': { rootValue: 37.5, // 1rem = 37.5px rem基准值 750设计稿就改为 75 propList: ['*'], // 配置要转换的css属性 * 表示所有属性 }, }, }; module.exports = { plugins: { // postcss-pxtorem 插件的版本需要 >= 5.0.0 'postcss-pxtorem': { rootValue({ file }) { // Vant中是根据375来写 如果我们的不是,就需要使用 函数的形式做判断 return file.indexOf('vant') !== -1 ? 37.5 : 75; }, propList: ['*'], }, }, };2. lib-flexible该插件可以根据屏幕动态的设置html的font-size大小默认会将屏幕分成十份,然后给html的font-size, 比如屏幕宽度 750px 那么html的font-size就是 75px1rem = 75pxnpm install lib-flexible// 在main.js中导入 import 'amfe-flexible'
2022年01月10日
96 阅读
0 评论
2 点赞
2022-01-10
js的两种定时器
1. window.setTimeout(fn, wait)设置一个定时器,等待wait时间后,执行fn函数,该定时器只会执行一次,执行完函数后,该定时器停止。// 1000毫秒后打印一次 1 const timer1 = window.setTimeout(() => { console.log(1) }, 1000)2. window.setInterval(fn, wait)设置一个定时器,每等待wait时间,都会执行一次fn函数。该定时器会一直执行。// 每隔1000毫秒打印一次 2 const timer2 = window.setTimeout(() => { console.log(2) }, 1000)3. 清除定时器每个定时器都会返回一个定时器的id 如上边的timer1,timer2就是定时器id通过clearTimeout(timer1) 或者 clearInterval(timer2)来清除相对应的定时器,定时器的id依然存在,下次创建定时器,id会继续往后排队clearTimeout(timer1) clearInterval(timer2)
2022年01月10日
26 阅读
0 评论
2 点赞
2022-01-04
前端indexDB数据库的使用
一、indexDB中的对象数据库:IDBDatabase 对象 对象仓库:IDBObjectStore 对象 索引: IDBIndex 对象 事务: IDBTransaction 对象 操作请求:IDBRequest 对象 指针: IDBCursor 对象 主键集合:IDBKeyRange 对象二、操作数据库1. 打开数据库如果存在就打开,不存在就创建一个indexDB数据库window.indexedDB.open(databaseName, version) // 数据库名称,版本号2. 创建表(创建对象仓库)要在onupgradeneeded中创建表和索引,onupgradeneeded函数只有在数据库创建和数据库版本升级才会触发const req = window.indexDB.open('utm_db_product', 1) // 打开/创建数据库 req.onsuccess = function (event) { // 监听数据库创建成功事件 let db = event.target.result // 数据库对象 console.log('数据库打开成功') } req.onerror = function (error) { console.log('数据库打开报错') } req.onupgradeneeded = function (event) { // 数据库创建或升级的时候会触发 db = event.target.result let storeName = 'product' // 表名 if (!db.objectStoreNames.contains(storeName)) { // 判断表是否存在 let objectStore = db.createObjectStore(storeName, { keyPath: 'pro_id',autoIncrement: true }) } }db.createObjectStore可以创建一张表,param1 表名,param2 配置对象,keyPath为主键,autoIncrement是自动生成一个自增主键,一般keyPath和autoIncrement只需要一个,两个都存在的话,自动生成一个自增主键,并且keyPath设置的字段必须要存在3. 创建索引索引可以用来搜索,主键是默认的索引req.onupgradeneeded = function (event) { // 数据库创建或升级的时候会触发 db = event.target.result let storeName = 'product' // 表名 if (!db.objectStoreNames.contains(storeName)) { // 判断表是否存在 let objectStore = db.createObjectStore(storeName, { keyPath: 'pro_id',autoIncrement: true }) objectStore.createIndex('name', 'name', { unique: false }) // 创建索引 可以让你搜索任意字段 } }给对象仓库(数据库表)创建索引,需要使用对象仓库的createIndex()函数,param1 索引名称,param2 索引所在属性,param3 配置对象 配置该属性是否是唯一的param3 配置对象可配置属性unique 唯一multiEntry 对于有多个值的主键数组,每个值将在索引里面新建一个条目,否则主键数组对应一个条目4. 使用promise封装 open方法/** * 打开/创建数据库 * @param {object} dbName 数据库的名字 * @param {string} storeName 仓库名称 * @param {string} version 数据库的版本 * @param {Array} index 索引数组 * @return {object} 该函数会返回一个数据库实例 */ const openDB = function (dbName, version, storeName, keyPath, index) { return new Promise((resolve, reject) => { // 兼容浏览器 let indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB let db = null const req = indexedDB.open(dbName, version) // 操作成功 req.success = function () { db = event.target.result // 数据库对象 resolve({code: 0, success: true, data: db, msg: '数据库打开成功!'}) } // 操作失败 request.onerror = function (event) { resolve({code: -1, success: false, data: null, msg: '数据库打开失败!'}) } // 创建表和索引 request.onupgradeneeded = function (event) { // 数据库创建或升级的时候会触发 db = event.target.result // 数据库对象 let objectStore if (!db.objectStoreNames.contains(storeName)) { objectStore = db.createObjectStore(storeName, { keyPath: keyPath || 'id',autoIncrement: true }) // 创建表 index.forEach(item => { objectStore.createIndex(item, item, { unique: false }) // 创建索引 }) } } }) }5. 添加数据需要通过事务对象IDBTransaction 来获取到对象仓库(表),然后通过对象仓库的add()方法向表中添加数据// 1. 打开数据库 const db = window.indexDB.open('utm_db_product', 1) // 2. 创建事务对象 const t = db.transaction(['product'], 'readwrite') // params1 表名, param2 读写模式 // 3. 拿到对象仓库 const objectStore = t.objectStore('product') // params 表名 // 4. 添加数据 const req = objectStore.add({pro_id: 123456, pro_name: '大白菜'}) // params 添加的数据 // 5. 操作成功 req.success = function (e) {} // 6. 操作失败 req.success = function (e) {} // 注:1234 可使用点操作符连写 const req = window.indexDB.open('utm_db_product', 1) .transaction(['product'], 'readwrite') .objectStore('product') .add({pro_id: 123456, pro_name: '大白菜'})6. 使用promise封装 add方法/** * 新增数据 * @param {object} db 数据库实例 * @param {string} storeName 仓库名称 * @param {string} data 数据 **/ const addData = function (db, storeName, data) { return new Promise((resolve, reject) => { let req = db .transaction([storeName], 'readwrite') .objectStore(storeName) // 仓库对象 .add(data) // 操作成功 req.onsuccess = function (event) { console.log('数据写入成功') resolve({code: 0, success: true, data: null, msg: '数据写入成功!'}) } // 操作失败 req.onerror = function (event) { console.log('数据写入失败') let data = {code: -1, success: false, data: null, msg: '数据写入失败!'} resolve(data) } }) }7. 修改数据使用对象仓库的put方法,修改表中数据objectStore.put({id: 1, pro_id: 123456, pro_name: '胡萝卜'}) // param1 数据 param2 主键,可选该方法自动更新了主键id为1的数据8. 使用promise封装 put方法/** * 更新数据 * @param {object} db 数据库实例 * @param {string} storeName 仓库名称 * @param {object} data 数据 */ const updateData = function (db, storeName, data) { return new Promise((resolve, reject) => { const req = db .transaction([storeName], 'readwrite') .objectStore(storeName) .put(data) // 操作成功 req.onsuccess = function (event) { console.log('数据更新成功') resolve({code: 0, success: true, data: null, msg: '数据更新成功!'}) } // 操作失败 req.onerror = function (event) { console.log('数据更新失败') let data = {code: -1, success: false, data: null, msg: '数据更新失败!'} resolve(data) } }) }9. 删除数据使用对象仓库的delete方法,删除表中数据objectStore.delete(1) // param 主键的值该方法会删除主键为1的数据10. 获取数据使用对象仓库的get方法,获取对应主键的数据objectStore.get(1) // param 主键的值该方法会获取主键为1的数据11. 使用指针对象遍历所有数据使用指针对象IDBCursor遍历数据objectStore.openCursor().onsuccess = function () { const cursor = e.target.result if (cursor) { console.log(cursor.key) // 当前遍历数据的主键 console.log(cursor.value) // 当前遍历的数据 cursor.continue() // 继续下一个 } }
2022年01月04日
137 阅读
0 评论
6 点赞
2021-12-24
js实现深拷贝
1. 使用递归let str = "我是string基本数据类型" let arr = [1, 6, [1, 3, 5, 7, 9], 5, 8, { a: 4, b: 7 }, 9, 0] let obj = { a: 1, b: 2, c: 3, d: [123, 456], e: { ea: 789, eb: 666 } } let nu = null function deepClone(ob) { if (typeof ob === "object") { if (Object.prototype.toString.call(ob).slice(8, -1) === 'Null') return ob if (ob instanceof Array) { // 数组 let newArr = [] ob.forEach((item, index, arr) => { newArr[index] = deepClone(item) }) return newArr } else { // 对象 let newObj = {} // for (let k in ob) { // newObj[k] = deepClone(ob[k]) // } Object.keys(ob).forEach((key, index, arr) => { newObj[key] = deepClone(ob[key]) }) return newObj } } else { return ob } } console.log(deepClone(str)) console.log(deepClone(arr)) console.log(deepClone(obj)) console.log(deepClone(nu))2. JSON.parse()和JSON.stringify()JSON.stringify() // 将对象转化为json字符串 JSON.parse() // 将json转化为json对象 console.log(JSON.parse(JSON.stringify({a: 1, b: [4,5,6]})))该方法可能会出现如下问题undefined、任意的函数以及 symbol 值,在序列化过程中会被忽略Date 日期调用了 toJSON() 将其转换为了 string 字符串(Date.toISOString()),因此会被当做字符串处理。NaN 和 Infinity 格式的数值及 null 都会被当做 null。其他类型的对象,包括 Map/Set/WeakMap/WeakSet,仅会序列化可枚举的属性。对包含循环引用的对象(对象之间相互引用,形成无限循环)执行此方法,会抛出错误。请谨慎使用3. Object.assign() (该方法只能浅拷贝)
2021年12月24日
97 阅读
0 评论
1 点赞
2021-12-24
js如何判断数据类型
一、常用的js数据类型基本数据类型 :String、Number、Boolean、Null、Undefined 复杂数据类型 :Object二、js数据类型判断// 初始化一些数据用来判断 let str = "字符串类型" let bool = true let num = 123 let nulll = null let undef let arr = [] let obj = {} let sum = function () {} 1.使用typeof进行判断console.log(typeof str) // string console.log(typeof bool) // boolean console.log(typeof num) // number console.log(typeof nulll) // object console.log(typeof undef) // undefined console.log(typeof arr) // object console.log(typeof obj) // object console.log(typeof sum) // function{callout color="#66edff"}使用typeof进行判断数据类型,只能够判断基本数据类型string number boolean 以及 function,而null和object不能够进一步的判断。{/callout} 2.使用A instanceof B进行判断console.log(str instanceof String) // false console.log(bool instanceof Boolean) // false console.log(num instanceof Number) // false console.log(nulll instanceof Object) // false console.log(undef instanceof Object) // false console.log(arr instanceof Array) // true console.log(obj instanceof Object) // true console.log(sum instanceof Function) // true{callout color="#66edff"}使用A instanceof B的方式进行判断,字面意思,A是否是B的实例,可以判断出Array和Object类型,但是undefined和null不能区分数据类型,基础的数据类型,因为不是使用new出来的,也测试不出来。{/callout} 3.使用Object.prototype.toString.call()进行判断console.log(Object.prototype.toString.call(str)) // [object String] console.log(Object.prototype.toString.call(bool)) // [object Boolean] console.log(Object.prototype.toString.call(num)) // [object Number] console.log(Object.prototype.toString.call(nulll)) // [object Null] console.log(Object.prototype.toString.call(undef)) // [object Undefined] console.log(Object.prototype.toString.call(arr)) // [object Array] console.log(Object.prototype.toString.call(obj)) // [object Object] console.log(Object.prototype.toString.call(sum)) // [object Function]{callout color="#66edff"}Object.prototype.toString()方法可以返回一个表示该对象的字符串'[object type]',为了每个对象都能通过 Object.prototype.toString() 来检测,需要以 Function.prototype.call() 或者 Function.prototype.apply() 的形式来调用,传递要检查的对象作为第一个参数,称为 thisArg。{/callout}三、封装成函数function judgeType (data) { return Object.prototype.toString.call(data).slice(8, -1) } judgeType('jkl') // 'String' judgeType(123) // 'Number' judgeType(true) // 'Boolean' judgeType(null) // 'Null' judgeType(undefined) // 'Undefined' judgeType([]) // 'Array' judgeType({}) // 'Object' judgeType(function sum () {}) // 'Function' judgeType(new Set()) // 'Set' judgeType(new Map()) // 'Map'
2021年12月24日
117 阅读
1 评论
4 点赞
2021-12-23
css修改滚动条样式
滚动条相关样式::-webkit-scrollbar // 滚动条整体部分 ::-webkit-scrollbar-thumb // 滚动条轨道里面的小方块,能向上向下移动 ::-webkit-scrollbar-track // 滚动条的轨道 ::-webkit-scrollbar-button // 滚动条的轨道的两端按钮,允许通过点击微调小方块的位置。 ::-webkit-scrollbar-track-piece // 内层轨道,滚动条中间部分(除去) ::-webkit-scrollbar-corner // 边角,即两个滚动条的交汇处 ::-webkit-resizer // 两个滚动条的交汇处上用于通过拖动调整元素大小的小控件如果想要改变滑块的宽度我是通过给滑块加border透明实现改变滑块的宽度// 滑块 &::-webkit-scrollbar-thumb { border: 3px solid transparent; // 加边框 透明 border-radius: 6px; height: 88px; background: #00d2fb; background-clip: content-Box; // 裁剪 }
2021年12月23日
204 阅读
0 评论
0 点赞
2021-12-23
前端如何使用css变量
原生css变量1. 在html节点定义变量,变量以--name的形式html { --bg-color: red }2. 使用var()调用变量.box { background: var(--bg-color) }使用预处理器1. scss定义变量以$符号开头$base-color: #c6538c;使用变量.alert { border: 1px solid $border-dark; }2. less定义变量以$符号开头@link-color: #428bca;使用变量a { color: @link-color; }
2021年12月23日
73 阅读
0 评论
2 点赞
2021-12-23
使用require.context()函数实现自动化导入
require.context()该函数接收三个参数directory {String} -读取文件的路径useSubdirectories {Boolean} -是否遍历文件的子目录regExp {RegExp} -匹配文件的正则该函数执行后会返回一个函数,包含三个属性resolve {Function} -接受一个参数request,request为test文件夹下面匹配文件的相对路径,返回这个匹配文件相对于整个工程的相对路径keys {Function} -返回匹配成功模块的名字组成的数组id {String} -执行环境的id,返回的是一个字符串,主要用在module.hot.accept,应该是热加载实际应用场景vuex的module模块批量自动化导入const files = require.context('./modules', false, /\.js$/) // 导入modules目录下所有的js文件 const modules = {} // 所有的store模块 // files.keys() 拿到 ['./account.js', './log.js']组成的数组 // 使用replace将./和.js替换为空,当做键名 files(key).default当做键值 files.keys().forEach(key => { //files(key).default 可以拿到每一个模块 modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default }) export default { namespaced: true, modules }
2021年12月23日
329 阅读
2 评论
1 点赞
2021-12-22
封装localStorage本地存储
封装本地存储是为了更好更方便的实现本地存储,简洁明了实现本地存储的步骤1. 首先创建枚举列表,用来记录本地存储的键,可以清楚地知道,你本地都存了啥// storageEnum枚举列表 const storageEnum = { user: ['user', '用户'], // key:简写名称 value array[0]: 本地存储的键名, array[1]:描述是干嘛的 userToken: ['user::access_token', '用户token'], userInfo: ['sc_selfInfo', '用户信息'], cart: ['cart', 'cart购物车'], } module.exports = storageEnum2. 定义枚举工具/** * 枚举定义工具 * 示例: * const AA = createEnum({ * b: [1, '审核中'], * C: [2, '审核通过'] * }) * 获取枚举值:AA.b * 获取枚举描述:AA.getDesc('b') * 通过枚举值获取描述:AA.getDescFromValue(AA.b) * */ export function createEnum(definition) { const strToValueMap = {} const numToDescMap = {} for (const enumName of Object.keys(definition)) { const [value, desc] = definition[enumName] strToValueMap[enumName] = value numToDescMap[value] = desc } return { ...strToValueMap, getDesc(enumName) { return (definition[enumName] && definition[enumName][1]) || '' }, getDescFromValue(value) { return numToDescMap[value] || '' } } }3. 封装本地存储方法/* * @param param {Object} key值为 method name data */ Vue.prototype.$storageEnum = (param) => { let that = this; let { method, // get / set name, // 存储storageEnum的键名简写 data // 要存储的数据 } = param let storagelist = createEnum(storageEnum) let storageAction = new Map() .set('set', () => { uni.setStorageSync(storagelist[name], data) }) .set('get', () => { return uni.getStorageSync(storagelist[name]); }) try { return storageAction.get(method)(); } catch (e) { uni.showToast({ icon: 'none', title: `<${name}>缓存,使用错误请检查!` }); } }4. 使用this.$storageEnum({ method: 'set', name: 'userInfo', data: { username: 'zs', age: 18 } })
2021年12月22日
272 阅读
0 评论
1 点赞
2021-12-17
vue路由传参的几种方式
路由跳转的两种方式1. 声明式导航使用router-link的to属性进行路由跳转 to的值是要跳转到的那个路由// 1.1 to后直接跟路由 <router-link to="/home">to home</router-link> // 1.2 to后跟一个配置对象path属性是要跳转到的那个路由 <router-link :to="{ path: '/home' }">to home</router-link> // 1.3 to后跟一个配置对象,使用命名路由的name进行跳转 <router-link :to="{ name: 'homeIndex' }">to home</router-link>查询字符串形式 路由传参 to的值是一个配置对象 以查询字符串形式携带 url?id=123// 2.1 以 url?id=123&name=zs的形式携带 <router-link :to="{ path: '/home?id=123' }">to home?id=123</router-link> // 2.2 以query属性进行传参 <router-link :to="{ path: '/home', query: { id: 123 } }">to home 以query携带</router-link> // 2.3 以params进行传参 需要命名路由name <router-link :to="{ name: 'userIndex', params: { id: 123 } }">to user 以params携带</router-link>2. 编程式导航使用this.$router进行跳转 $router可以访问到路由的实例this.$router.push('/home') this.$router.push('/home?id=123') // 携带query参数 this.$router.push({ path: '/home', query: { id: 123 } }) // 携带query参数 this.$router.push({ name: 'homeIndex', params: { id: 123 } }) // 携带params参数 需要和命名路由搭配使用$router实例的跳转方法push() // 跳转到指定的路由,向history历史中添加记录,点击返回,返回到来之前的路由。 go(n) // 向前前进 n 或 后退 n个路由 n可为负数 replace() // 跳转到指定的路由,但是不会在history中添加记录,点击返回,会跳转到上上一个路由。 back() // 后退 forward() // 前进
2021年12月17日
144 阅读
0 评论
2 点赞
1
2
3
4