首页
友链
壁纸
留言
今日热榜
更多
关于
时光
推荐
精品流量卡
Search
1
都二十多年了,你的梦为什么还没碎!
57,088 阅读
2
2022年5个好用的 BT/ 磁力链接下载工具推荐 |Windows 、安卓系统
37,361 阅读
3
nps内网穿透实现外网访问树莓派
32,425 阅读
4
实践利用宝塔建emlog个人博客-超详细【原创】
26,132 阅读
5
Typecho-Joe-Theme主题帮助文档
24,619 阅读
闲杂乱码
Python
网站源码
微信小程序
娱乐分享
Is相册
软件工具
登录
Search
标签搜索
PHP
HTML
API
Javascript
源码
JS
Vue
Github
CloudFlare
接口
函数
SQL
ASP.NET
MVC
EF
T4模板
后台管理
CDN
微信小程序
MAC
韩小韩
累计撰写
261
篇文章
累计收到
1,305
条评论
首页
栏目
闲杂乱码
Python
网站源码
微信小程序
娱乐分享
Is相册
软件工具
页面
友链
壁纸
留言
今日热榜
关于
时光
推荐
精品流量卡
搜索到
260
篇与
韩小韩
的结果
2023-07-28
Vue3 + Vite + Vue Router 4后端返回路由配置动态路由权限管理
动态路由// 路由递归处理 const AllRouter = import.meta.glob('@/views/**/*.vue'); interface RouterItem { path: string; name: string; component: () => any; children?: RouterItem[]; meta: { title: string; icon: string; }; } const routerFormat = (routerList: any): RouterItem[] => { if (!routerList || !Array.isArray(routerList)) return []; return routerList.map((item: any) => { return { ...item, component: AllRouter[`/src/views/${item['component']}`], children: routerFormat(item['children']) }; }); }; // 动态路由挂载 const addDynamicRoutes = (layoutRoute: RouteRecordRaw | undefined, page: RouteLocationNormalizedLoaded) => { const newRouteStr = localStorage.getItem('routerList'); if (layoutRoute && newRouteStr && layoutRoute.children!.length < 1) { const newRouteArr = routerFormat(JSON.parse(newRouteStr) as RouteRecordRaw[]); layoutRoute.children = newRouteArr; router.addRoute(layoutRoute); router.push(page); } };路由守卫// 路由守卫 router.beforeEach(async (to, from, next) => { // 每次请求判断动态路由是否挂载 const layoutRoute: RouteRecordRaw | undefined = router.options.routes.find(route=> route.name === 'Layout'); addDynamicRoutes(layoutRoute, to); // 路由拦截规则 const TOKEN_STATIC: string | null = localStorage.getItem('session'); if (to.path === '/login' && TOKEN_STATIC) { next('/Layout'); } else { !TOKEN_STATIC && to.path !== '/login' ? next('/login') : next(); } });Login获取路由信息// 路由递归处理 const routerFormat = (routerList: any[]): any[] => { if (!routerList) return []; return routerList.map((item: any) => { return { path: item['url'], name: item['title'], component: item['component'], children: routerFormat(item['children']), meta: { title: item['title'], icon: item['ico'] } }; }); }; // 获取用户信息 const getUserInfoFn = async (session: any) => { localStorage.setItem('session', session); const res = await getUserInfo(); if (res.code == 0) { const routerList = routerFormat(res.data.router_list); localStorage.setItem('userInfo', JSON.stringify(res.data.user_info)); localStorage.setItem('routerList', JSON.stringify(routerList)); router.push({ name: 'Layout' }); } };
2023年07月28日
7,000 阅读
0 评论
2 点赞
2023-07-01
为Clash节点配置负载均衡(适用于Clash、Clash Premium和Clash Meta)
{message type="info" content="在我们使用Clash节点的时候,有时候觉得自己的节点网速跑不满,速度不够快。这时候,我们可以尝试着使用负载均衡,来让节点的网速拉满。在这期教程中,我来和大家一起来为Clash节点配置负载均衡。"/}准备材料Clash 节点配置基于原版 Clash、Clash Premium 或 Clash Meta 的客户端部署步骤CFW Parsers打开 Clash For Windows,转到“Settings”→“Profiles”。点击“Parsers”右边的“Edit”按钮在内置编辑器中,粘贴以下内容并保存parsers: - reg: 'slbable$' yaml: append-proxy-groups: - name: ⚖️ 负载均衡-散列 type: load-balance url: 'http://www.google.com/generate_204' interval: 300 strategy: consistent-hashing - name: ⚖️ 负载均衡-轮询 type: load-balance url: 'http://www.google.com/generate_204' interval: 300 strategy: round-robin commands: - proxy-groups.⚖️ 负载均衡-散列.proxies=[]proxyNames - proxy-groups.0.proxies.0+⚖️ 负载均衡-散列 - proxy-groups.⚖️ 负载均衡-轮询.proxies=[]proxyNames - proxy-groups.0.proxies.0+⚖️ 负载均衡-轮询为了防止正常订阅被污染,请自行修改订阅地址,在其后面加上 #slbable 即可使用负载均衡手动配置使用VS Code或其他编辑器,打开Clash的节点配置文件。将以下内容,添加到第一个策略组- ⚖️ 负载均衡-轮询 - ⚖️ 负载均衡-散列在现有代理组的后面,添加代理策略组。- name: ⚖️ 负载均衡-散列 type: load-balance url: http://www.google.com/generate_204 interval: 300 strategy: consistent-hashing proxies: - P1 - P2 - P3 - name: ⚖️ 负载均衡-轮询 type: load-balance url: http://www.google.com/generate_204 interval: 300 strategy: round-robin proxies: - P1 - P2 - P3{callout color="#f0ad4e"}请将实际的P1、P2、P3替换成自己的节点名称{/callout}在基于Clash内核的客户端中,导入节点配置文件转自 https://blog.misaka.rest/2023/04/17/clash-load-balancing/
2023年07月01日
5,772 阅读
0 评论
0 点赞
2023-03-24
手撸call apply bind
{callout color="#f0ad4e"}如果自己去实现call apply bind,看上去挺复杂,写起来其实就几行代码因为call和apply一样,只是传参不一样,所以我就只写一个call{/callout}实现call(其实只有2行代码)/* 随便定义一个对象,待会将函数内的this指向指向倒这个对象 */ const obj = { name: '我是需要被绑定改变this指向的对象' } /* 需要改变this指向的函数,没有使用call时,this指向window */ function fn(arg) { console.log('fn---------', this); console.log('fn---------', arg); } /* * * 重写call方法 * target 需要把this改变到哪个目标 * args 传递进来的参数 */ Function.prototype.call = function (target, ...args) { /* 这里的this就指向上面的fn函数 */ console.log(this); /* 随便定义一个变量,用于在目标对象里存fn函数,这里使用symbol更好 */ target['sb250'] = this /* 这样target目标上就有个sb250的属性,并且属性值就是fn函数 */ console.log(target); /* 调用这个sb250,并把参数传入进去就实现this改变了 */ target['sb250'](args) /* 防止给target上多出多余没用的参数,在将sb250删除掉 */ delete target['sb250'] } fn.call(obj, '我是傻逼')实现bind因为bind的调用方式,是返回一个新函数,在调用一次,例如:fn.bind(null)(options),所以需要用到高阶函数/* 随便定义一个对象,待会将函数内的this指向指向倒这个对象 */ const obj = { name: '我是需要被绑定改变this指向的对象' } /* 需要改变this指向的函数,没有使用call时,this指向window */ function fn(arg) { console.log('fn---------', this); console.log('fn---------', arg); } /* * * 重写call方法 * target 需要把this改变到哪个目标 * args 传递进来的参数 */ Function.prototype.bind = function (target) { target['sb250'] = this /* 这里使用高阶函数接收参数 */ return (...args) => { target['sb250'](args) delete target['sb250'] } } fn.bind(obj)('我是大傻逼!!!')
2023年03月24日
2,818 阅读
4 评论
0 点赞
2023-03-14
2023年有哪些良心的流量卡推荐?爆肝给大家整理好了最新的流量卡合集
不用再费力翻找了,良心的流量卡都在这里,还不知道如何申请?仅此一篇,拿走不谢。 {callout color="#F6F6F6"}本篇为流量卡测评+推荐+领取攻略文章(点赞+收藏我相信你一定会用的上){/callout}@小韩 长期搜寻全国各地运营商发布的优惠补贴流量卡。集合了河南、山东、海南、福建、宁夏、北京、广东、四川、湖北、湖南各地运营商推出的各款流量卡,目前还在持续挖掘中......运营商调整时期,相信很多友友都发现了近期想要去找优惠补贴手机流量卡,但是无论去哪里都找不到。为解决这个问题, 小韩 在此特别更新一篇还可领取的流量卡文章,给大家筛选出来可以盲入的流量卡系列。开篇前先给大家讲点小知识。(坐下听课了)如果你仔细了解了这些流量卡之中的套路,那可以跳过以下避坑指南,直接进入正文部分。如果你是新手小白或者对流量卡只是略懂,建议最好看完这部分经验,最大程度保证你不会交流量卡方面的智商税~流量卡避坑指南选择流量卡之前一定要看清楚套餐详情,这是重中之重,套餐详情就好比盖房子的地基一样,那玩意给你拐弯抹角你能说不踩坑?比如看着是360G,真正用上之后才知道每个月30G,回头仔细看套餐详情,原来是360G每年。还是定向流量,年字小到根本看不到。如下图:记住一点(越是含糊不清不想让大家看到的,就越暗藏坑点)另外!! {callout color="#f0ad4e"}物联卡一定是不能选的,无论是物联卡还是手机卡他都能被归为流量卡。目前流量卡市场鱼龙混杂,有些商家利用纯低的月租和纯高的流量来吸引用户,实际上坑很多。{/callout}要么虚量,要么是买了就消失,要么前面收费便宜后面收费变高,总之套路特别多。咱就是说5块能有20G流量,难道运营商不吃饭了?出这种套餐?所以友友们一定要擦亮自己的眼睛。 给大家科普一下为什么20G流量只要5块?首先他会设置虚量,虚完之后应该就剩10G然后速度也比正常的手机卡要慢(虚量+限速=用量变少)。最后差不多和日租卡一样,最后算下来并没有特别划算。还有,现在选择手机流量卡或者物联卡的时候,记得一定要是实名制的。如果谁告诉你 不要实名,赶紧溜,必有大坑!▶ 为什么这些优惠套餐只能线上申请? {callout color="#f0ad4e"}线上不能影响线下的收入,因为大部分的友友办理手机卡都还是习惯于去线下,如果都用上了优惠套餐,那只能造成一个后果,就是只能再次提高流量价格!所以优惠套餐只能线上申请,不能在线下申请。但是无论线上还是线下,都是官方营业厅可以查询到的。都能享受到官方的各种服务!{/callout}{mtitle title="好卡大多能选择的期限"/}性价比流量卡推荐区:{abtn icon="fa-link" color="#ff6800" href="https://www.vvhan.com/HaoKa/" radius="" content="2023年良心流量卡推荐"/}
2023年03月14日
2,507 阅读
10 评论
1 点赞
2023-03-06
class中函数的this指向
定义一个基础的类class Person { constructor(name = '杜恒') { this.name = name } speak() { console.log(this); } }将上面的类实例出一个对象p,并调用p的speak方法const p = new Person() p.speak() // Person {name: "杜恒"}{callout color="#f0ad4e"}上面的打印结果显示由类构造出的实例对象,因此this会指向由类构造出的实例对象{/callout}尝试将p实例对象身上的speak方法赋值给另一个变量进行调用const test = p.speak test() // undefined打印undefind,因此上面的方法可以改写成如下const test = function () { "use strict" console.log(this); } test() // undefined{callout color="#ef4db4"}由此可以得出,在class中,定义的方法,class会默认在函数体内开启严格模式,严格控制this的指向{/callout}
2023年03月06日
2,906 阅读
0 评论
1 点赞
2023-02-26
Vue底层判断标签的性能优化方法
在vue中,如果写div、span等正常的html标签,vue会解析成传统的html标签,但当写不是这些标签的时候,vue会认为他是一个组件,例如:<Custom></Custom>。是如何做到这种判断的呢,首先自己来实现一个这样的判断const tags = 'div,span,img,a'.split(",") function checkTag(tag) { return tags.some(item => item === tag) } console.log(checkTag('Custom')); // false console.log(checkTag('div')); // true console.log(checkTag('a')); // true这里的实现方案有很多,可以用for、some、forEach等,但是都是离不开循环,思考这样的一个问题,传入一个a,a在字符串最后一个位置,所以会循环4次来判断是否包含a,如果页面上的标签极多,甚至会有上万次的循环再来查看Vue实现这个的方式,大致源码如下const tags = 'div,span,img,a' function makeMap(str) { var map = Object.create(null); var list = str.split(','); for (var i = 0; i < list.length; i++) { map[list[i]] = true; } return function (val) { return map[val]; } } const isHtmlTag = makeMap(tags) isHtmlTag('div') isHtmlTag('Custom') isHtmlTag('a')这里可以看出,实现出一个柯里化函数,并且也是一个闭包状态。此时,在第一次调用时,会循环一次,后续不论在去判断什么标签,都不会再去循环,因为第一次的循环结果利用闭包已经存在了内存里,这就是闭包能带来的性能优化
2023年02月26日
2,479 阅读
0 评论
1 点赞
2023-02-18
Vue.set与this.$set源码
Vue.set()和this.$set()应用的场景在 Vue 2.X 项目开发中,有时候需要对数组进行修改,或是对对象新增一个属性,但是发现页面并不会同步更新。例如:const vm = new Vue({ data: { arr: [1, 2], obj: { a: 3 } } }); vm.$data.arr[0] = 3; // 页面不会发生改变 vm.$data.obj.b = 3; // 页面不会发生改变此时就需要使用到 Vue.set() 或 this.$set()。这个2个的使用方法一样,不过一个是挂载在Vue身上,一个挂载在Vue.prototype上// Vue.set import { set } from '../observer/index' Vue.set = set // this.$set import { set } from '../observer/index' Vue.prototype.$set = se使用Vue.set或this.$set来实现页面不更新的问题:const vm = new Vue({ data: { arr: [1, 2], obj: { a: 3 } } }); // 修改数组 Vue.set(vm.$data.arr, 0, 3); vm.$set(vm.$data.arr, 0, 3); // 对象新增属性 Vue.set(vm.$data.obj, 'b', 3); vm.$set(vm.$data.obj, 'b', 3);set函数的源代码../observer/indexfunction set (target: Array<any> | Object, key: any, val: any): any { // isUndef(target):用于判断传入的target是否是undefined或null // isPrimitive(target):用于判断传入的target是否是原始数据类型 // 如果是 null 或者是 undefined 时,抛出异常 if (process.env.NODE_ENV !== 'production' &&(isUndef(target) || isPrimitive(target))) { warn(`Cannot set reactive property on undefined, null, or primitive value: ${(target: any)}`) } // 如果传入了一个数组,并且传入的key是数组的有效值 if (Array.isArray(target) && isValidArrayIndex(key)) { // 用于设置数组的最大length // Math.max(target.length, key):取数组的length和key二者中的最大值 target.length = Math.max(target.length, key) // 直接调用数组身上的splice方法,因为Vue里变异了数组方法,调用会触发dep.notify() target.splice(key, 1, val) return val } // 接下来就是对象的判断了 // 如果传入的 key 在原对象中,说明已经是响应式了,直接修改即可 if (key in target && !(key in Object.prototype)) { target[key] = val return val } // 这里到最后的代码,都是对象不在原对象上,是新增的属性值 const ob = (target: any).__ob__ // 如果是Vue实例对象,或根数据对象,则抛出警告 if (target._isVue || (ob && ob.vmCount)) { process.env.NODE_ENV !== 'production' && warn( 'Avoid adding reactive properties to a Vue instance or its root $data ' + 'at runtime - declare it upfront in the data option.' ) return val } // 如果没有 __ob__ 表示当前 target 不是响应式的,那么直接赋值 if (!ob) { target[key] = val return val } // 剩下就是给响应式对象增加一个 key 新属性,并通知更新 defineReactive(ob.value, key, val) ob.dep.notify() return val }
2023年02月18日
2,261 阅读
0 评论
0 点赞
2023-02-13
火爆全球的ChatGPT,最全的使用方法!
{message type="info" content="ChatGPT是OpenAI旗下的一款聊天机器人,现在已经火遍全球,前几天我简要介绍了一下,很多小伙伴儿留言想知道怎么使用。目前来说,需要免费注册一个OpenAI账号,才能使用。可惜暂未对国内开放注册,无法访问。下面简要介绍几种方法,供大家参考。"/}ChatGPT高仿/反代{callout color="#f0ad4e"}① https://aigcfun.com这个网站和官网的界面设计是一样的。免费使用、无需登录账号、无需科学上网,网站无广告,非常方便。打开网页后,直接输入问题提问即可。{/callout}{callout color="#f0ad4e"}② http://chat.h2ai.cn/home与上面的网站类似,界面为中文,与官网界面一致。可以作为备用。{/callout}{callout color="#f0ad4e"}③ https://xc.com这也是一个第三方的镜像网站,使用也比较简单。{/callout}官网直接注册{callout color="#f0ad4e"}ChatGPT的使用方法其实很简单,就是登录官方地址,注册一个账号,然后就可以免费使用了。之所以很多人搞不定,主要是尚未对国内开放,需要科学上网;在注册账号的过程中,有一步需要验证码,而这个验证码需要国外的手机号。因此,使用上有一定的门槛,下面简要说明:{/callout}1、科学上网,打开ChatGPT官网进行注册: https://chat.openai.com2、注册账号的过程中,需要一个国外手机号收验证码。我们可以用下面网站提供的虚拟号码来接受验证码。 https://sms-activate.org{callout color="#f0ad4e"}可惜并不是免费的,需要至少充值1美元(7元人民币)。这个网站使用的时候,也要先注册一个账号。购买号码时,选择一个(例如:印度)点击购物车,充值时可以选择支付宝,便宜的号码5~6元人民币左右,购买后账户还会剩下一点余额。成功付款后,等待几秒钟自动给出一个虚拟号码,这个号码可以用来接受验证码。需要注意的是,虚拟号码给出后,要尽快使用,过期就失效了。{/callout}微软新Bing(集成ChatGPT)前不久的新闻,微软的Bing搜索引擎与ChatGPT合作,打开如下网站,可以获取“使用ChatGPT版Bing”的后补资格。https://www.bing.com/new这个网站打开后,应该是如下界面,不过目前仍需要一些手段才可以打开。使用方法:使用Edge浏览器,扩展市场中搜索并安装Gooreplacer。点击浏览器中该扩展的图标,点击导入下面的规则。如下图所示。重启浏览器,然后再进入新的Bing网站,就可以正常打开了。点击一下申请候选“Join the waitlist”,这个时候需要登录微软账户。接下来就是等待邮件通知了,等收到通知就可以体验ChatGPT版本的Bing了。{callout color="#f0ad4e"}Gooreplacer规则文件{/callout}{cloud title="Gooreplacer规则" type="lz" url="https://ohan.lanzouf.com/iVnFd0nfuawb" password=""/}{gird column="2" gap="15"}{gird-item}{/gird-item}{gird-item}{/gird-item}{/gird}使用ChatGPT的API密钥这种方法,依然需要注册一个OpenAI的账号,方法参考方法2。在已经有了OpenAI账号的前提下:1、打开OpenAI官网,申请API密钥(科学上网)。https://platform.openai.com/account/api-keys2、下载一个第三方的客户端(来自吾爱破解论坛),将申请到的API密钥输入到下图中。然后就也可以和ChatGPT对话了,平时对话的时候,不需要科学上网,正常联网即可。{cloud title="ChatGPT v1.1p" type="lz" url="https://ohan.lanzouf.com/ibYqu0nfuwxe" password=""/}{gird column="3" gap="15"}{gird-item}{/gird-item}{gird-item}{/gird-item}{gird-item}{/gird-item}{/gird}
2023年02月13日
4,312 阅读
5 评论
3 点赞
1
2
3
...
33