├── .gitignore ├── docs ├── public │ ├── 41b92f0efa1847f482beb87fd2d28f8e.txt │ ├── resume.pdf │ ├── robots.txt │ └── image │ │ ├── favicon.png │ │ ├── wechat.png │ │ ├── zhifubao.png │ │ ├── wechatCode.png │ │ ├── cont.svg │ │ ├── user.svg │ │ └── favicon.svg ├── api │ ├── nodejs │ │ ├── nest.md │ │ └── sql.md │ └── install-software │ │ ├── docker │ │ ├── redis.md │ │ ├── mysql.md │ │ └── index.md │ │ └── mysql.md ├── chatGPT │ ├── search.md │ └── gptApi.vue ├── web │ ├── basics │ │ ├── gap.md │ │ ├── line.md │ │ ├── use-sass.md │ │ ├── float.md │ │ ├── triangle.md │ │ ├── preview.md │ │ ├── clear-array.md │ │ ├── wrap.md │ │ ├── is-NaN.md │ │ ├── sleep.md │ │ ├── dashed-line.md │ │ ├── code-safety.md │ │ ├── exist-key.md │ │ ├── download.md │ │ ├── hidden.md │ │ ├── regExp.md │ │ ├── reflow-repaint.md │ │ ├── code-promise.md │ │ └── es6-practice.md │ ├── h5 │ │ ├── font-deformation.md │ │ ├── safe-distance.md │ │ ├── limit-back.md │ │ └── handle-delay.md │ ├── wechat │ │ ├── get-page-options.md │ │ ├── prohibit-scrolling.md │ │ ├── api-request.md │ │ ├── global-share.md │ │ ├── life-cycle.md │ │ ├── code-watch.md │ │ └── custom-nav.md │ ├── vue │ │ ├── bug-table.md │ │ ├── css-use-vue.md │ │ ├── resetData.md │ │ ├── dialog │ │ │ ├── dialog.ts │ │ │ ├── core.md │ │ │ └── dialogModule.vue │ │ ├── freeze.md │ │ ├── packaging-format.md │ │ ├── preview │ │ │ ├── core.md │ │ │ └── preview.vue │ │ ├── project-template.md │ │ ├── plugins.md │ │ ├── upgradation │ │ │ ├── vite.config.ts │ │ │ └── up-vite.md │ │ ├── upload-image │ │ │ ├── core.md │ │ │ └── upload.js │ │ ├── local.md │ │ ├── use-computed.md │ │ └── publish-npm.md │ ├── harmony │ │ ├── aspect-ratio.md │ │ ├── distinction.md │ │ ├── show.md │ │ ├── use-image.md │ │ └── holy-grail.md │ └── knowledge │ │ ├── npm-registry.md │ │ ├── npm-publish.md │ │ └── use-pm2.md ├── oneself │ ├── author-wechat.md │ └── author.md ├── other │ ├── system │ │ ├── mac │ │ │ └── install-error.md │ │ ├── win │ │ │ └── clear-icon.md │ │ └── linux │ │ │ ├── command.md │ │ │ └── release.md │ ├── tools │ │ ├── web │ │ │ └── collect.md │ │ ├── collect.md │ │ ├── internet.md │ │ ├── git-command.md │ │ └── link │ │ │ └── logo.md │ └── blog │ │ ├── up │ │ ├── up-https.md │ │ ├── setup-oss.md │ │ ├── config-algolia.md │ │ ├── use-github-actions.md │ │ ├── use-page.md │ │ ├── sync-code.md │ │ ├── use-linux.md │ │ └── use-nginx.md │ │ └── basics │ │ ├── deploy.md │ │ └── write.md └── .vitepress │ ├── theme │ ├── index.mts │ └── custom.css │ ├── custom │ ├── css │ │ └── index.scss │ └── components │ │ └── MyLayout.vue │ ├── config │ ├── nav.js │ └── sidebar.js │ └── config.mts ├── package.json ├── crawlerConfig.json ├── README.md └── .github └── workflows ├── algolia.yml ├── syncToGitee.yml └── run_script.yml /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | docs/.vitepress/cache 3 | docs/.vitepress/dist -------------------------------------------------------------------------------- /docs/public/41b92f0efa1847f482beb87fd2d28f8e.txt: -------------------------------------------------------------------------------- 1 | 41b92f0efa1847f482beb87fd2d28f8e -------------------------------------------------------------------------------- /docs/public/resume.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ytlyy1773/blog/HEAD/docs/public/resume.pdf -------------------------------------------------------------------------------- /docs/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: / 3 | Sitemap: https://www.jwblog.cn/sitemap.xml 4 | -------------------------------------------------------------------------------- /docs/public/image/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ytlyy1773/blog/HEAD/docs/public/image/favicon.png -------------------------------------------------------------------------------- /docs/public/image/wechat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ytlyy1773/blog/HEAD/docs/public/image/wechat.png -------------------------------------------------------------------------------- /docs/public/image/zhifubao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ytlyy1773/blog/HEAD/docs/public/image/zhifubao.png -------------------------------------------------------------------------------- /docs/public/image/wechatCode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ytlyy1773/blog/HEAD/docs/public/image/wechatCode.png -------------------------------------------------------------------------------- /docs/api/nodejs/nest.md: -------------------------------------------------------------------------------- 1 | # 待定... 2 | 3 |
4 | asdhajksdhaksd 5 |
-------------------------------------------------------------------------------- /docs/api/install-software/docker/redis.md: -------------------------------------------------------------------------------- 1 | # redis 2 | 3 | ```sh 4 | docker run -d --name my_redis -p 6379:6379 --restart always redis:latest --requirepass "yours password" 5 | ``` -------------------------------------------------------------------------------- /docs/chatGPT/search.md: -------------------------------------------------------------------------------- 1 | --- 2 | footer: false 3 | lastUpdated: false 4 | --- 5 | 6 | 7 | 8 | 11 | -------------------------------------------------------------------------------- /docs/web/basics/gap.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: HTML元素之间有间隙 3 | description: HTML元素之间有间隙 4 | --- 5 | 6 | # HTML元素之间有间隙 7 | 8 | ## 问题因素 9 | 10 | * 通常是div有fontsize属性但是里边没有文字导致 11 | 12 | * div或者img设置fontsize为0就可以了 13 | -------------------------------------------------------------------------------- /docs/web/h5/font-deformation.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: font-size在移动端设备上字体变大的问题 3 | description: 如何处理font-size在移动端设备上字体变大的问题 4 | --- 5 | 6 | # font-size在移动端设备上字体变大的问题 7 | 8 | ```css 9 | { 10 | text-size-adjust: none; 11 | -webkit-text-size-adjust: none; 12 | } 13 | ``` 14 | 15 | -------------------------------------------------------------------------------- /docs/web/basics/line.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: CSS实现0.5px的线 3 | description: CSS实现0.5px的线 4 | --- 5 | 6 | # CSS实现0.5px的线 7 | 8 | ## 0.5px 或 0.5rpx 的线 9 | 10 | 核心代码 11 | 12 | ```css 13 | transform: scaleY(0.5); 14 | ``` 15 | 16 | ## 效果示例 17 | 18 | ![0.5px的线](https://www.jwblog.cn/images/code/line_one.png) -------------------------------------------------------------------------------- /docs/web/h5/safe-distance.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: iphone底部安全距离 3 | description: iphone手机底部预览安全距离 4 | --- 5 | 6 | # iphone底部安全距离 7 | 8 | > env() 跟 constant() 需要同时存在,而且顺序不能换 9 | 10 | ```css 11 | { 12 | padding-bottom: constant(safe-area-inset-bottom); 13 | padding-bottom: env(safe-area-inset-bottom); 14 | } 15 | ``` 16 | 17 | -------------------------------------------------------------------------------- /docs/oneself/author-wechat.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 一条懒羊羊的微信小程序 3 | description: 一条懒羊羊的微信小程序推广码 4 | footer: false 5 | --- 6 | 7 | # 一条懒羊羊的微信小程序 8 | 9 | > 制作不易,尊重他人劳动成果 10 | 11 | ## 博主的微信小程序 12 | 13 | ![微信小程序推广码](/public/image/wechatCode.png) 14 | 15 | 16 | -------------------------------------------------------------------------------- /docs/other/system/mac/install-error.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: mac安装第三方软件 3 | description: mac安装第三方软件,mac安装第三方软件遇到问题:无法打开 4 | outline: [2, 3] 5 | --- 6 | 7 | # mac安装第三方软件 8 | 9 | 10 | * 报错 无法打开“***App”,因为它不是从App Store下载 11 | 12 | ![mac安装软件报错](https://www.jwblog.cn/images/api/install001.png) 13 | 14 | * 进入设置 15 | 16 | - 打开设置 17 | - 进入 `隐私与安全性` 18 | - 选择 `App Store和被认可的开发者` 19 | 20 | ![解决mac安装软件报错](https://www.jwblog.cn/images/api/install002.png) -------------------------------------------------------------------------------- /docs/web/basics/use-sass.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: CSS使用sass语法 3 | description: CSS使用sass语法 4 | --- 5 | 6 | # CSS使用sass语法 7 | 8 | ## sass高阶用法 9 | 10 | ```css 11 | @mixin pubBgi($url, $width: 100%, $height: 100%) { 12 | width: $width; 13 | height: $height; 14 | background-image: url('https://www.jwblog.cn/images/user/#{$url}.png'); 15 | background-repeat: no-repeat; 16 | background-size: 100% 100%; 17 | } 18 | .img-box { 19 | @include pubBgi('user', 200px, 200px); 20 | } 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/web/wechat/get-page-options.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: onShow生命周期拿到onLoad生命周期里边的路由传参 3 | description: 微信小程序onShow生命周期拿到onLoad生命周期里边的路由传参 4 | --- 5 | 6 | # onShow生命周期拿到onLoad生命周期里边的路由传参 7 | 8 | ## 实现思路 9 | 10 | > 通过小程序页面栈,获取传参 11 | 12 | ```js 13 | onShow() { 14 | const pages = getCurrentPages() 15 | const curr = pages[pages.length - 1] 16 | console.log('c---',curr.options); 17 | } 18 | ``` 19 | 20 | ## 代码截图 21 | 22 | ![onShow生命周期拿到onLoad生命周期里边的路由传参](https://www.jwblog.cn/images/code/onshow.png) 23 | -------------------------------------------------------------------------------- /docs/web/basics/float.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: CSS清楚浮动 3 | description: CSS清楚浮动的几种方式 4 | --- 5 | 6 | # CSS清楚浮动 7 | 8 | > 得益于flex布局的强大,虽然float已经算是过去式,但是你依旧要会 9 | 10 | ## 兼容性最好-的伪元素方法 :after 11 | 12 | > 给浮动的父盒子提供一个伪元素 13 | 14 | ```css 15 | .father:after { 16 | content: " "; 17 | display: block; 18 | height: 0; 19 | clear: both; 20 | visibility: hidden; 21 | } 22 | ``` 23 | 24 | 25 | ## 额外标签,不建议使用(low且掉档次) 26 | 27 | > 直接在浮动的盒子后边加一个空的标签 28 | 29 | ```html 30 |
31 | ``` 32 | 33 | -------------------------------------------------------------------------------- /docs/web/basics/triangle.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: CSS绘制三角形 3 | description: CSS绘制三角形 4 | --- 5 | 6 | # CSS绘制三角形 7 | 8 | ## css实现代码 9 | ```css 10 | { 11 | width: 0; 12 | height: 0; 13 | border: 40px solid transparent; 14 | border-top: 40px solid red; 15 | } 16 | ``` 17 | 18 | ## 效果 19 | 20 |
21 | 22 | 23 | 31 | -------------------------------------------------------------------------------- /docs/web/basics/preview.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Html预览word,pdf,excel 3 | description: Html预览word,pdf,excel 4 | --- 5 | 6 | # Html预览word,pdf,excel 7 | 8 | > 核心就是` 19 | 20 | 21 | ``` 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "dev": "vitepress dev docs", 4 | "build": "vitepress build docs", 5 | "build:github": "cross-env BUILD_ENV=vercel vitepress build docs", 6 | "preview": "vitepress preview docs" 7 | }, 8 | "dependencies": { 9 | "animate.css": "^4.1.1", 10 | "ant-design-vue": "^4.0.3", 11 | "openai": "^4.10.0", 12 | "vitepress": "^1.3.3" 13 | }, 14 | "devDependencies": { 15 | "cross-env": "^7.0.3", 16 | "sass": "^1.67.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /docs/web/basics/clear-array.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Array常见的两种重置方法对比 3 | description: Array常见的两种重置方法对比 4 | --- 5 | 6 | # Array常见的两种重置方法对比 7 | 8 | ## Array === [] 9 | 10 | > 实质上是创建了一个新数组,并将Array指向它,Array的指向发生变化,并没有去修改原数组 11 | 12 | ```js 13 | const list = [1,2,4] 14 | const copyList = list 15 | list = [] 16 | console.log(list) 输出>>> [] 17 | console.log(copyList) 输出>>> [1,2,4] 18 | 19 | ``` 20 | 21 | ## length设置为0 22 | 23 | > 设置lenght属性为0本质上是改变了数组的length属性,修改了原数组,会影响所有该元素的浅拷贝对象 24 | 25 | ```js 26 | const list = [1,2,4] 27 | const copyList = list 28 | list.length = 0 29 | console.log(list) 输出>>> [] 30 | console.log(copyList) 输出>>> [] 31 | ``` 32 | 33 | -------------------------------------------------------------------------------- /docs/web/wechat/prohibit-scrolling.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 微信小程序出现弹窗页面禁止滚动 3 | description: 微信小程序出现弹窗页面禁止滚动 4 | --- 5 | 6 | # 微信小程序出现弹窗页面禁止滚动 7 | 8 | ## overflow属性 9 | 10 | > 默认值visible 11 | 12 | ```js 13 | // 原理 14 | 弹窗出现的时候动态设置overflow: hidden; 15 | 弹窗关闭的时候改回来设置overflow: visible; 16 | 17 | // css 当前页面设置 18 | page { 19 | min-height: 100vh; 20 | } 21 | 22 | // html标签的行内样式 23 | 32 | ``` 33 | 34 | catchtouchmove接受一个布尔值,true就是禁止背景滚动,动态设置一个变量控制这个行内样式就可以了 35 | 36 | -------------------------------------------------------------------------------- /docs/web/h5/limit-back.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 限制浏览器返回 3 | description: vue代码里边如何限制浏览器返回 4 | --- 5 | 6 | # 限制浏览器返回 7 | 8 | > 用途,H5页面有内容返回增加一个弹窗提醒 9 | 10 | ## 代码 11 | 12 | * 不同于VueRouter里边跳转的replace方法可以做到不能跳转回上一页 13 | * 限制无法回退页面 14 | 15 | ```js-vue 16 | onMounted(() => { 17 | history.pushState(null, null, document.URL) 18 | window.addEventListener('popstate', backPage) 19 | }) 20 | function backPage() { 21 | history.pushState(null, null, document.URL) 22 | if (true) { 23 | // 满足限制条件 open popup 24 | } else { 25 | window.removeEventListener('popstate', backPage) 26 | history.go(-1) 27 | } 28 | } 29 | ``` 30 | 31 | -------------------------------------------------------------------------------- /docs/web/vue/bug-table.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: el-table设置高度之后合计行不显示解决方法 3 | description: el-table设置高度之后合计行不显示解决方法 4 | --- 5 | 6 | # el-table设置高度之后合计行不显示解决方法 7 | 8 | ## 示例 9 | 10 | ::: info 问题核心 11 | ```js-vue 12 | 的doLayout属性 13 | ``` 14 | > `doLayout` 对 Table 进行重新布局。 当表格可见性变化时,您可能需要调用此方法以获得正确的布局 15 | ::: 16 | 17 | 18 | ::: tip vue2解决方案 19 | ```js-vue 20 | updated() { 21 | this.$nextTick(() => { 22 | this.$refs.table.doLayout() 23 | }) 24 | } 25 | ::: 26 | 27 | ::: tip vue3解决方案 28 | ```js-vue 29 | const divRefs: Ref = ref() 30 | onUpdated(() => { 31 | nextTick(() => { 32 | divRefs.doLayout() 33 | }) 34 | }) 35 | ::: 36 | -------------------------------------------------------------------------------- /docs/web/harmony/aspect-ratio.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Harmony 实现宽高等比 3 | description: 鸿蒙实现宽高等比 4 | --- 5 | 6 | # Harmony 实现宽高等比 7 | > 一行代码实现宽高等比 8 | 9 | ::: info 借助`aspectRatio`属性 10 | > `aspectRatio: number` 指定当前组件的宽高比
11 | > `aspectRatio = width/height` 12 | ```js 13 | build() { 14 | Row() { 15 | Row() 16 | .width(100) 17 | .backgroundColor(Color.Blue) 18 | .aspectRatio(1) // [!code error] 19 | Row() 20 | .width(100) 21 | .backgroundColor(Color.Red) 22 | .aspectRatio(16 / 8) // [!code error] 23 | } 24 | .height('100%') 25 | } 26 | ``` 27 | - `aspectRatio`的值可以是 `1` 宽高等比 28 | - `aspectRatio`的值可以是 `16 / 9` >>> 16 * 9的比例 29 | ::: 30 | 31 | 32 | -------------------------------------------------------------------------------- /docs/web/vue/css-use-vue.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 在css中使用vue的变量 3 | description: 在css中使用vue的变量 4 | --- 5 | 6 | # 在css中使用vue的变量 7 | 8 | ## 原理 9 | 10 | - 使用vue的动态行内样式,也就是 `:style="{ '--color': color }"` 11 | - 动态绑定一个css变量 `--color` 12 | - 在class中使用 `var()` 函数去使用这个变量 13 | 14 | ## 示例 15 | 16 | ::: info 使用示例 17 | 18 | html 19 | ```html 20 |
杰夫贝佐斯
21 |
change
22 | ``` 23 | 24 | js 25 | ```js 26 | const color = ref() 27 | const change = () => { 28 | color.value = 'red' 29 | } 30 | ``` 31 | 32 | css 33 | ```css 34 | .demo-text { 35 | color: var(--color); 36 | } 37 | ``` 38 | ::: 39 | 40 | -------------------------------------------------------------------------------- /docs/other/tools/web/collect.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 前端开发工具集 3 | description: 前端开发工具,常用网站推荐 4 | outline: [2, 3] 5 | --- 6 | 7 | # 前端开发工具 8 | 9 | > 工欲善其事,必先利其器 10 | 11 | ## 软件 12 | 13 | ### nvm 14 | 15 | 支持 `mac` 和 `win`   [官网直通车   🚘](https://github.com/nvm-sh/nvm) 16 | 17 | * 使用阿里镜像源 18 | 19 | ```sh 20 | nvm npm_mirror https://npmmirror.com/mirrors/npm/ 21 | ``` 22 | 23 | ```sh 24 | nvm node_mirror https://npmmirror.com/mirrors/node/ 25 | ``` 26 | 27 | ## 网站 28 | 29 | ### TinyPNG 30 | 31 | > 无损压缩图片 32 | 33 | 支持 `mac` 和 `win`   [官网直通车   🚘](https://tinify.cn/) 34 | 35 | TinyPNG使用智能有损压缩技术将您的WebP, PNG and JPEG图片的文件大小降低。 通过选择性的减少图片中的颜色,只需要很少的字节数就能保存数据。 对视觉的影响几乎不可见,但是在文件大小上有非常大的差别。 -------------------------------------------------------------------------------- /docs/web/wechat/api-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 微信request的二次封装 3 | description: 微信使用promise对request的二次封装 4 | --- 5 | 6 | # 微信request的二次封装 7 | 8 | ## 代码 9 | 10 | ::: info 微信请求的二次封装 11 | ```js 12 | const baseUrl = "http://www.baidu.com/"; 13 | 14 | export const request = ({ url, method, data }) => { 15 | new Promise((resolve, reject) => { 16 | wx.request({ 17 | url: `${baseUrl}${url}`, 18 | data, 19 | method, 20 | header: { 21 | "content-type": "application/json", // 默认值 22 | }, 23 | success: (res) => { 24 | // 请求成功,就将成功的数据返回出去 25 | resolve(res); 26 | }, 27 | fail: (err) => { 28 | reject(err); 29 | }, 30 | }); 31 | }); 32 | }; 33 | ``` 34 | ::: 35 | 36 | -------------------------------------------------------------------------------- /docs/web/basics/wrap.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: CSS解决纯英文文字不会自动换行 3 | description: CSS解决纯英文文字不会自动换行 4 | --- 5 | 6 | # CSS解决纯英文文字不会自动换行 7 | 8 | > 代码不规范,亲人两行泪 9 | 10 | ## 示例 11 | 12 | > 只需要两行代码就可以搞定 13 | 14 | ```css 15 | { 16 | word-wrap: break-word; 17 | word-break: break-all; 18 | } 19 | ``` 20 | 21 | ## 效果对比 22 | 23 |
asdhaklssdhaklsdhaklsdhklasdhkdhaklsdhklaasdhaklssdhaklsdhaklsdhklasdhkdhaklsdhklasdhkasdhaklssdhaklsdhaklsdhklasdhkdhaklsdhklasdhk
24 | 25 |
asdhaklssdhaklsdhaklsdhklasdhkdhaklsdhklaasdhaklssdhaklsdhaklsdhklasdhkdhaklsdhklasdhkasdhaklssdhaklsdhaklsdhklasdhkdhaklsdhklasdhk
26 | 27 | 34 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/index.mts: -------------------------------------------------------------------------------- 1 | const imgUrl = Object.freeze('https://www.jwblog.cn/images/') 2 | 3 | import type { Theme } from 'vitepress' 4 | import DefaultTheme from "vitepress/theme"; 5 | import 'animate.css'; 6 | import MyLayout from '../custom/components/MyLayout.vue' 7 | // 引入antd组件库 8 | import "ant-design-vue/dist/reset.css"; 9 | import { Button, Input, Modal } from "ant-design-vue"; 10 | // 自定义主题颜色 11 | import "../custom/css/index.scss"; 12 | 13 | export default { 14 | extends: DefaultTheme, 15 | Layout: MyLayout, 16 | enhanceApp({ app }) { 17 | app.use(Button) 18 | app.use(Input) 19 | app.use(Modal) 20 | app.config.globalProperties.$filterImgUrl = (val: string) => { 21 | return val.indexOf('http') !== -1 ? val : `${imgUrl}${val}` 22 | } 23 | }, 24 | } as Theme 25 | 26 | -------------------------------------------------------------------------------- /docs/oneself/author.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 一条懒羊羊的联系方式 3 | description: 一条懒羊羊的联系方式,赞助一条懒羊羊 4 | footer: false 5 | --- 6 | 7 | # 一条懒羊羊的联系方式 8 | 9 | > 制作不易,尊重他人劳动成果 10 | 11 | ## 联系方式 12 | 13 | ::: warning 邮箱 14 | 15 | > 如有建议、内容错误请发送邮箱联系作者 16 | 17 | ```js 18 | jiangwan1773@163.com 19 | ``` 20 | ::: 21 | 22 | ## 成为网站的赞助者 23 | 24 | ::: tip 扫码赞助 25 |
26 | 微信赞助 27 | 支付宝赞助 28 |
29 | ::: 30 | 31 | 32 | -------------------------------------------------------------------------------- /docs/other/tools/collect.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 开发工具集 3 | description: 多年从事开发工作,整理的工具集 4 | --- 5 | 6 | # 开发工具集 7 | 8 | > 工欲善其事,必先利其器 9 | ## 软件推荐 10 | 11 | ::: info utools 12 | > 支持 `mac` 和 `win`   [官网直通车   🚘](https://www.u.tools) 13 | ```js 14 | 新一代效率工具平台,搭配插件使用yyds 15 | ``` 16 | ::: 17 | 18 | ::: info Snipaste 19 | > 支持 `mac` 和 `win`   [官网直通车   🚘](https://zh.snipaste.com) 20 | ```js 21 | 简单但强大的 截图 + 贴图 + 取色器 工具 22 | ``` 23 | ::: 24 | 25 | ::: info ditto 26 | > 支持 `win`   [官网直通车   🚘](https://ditto-cp.sourceforge.io) 27 | ```js 28 | 剪切版工具,比win自带的剪切版多了搜索功能 29 | ``` 30 | ::: 31 | 32 | ::: info icopy 33 | > 支持 `mac`   [官网直通车   🚘](https://www.better365.cn/icopy.html) 34 | ```js 35 | 剪切版工具,可以弥补mac没有剪切版,平替可以用Paste(收费) 36 | ``` 37 | ::: 38 | 39 | -------------------------------------------------------------------------------- /crawlerConfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "index_name": "一条懒羊羊", 3 | "start_urls": ["http://www.jwblog.cn"], 4 | "rateLimit": 8, 5 | "maxDepth": 10, 6 | "selectors": { 7 | "lvl0": { 8 | "selector": "", 9 | "defaultValue": "Documentation" 10 | }, 11 | "lvl1": ".content h1", 12 | "lvl2": ".content h2", 13 | "lvl3": ".content h3", 14 | "lvl4": ".content h4", 15 | "lvl5": ".content h5", 16 | "content": ".content p, .content li", 17 | "lang": { 18 | "selector": "/html/@lang", 19 | "type": "xpath", 20 | "global": true 21 | } 22 | }, 23 | "selectors_exclude": [ 24 | "aside", 25 | ".page-footer", 26 | ".next-and-prev-link", 27 | ".table-of-contents" 28 | ], 29 | "custom_settings": { 30 | "attributesForFaceting": ["lang", "tags"] 31 | }, 32 | "js_render": true 33 | } 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Blog 2 | 3 | 基于vitepress开发的个人博客 4 | 5 | ## 核心亮点 6 | 7 | * 多样性的前端知识 8 | 9 | * 提交代码到一个代码仓库自动同步其他代码仓库 10 | 11 | * 自动打包发布github pages网站 12 | 13 | * 运行linux服务器脚本执行拉取代码、打包部署操作 14 | 15 | ## 网站链接 16 | 17 | - :car: [官网](http://www.jwblog.cn) 18 | 19 | - :car: [国际官网访问](https://jwblog.vercel.app) 20 | 21 | ## 源码链接 22 | 23 | - :beginner: [github仓库地址](https://github.com/ytlyy1773/blog) 24 | 25 | - :beginner: [gitee仓库地址](https://gitee.com/ytlyy1773/blog) 26 | 27 | ## 环境 28 | 29 | - node >= v18 30 | 31 | - pnpm | yarn 32 | 33 | ## 启动命令 34 | 35 | ```pnpm 36 | pnpm dev 37 | ``` 38 | 39 | ## 赞助 40 |
41 | 微信赞助 42 | 支付宝赞助 43 |
44 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/custom.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --vp-home-hero-name-color: transparent; 3 | --vp-home-hero-name-background: -webkit-linear-gradient(120deg, #bd34fe 30%, #41d1ff); 4 | --vp-home-hero-image-background-image: linear-gradient(-45deg, #bd34fe 50%, #47caff 50%); 5 | --vp-home-hero-image-filter: blur(40px); 6 | --vp-button-brand-bg: #5d86ff; 7 | --vp-button-brand-hover-bg: #3366ff; 8 | --vp-c-indigo-1: #3366ff; 9 | } 10 | 11 | .ant-input { 12 | margin: 8px 0; 13 | } 14 | 15 | .vp-dja { 16 | display: flex; 17 | justify-content: center; 18 | align-items: center; 19 | } 20 | 21 | .cp-span-warn { 22 | display: inline-block; 23 | border-radius: 4px; 24 | padding: 3px 6px; 25 | background-color: #ffebec; 26 | transition: color 0.25s, background-color 0.5s; 27 | font-size: var(--vp-code-font-size); 28 | color: #fc3b40; 29 | } -------------------------------------------------------------------------------- /docs/web/vue/resetData.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Vue2重置data里边的数据 3 | description: Vue2重置data里边的数据 4 | --- 5 | 6 | # Vue2重置data里边的数据 7 | 8 | > 局限于vue2 9 | 10 | ## 初始化组件中的所有数据 11 | 12 | ```js-vue 13 | Object.assign(this.$data,this.$options.data()) 14 | ``` 15 | 16 | ## 初始化组件中某个对象中的数据 17 | 18 | ```js-vue 19 | Object.assign(this.$data.form,this.$options.data().form) 20 | ``` 21 | 22 | ## 重置方法总结 23 | ```js-vue 24 | Object.assign(this.$data,this.$options.data()) 25 | // 方法慎用 26 | 会导致BUG 生命周期请求接口返回的数据也会清空,只能是搭配使用 27 | 28 | // 重置所有数据方法 29 | reSetData( 30 | Object.assign(this.$data,this.$options.data()) 31 | this.getQueryData() 32 | ) 33 | 34 | // eg:BUG实例--生命周期有请求接口赋值数据 35 | created() { 36 | this.getQueryData() 37 | } 38 | methods: { 39 | async getQueryData() { 40 | const res = await getPost({}) 41 | // 赋值 42 | res.code == 200 && (this.formObj = res.data) 43 | } 44 | } 45 | ``` 46 | -------------------------------------------------------------------------------- /docs/web/basics/is-NaN.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: js判断内容是不是是NaN 3 | description: js判断内容是不是是NaN 4 | --- 5 | 6 | # js判断内容是不是是NaN 7 | 8 | ## 示例 9 | ## isNaN() 函数 10 | > isNaN() 是 JavaScript 中的一个全局函数,用于判断一个值是否为 NaN。该函数的参数可以是任何类型的值,如果该值为 NaN,则返回 true,否则返回 false。 11 | ```js 12 | console.log(isNaN(NaN)); // true 13 | console.log(isNaN(123)); // false 14 | console.log(isNaN("abc")); // true 15 | ``` 16 | 17 | ## Number.isNaN() 函数 18 | > Number.isNaN() 是 JavaScript 中 Number 对象的一个静态方法,用于判断一个值是否为 NaN。该函数的参数可以是任何类型的值,如果该值为 NaN,则返回 true,否则返回 false。 19 | ```js 20 | console.log(isNaN(NaN)); // true 21 | console.log(isNaN(123)); // false 22 | console.log(isNaN("abc")); // true 23 | ``` 24 | 25 | ## Object.is() 方法 26 | > Object.is() 是 JavaScript 中 Object 对象的一个静态方法,用于判断两个值是否严格相等 27 | ```js 28 | console.log(Object.is(NaN, NaN)); // true 29 | console.log(Object.is(123, 123)); // true 30 | console.log(Object.is("abc", "abc")); // true 31 | ``` -------------------------------------------------------------------------------- /docs/web/wechat/global-share.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 微信小程序全局添加分享功能 3 | description: 微信小程序全局添加分享功能 4 | --- 5 | 6 | # 微信小程序全局添加分享功能 7 | 8 | > 页面本身的分享方法会覆盖全局的分享方法 9 | 10 | ## 缺陷 & 思路 11 | 12 | - 全局添加分享功能,每个子页面都需要有一个分享方法(微信原生Api已经提供) 13 | 14 | - 页面本身的分享会覆盖全局封装的方法 15 | 16 | - 支持自定义的显示内容很少(微信小程序本身导致) 17 | 18 | ## 实现功能源代码 19 | 20 | > 全局分享功能,页面有空的onShareAppMessage()会不生效 21 | 22 | ```js 23 | (function(){ 24 | const PageTmp = Page; 25 | Page = (pageConfig) => { 26 | // 设置全局默认分享 27 | pageConfig = Object.assign({ 28 | onShareAppMessage:function () { 29 | return { 30 | title:'默认文案title', 31 | path:'默认分享路径+id', 32 | imageUrl:'默认分享图片', 33 | }; 34 | } 35 | },pageConfig); 36 | PageTmp(pageConfig); 37 | }; 38 | })(); 39 | ``` 40 | 41 | ## 代码截图 42 | 43 | ![全局代码](https://www.jwblog.cn/images/code/share.png) 44 | 45 | ![局部代码](https://www.jwblog.cn/images/code/replaceShare.png) 46 | 47 | -------------------------------------------------------------------------------- /docs/web/basics/sleep.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: JavaScript 实现 Sleep(伪 sleep) 3 | description: 如何在 JavaScript 中实现 sleep 功能,通过 Promise 结合 setTimeout 实现异步暂停。详细介绍了核心实现方式并说明了为什么在此场景下无需手动清除定时器。 4 | outline: [2, 3] 5 | --- 6 | 7 | # JavaScript 实现 Sleep(伪 sleep) 8 | 9 | 在 JavaScript 中,我们通常用 `setTimeout` 和 `Promise` 结合实现类似 `sleep` 的效果。以下是一个核心示例: 10 | 11 | ### 核心代码 12 | 13 | > 这个代码片段会使当前执行的异步函数暂停 4 秒,然后继续执行。 14 | 15 | ```js 16 | await new Promise(resolve => setTimeout(resolve, 4000)); 17 | ``` 18 | 19 | ### eg 20 | 21 | ```js 22 | async function falseSleep() { 23 | console.log('开始执行----'); 24 | await new Promise(resolve => setTimeout(resolve, 4000)); 25 | console.log('延迟4秒执行----'); 26 | } 27 | ``` 28 | 29 | ## 详细解析 30 | 31 | ### 为什么不需要 `clearTimeout` 32 | 33 | * `setTimeout` 的一次性定时器: 34 | 35 | - 在这个场景中,`setTimeout` 只执行一次,定时器触发后会自动清除。因此,无需手动调用 `clearTimeout`。 36 | 37 | - `resolve` 被调用后,`Promise` 会完成其使命,且定时器已经完成并自动清理。 38 | 39 | * `Promise` 的自动完成: 40 | 41 | - 通过 `resolve` 执行,`Promise` 状态会从 `pending` 变为 `fulfilled`,这时 JavaScript 引擎会清理相关资源。 42 | -------------------------------------------------------------------------------- /.github/workflows/algolia.yml: -------------------------------------------------------------------------------- 1 | name: algolia # 工作流名称 2 | 3 | on: 4 | push: 5 | branches: 6 | - master # 触发条件:当推送到 master 分支时触发此工作流 7 | 8 | jobs: 9 | algolia: 10 | runs-on: ubuntu-latest # 在最新版本的 Ubuntu 环境中运行此作业 11 | 12 | steps: 13 | - uses: actions/checkout@v3 # 步骤1:使用 GitHub 官方的动作检出代码库 14 | 15 | - name: Get the content of algolia.json as config # 步骤2:读取 crawlerConfig.json 文件内容作为配置 16 | id: algolia_config 17 | run: echo "config=$(cat crawlerConfig.json | jq -r tostring)" >> $GITHUB_OUTPUT 18 | # 读取 crawlerConfig.json 文件的内容并转换为字符串格式,然后将其保存到 GitHub Actions 的输出变量中 19 | 20 | - name: Push indices to Algolia # 步骤3:将索引推送到 Algolia 21 | uses: signcl/docsearch-scraper-action@master 22 | env: 23 | APPLICATION_ID: ${{ secrets.APPLICATION_ID }} # 从 GitHub Secrets 中读取 Algolia 应用程序 ID 24 | API_KEY: ${{ secrets.API_KEY }} # 从 GitHub Secrets 中读取 Algolia API 密钥 25 | CONFIG: ${{ steps.algolia_config.outputs.config }} # 使用上一步骤中读取的配置 26 | # 使用 signcl/docsearch-scraper-action 动作,将配置推送到 Algolia 27 | -------------------------------------------------------------------------------- /.github/workflows/syncToGitee.yml: -------------------------------------------------------------------------------- 1 | name: syncToGitee 2 | on: 3 | push: 4 | branches: 5 | - master 6 | jobs: 7 | repo-sync: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Mirror the Github organization repos to Gitee. 11 | uses: Yikun/hub-mirror-action@master 12 | with: 13 | src: 'github/ytlyy1773' 14 | dst: 'gitee/ytlyy1773' 15 | dst_key: ${{ secrets.GITEE_PRIVATE_KEY }} 16 | dst_token: ${{ secrets.GITEE_TOKEN }} 17 | static_list: "blog" # 仓库名字 18 | force_update: true # 强制同步 19 | debug: true # 启用 `debug` 开关 20 | 21 | # - name: Build Gitee Pages 22 | # uses: yanglbme/gitee-pages-action@main 23 | # with: 24 | # # 注意替换为你的 Gitee 用户名 25 | # gitee-username: 'ytlyy1773' 26 | # # 注意在 Settings->Secrets 配置 GITEE_PASSWORD 27 | # gitee-password: ${{ secrets.GITEE_PASSWORD }} 28 | # # 注意替换为你的 Gitee 仓库,仓库名严格区分大小写,请准确填写,否则会出错 29 | # gitee-repo: 'ytlyy1773/blog' 30 | # # 要部署的分支,默认是 master,若是其他分支,则需要指定(指定的分支必须存在) 31 | # branch: github-pages -------------------------------------------------------------------------------- /docs/web/harmony/distinction.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Harmony 属性和参数的区别 3 | description: 鸿蒙属性和参数的区别 4 | --- 5 | 6 | # Harmony 属性和参数的区别 7 | 8 | ::: info 什么是属性 9 | 10 | > 标签后以.开头的就是属性 11 | 12 | ```js 13 | build() { 14 | Row() { 15 | Row() 16 | .width(100) // [!code warning] 17 | .backgroundColor(Color.Blue) // [!code warning] 18 | .aspectRatio(1) // [!code warning] 19 | } 20 | .height('100%') // [!code warning] 21 | } 22 | ``` 23 | ::: 24 | 25 | ::: tip 什么是参数 26 | 27 | > 以对象形式写在标签里边的就是参数 28 | 29 | ```js 30 | build() { 31 | Flex({ 32 | direction: FlexDirection.Row, // [!code error] 33 | justifyContent: FlexAlign.SpaceAround, // [!code error] 34 | wrap: FlexWrap.Wrap // [!code error] 35 | }) { 36 | Row().width(100).height(100).backgroundColor(Color.Blue) 37 | Row().width(100).height(100).backgroundColor(Color.Blue) 38 | Row().width(100).height(100).backgroundColor(Color.Blue) 39 | Row().width(100).height(100).backgroundColor(Color.Blue) 40 | Row().width(100).height(100).backgroundColor(Color.Blue) 41 | } 42 | } 43 | ``` 44 | ::: 45 | 46 | 47 | -------------------------------------------------------------------------------- /docs/web/vue/dialog/dialog.ts: -------------------------------------------------------------------------------- 1 | import { ref, createApp } from 'vue' 2 | // @ts-ignore 3 | import dialogModule from './dialogModule.vue' 4 | 5 | interface OptionsType { 6 | title?: string // 标题 7 | mainText?: string // 内容 8 | width?: string // 宽度 9 | LeftText?: string // 左侧按钮文字 10 | LeftType?: string // 左侧按钮样式,支持elementUI组件库按钮组type 11 | RightText?: string // 右侧按钮文字 12 | RightType?: string // 右侧按钮样式,支持elementUI组件库按钮组type 13 | } 14 | 15 | const visible = ref(false) 16 | 17 | export default function (options: OptionsType = {}) { 18 | return new Promise((resolve, reject) => { 19 | // 创建dom实例挂载在body上边 20 | const div = document.createElement('div') 21 | div.style.width = '0' 22 | div.style.height = '0' 23 | document.body.appendChild(div) 24 | const module = createApp(dialogModule, { 25 | modelValue: visible, 26 | resolve: () => { 27 | resolve('成功返回') 28 | div.remove() 29 | }, 30 | reject: () => { 31 | reject('失败返回') 32 | div.remove() 33 | }, 34 | ...options 35 | }) 36 | module.mount(div) 37 | visible.value = true 38 | }) 39 | } -------------------------------------------------------------------------------- /docs/web/basics/dashed-line.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: CSS控制虚线间距虚线长度 3 | description: CSS控制虚线间距虚线长度 4 | --- 5 | 6 | # CSS控制虚线间距虚线长度 7 | 8 | ## 示例 9 | 10 | ::: info 源代码 11 |
12 | 13 | ```css 14 | { 15 | margin: 26px 0 28px 0; 16 | width: 498px; 17 | padding: 1px 30px; 18 | box-sizing: border-box; 19 | background-image: linear-gradient( 20 | to right, 21 | #c2daff 35%, 22 | rgba(255, 255, 255, 0) 0% 23 | ); /* 35%设置虚线点x轴上的长度 */ 24 | background-position: bottom; /* top配置上边框位置的虚线 */ 25 | background-size: 10px 1px; /* 第一个参数设置虚线点的间距;第二个参数设置虚线点y轴上的长度 */ 26 | background-repeat: repeat-x; 27 | } 28 | ``` 29 | ::: 30 | 31 | 47 | -------------------------------------------------------------------------------- /docs/.vitepress/custom/css/index.scss: -------------------------------------------------------------------------------- 1 | :root { 2 | --primary: #1677ff; 3 | --primary-hover: #4096ff; 4 | --vp-home-hero-name-color: transparent; 5 | --vp-home-hero-name-background: -webkit-linear-gradient(120deg, #bd34fe 30%, #41d1ff); 6 | --vp-home-hero-image-background-image: linear-gradient(-45deg, #bd34fe 50%, #47caff 50%); 7 | --vp-home-hero-image-filter: blur(40px); 8 | --vp-button-brand-bg: var(--primary); 9 | --vp-button-brand-hover-bg: var(--primary-hover); 10 | --vp-c-indigo-1: var(--primary); 11 | } 12 | 13 | .main .vp-doc .github-dark { 14 | background: rgb(40, 44, 52); 15 | } 16 | 17 | .ant-input { 18 | margin: 8px 0; 19 | } 20 | 21 | .vp-dja { 22 | display: flex; 23 | justify-content: center; 24 | align-items: center; 25 | } 26 | 27 | .cp-span-warn { 28 | display: inline-block; 29 | border-radius: 4px; 30 | padding: 3px 6px; 31 | background-color: #ffebec; 32 | transition: color 0.25s, background-color 0.5s; 33 | font-size: var(--vp-code-font-size); 34 | color: #fc3b40; 35 | } 36 | 37 | .VPFooter .message { 38 | display: flex; 39 | justify-content: center; 40 | align-items: center; 41 | } -------------------------------------------------------------------------------- /docs/other/system/win/clear-icon.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 如何除去Windows的快捷方式小图标 3 | description: 多年从事开发工作,整理的工具集 4 | --- 5 | 6 | # 如何除去Windows的快捷方式小图标 7 | 8 | ## 去除前后效果对比 9 | ::: danger 去除之后(after) 10 | 11 | ::: 12 | ::: info 去除之前(before) 13 | 14 | ::: 15 | 16 | ## 具体实现 17 | ::: tip 步骤 18 | - 新建`clear.txt`文件 19 | 20 | > 在win桌面新建一个`clear.txt`文件 21 | 22 | - txt文件写入以下脚本内容 23 | 24 | ```bash 25 | reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Icons" /v 29 /d "%systemroot%\system32\imageres.dll,197" /t reg_sz /f 26 | taskkill /f /im explorer.exe 27 | attrib -s -r -h "%userprofile%\AppData\Local\iconcache.db" 28 | del "%userprofile%\AppData\Local\iconcache.db" /f /q 29 | start explorer 30 | pause 31 | ``` 32 | 33 | - 修改txt文件后缀名为 `.bat` 34 | 35 | > 变为可执行文件 36 | 37 | ```bash 38 | .txt >>> .bat 39 | ``` 40 | 41 | - 鼠标右键 `管理员` 执行.bat文件 42 | 43 | ::: 44 | 45 | 50 | -------------------------------------------------------------------------------- /docs/web/vue/freeze.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: vue中freeze和Readonly的区别 3 | description: Object.freeze() | Ts的Readonly 在vue中的应用以及区别 4 | --- 5 | 6 | # vue中freeze和Readonly的区别 7 | 8 | ## 相似之处 9 | - TypeScript 的 Readonly 和 JavaScript 的 Object.freeze 都会使对象变为只读,即无法修改对象的属性或方法。 10 | - 两者都可以用于防止意外修改对象,从而提高代码的安全性。 11 | 12 | ## 不同点 13 | | 区别 | Readonly | Object.freeze | 14 | |:---|:---|:---| 15 | | 作用范围 | 是一种 TypeScript 类型,它可以用于任何类型的值,包括对象、数组、元组等等 | Object.freeze 只能用于 JavaScript 对象 | 16 | | 类型检查 | 可以通过 TypeScript 的类型检查来确保对象是只读的 | Object.freeze 只能在运行时检查对象是否被冻结 | 17 | | 深度冻结 | Readonly 仅对对象本身进行冻结,而不会冻结对象中的嵌套对象 | Object.freeze 会递归冻结对象中的所有嵌套对象 | 18 | | 性能 | Readonly 的性能通常优于 Object.freeze,因为它不需要进行递归冻结 | | 19 | 20 | 21 | ## vue中的使用 22 | ```js{5} 23 | export default { 24 | data() { 25 | return { 26 | star: ['杰夫贝佐斯', '马斯克'], 27 | userInfo: Object.freeze({ name: '一条懒羊羊', age: 25 }) // 使用 Object.freeze() 会失去响应式 // [!code focus] 28 | } 29 | } 30 | } 31 | ``` 32 | 33 | 34 | ## 总结 35 | - `Readonly` 和 `Object.freeze` 都是使对象变为只读的有效方法。 36 | - 在 `TypeScript` 代码中,建议使用 `Readonly`,因为它可以提供更好的类型检查和性能。 37 | - 在 `JavaScript` 代码中,可以使用 `Object.freeze` 来冻结对象,但需要注意其性能问题。 38 | -------------------------------------------------------------------------------- /docs/web/knowledge/npm-registry.md: -------------------------------------------------------------------------------- 1 | # 使用阿里云npm镜像加速 2 | 3 | > 阿里云npm镜像地址链接 4 | 5 | [阿里云官方镜像站   🚘](https://npmmirror.com/) 6 | 7 | ## 什么是npm? 8 | 9 | `npm(node package manager)` 是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题. 10 | 11 | **常见的使用场景有以下几种:** 12 | 13 | * 允许用户从NPM服务器下载别人编写的第三方包到本地使用。 14 | 15 | * 允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用。 16 | 17 | * 允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用。 18 | 19 | * 由于新版的nodejs已经集成了npm,所以之前npm也一并安装好了。同样可以通过输入 "npm -v" 来测试是否成功安装。命令如下,出现版本提示表示安装成功 20 | 21 | > npm可以理解为一个命令行工具,它的使命就是帮你为项目自动安装所依赖的开发包。 22 | 23 | maven是java包依赖管理工具,node.js包管理工具是npm。可以这么去理解。 24 | 25 | `http://registry.npmjs.org` 是 `npm` 的默认的开发包仓库,npm 默认的下载地址在国外,下载速度较慢。但是切换成国内的镜像源包的下载速度会很快。 26 | 27 | ## 查看npm源地址设置 28 | 29 | ```sh 30 | npm config get registry 31 | ``` 32 | 33 | **输出官方镜像地址** 34 | 35 | ```sh 36 | https://registry.npmjs.org 37 | ``` 38 | 39 | ## 配置阿里巴巴镜像地址 40 | 41 | [阿里云官方镜像站   🚘](https://npmmirror.com/) 42 | 43 | npm阿里云地址: `http://www.npmmirror.com` 44 | 45 | ```sh 46 | npm config set registry https://registry.npmmirror.com 47 | ``` 48 | 49 | ## 解除镜像并恢复到官方源 50 | 51 | > 重新设置npm下载地址为npm官方地址即可 52 | 53 | ```sh 54 | npm config set registry https://registry.npmjs.org 55 | ``` 56 | -------------------------------------------------------------------------------- /docs/web/h5/handle-delay.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: iphone单机事件有300毫秒延迟的处理 3 | description: 面试经典问题,iphone单机事件有300毫秒延迟的处理 4 | --- 5 | 6 | # iphone单机事件有300毫秒延迟的处理 7 | 8 | > iphone手机H5页面有300毫秒延迟的处理 9 | 10 | ## 常见的处理方法 11 | 12 | * 禁用缩放 13 | * FastClick插件 14 | * touchstart事件代替click 15 | 16 | ## 禁用缩放 17 | > html声明 18 | ```html 19 | 20 | ``` 21 | 22 | ## FastClick插件 23 | ```js 24 | 1.npm i FastClick 25 | 2. 26 | 27 | document.addEventListener('DOMContentLoaded', function() { 28 | FastClick.attach(document.body); 29 | }, false); 30 | 31 | // vue在Mounted声明周期里边声明挂载 32 | FastClick.attach(document.body); 33 | ``` 34 | 35 | 36 | ## touchstart事件代替click 37 | ```js 38 |
单机事件
39 | 40 | function handle(type) { 41 | // 这里必须做区分,安卓和iphone在这里区别还是很大的,安卓走click,苹果走touchstart 42 | const phone = navigator.userAgent; 43 | const isAndroid = phone.indexOf('Android') > -1 || phone.indexOf('Adr') > -1; //android安卓 44 | const isiOS = !!phone.match(/(i[^;]+;( U;)? CPU.+Mac OS X/); //ios苹果 45 | if(isAndroid && type === 2) { 46 | return 47 | }, 48 | if(isiOS && type === 1) {} 49 | } 50 | ``` -------------------------------------------------------------------------------- /docs/web/vue/dialog/core.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: vue封装dialog弹窗 3 | description: 在vue项目中使用函数式封装一个dialog弹窗 4 | --- 5 | 6 | # 封装dialog弹窗 7 | 8 | > Vue3 + ts函数式封装 9 | 10 | ## 演示 11 | 12 | 唤醒弹窗 13 | 14 | 31 | 32 | ## 代码说明 33 | 34 | ### vue文件使用代码 35 | ```js-vue 36 | // ======= 依赖引入 ======= 37 | import { getCurrentInstance } from 'vue' 38 | 39 | // ======= 变量声明 ======= 40 | const { proxy }: any = getCurrentInstance() 41 | 42 | // ======= 函数声明 ======= 43 | function showDialog() { 44 | // 使用全局封装的弹窗 45 | proxy.$dialog().then(res => { 46 | // 确定事件 47 | }).catch(err => { 48 | // 取消事件 49 | }) 50 | } 51 | ``` 52 | 53 | ### 函数封装: 源代码 54 | 55 | <<< ./dialog.ts 56 | 57 | ### vue组件封装 58 | ::: details 源代码 59 | <<< ./dialogModule.vue 60 | ::: 61 | 62 | -------------------------------------------------------------------------------- /docs/other/tools/internet.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 科学上网 3 | description: 提供丰富的科学上网资源,包括白嫖和付费选项,不同协议和节点。您可以根据自己的预算和需求,选择最适合的方案。 4 | --- 5 | 6 | # 科学上网 7 | 8 | ::: danger 一元机场 9 | 10 | > 性价比超高 `年费12¥`   [官网直通车   🚘](https://xn--4gq62f52gdss.ink/#/register?code=r1GYrham) 11 | 12 | ```js 13 | 全平台支持(ios + android + win + mac) 14 | ``` 15 | ::: 16 | 17 | ::: tip iKuuu 18 | 19 | > 账户上充值 `1元` 可以一直白嫖   [官网直通车   🚘](https://ikuuu.pw/auth/register?code=ndXW) 20 | 21 | ```js 22 | 全平台支持(ios + android + win + mac) 23 | ``` 24 | ::: 25 | 26 | ::: info 树洞 27 | 28 | > 稳定支持chatGpt `年费150rmb+`   [官网直通车   🚘](https://com.ss.sssuusss.com/auth/register?code=QAVGMB) 29 | 30 | ```js 31 | 全平台支持(ios + android + win + mac) 32 | ``` 33 | ::: 34 | 35 | ::: info catnet 36 | 37 | > **多等级使用**   [官网直通车   🚘](https://dash.catnet.uk/#/register?code=KyYQ3heF) 38 | 39 | * 低配 `25/月` 40 | 41 | * 高配 `50/月` 42 | 43 | ```js 44 | 全平台支持(ios + android + win + mac) 45 | ``` 46 | ::: 47 | 48 | ::: info 魔戒 49 | 50 | > **按量购买** 不限时间,按流量包购买   [官网直通车   🚘](https://www.mojie.me/#/register?code=cLGFJLme) 51 | 52 | * 130G流量 `¥ 14.9` 53 | 54 | * 3600G流量 `¥ 279` 55 | 56 | * `等等...` 57 | 58 | ```js 59 | 全平台支持(ios + android + win + mac) 60 | ``` 61 | ::: -------------------------------------------------------------------------------- /docs/api/nodejs/sql.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: sql 3 | description: 常用的 sql 语句。 4 | outline: [2, 3] 5 | --- 6 | 7 | # 常用的 sql 语句 8 | 9 | ## 清空数据库表数据 10 | 11 | 注意不会删除表, 但是会删除表内 **`所有数据`** 12 | 13 | ```sql 14 | -- 设置分隔符以支持存储过程 15 | DELIMITER $$ 16 | 17 | -- 创建存储过程 18 | CREATE PROCEDURE truncate_all_tables() 19 | BEGIN 20 | DECLARE done INT DEFAULT FALSE; 21 | DECLARE tbl_name VARCHAR(255); 22 | DECLARE cur CURSOR FOR 23 | SELECT table_name 24 | FROM information_schema.tables 25 | WHERE table_schema = 'ocr' 26 | AND table_type = 'BASE TABLE'; 27 | DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; 28 | 29 | -- 禁用外键检查 30 | SET FOREIGN_KEY_CHECKS = 0; 31 | 32 | -- 打开游标并循环处理 33 | OPEN cur; 34 | read_loop: LOOP 35 | FETCH cur INTO tbl_name; 36 | IF done THEN 37 | LEAVE read_loop; 38 | END IF; 39 | 40 | -- 动态生成并执行 TRUNCATE 41 | SET @sql = CONCAT('TRUNCATE TABLE `', tbl_name, '`;'); 42 | PREPARE stmt FROM @sql; 43 | EXECUTE stmt; 44 | DEALLOCATE PREPARE stmt; 45 | END LOOP; 46 | 47 | -- 清理和恢复设置 48 | CLOSE cur; 49 | SET FOREIGN_KEY_CHECKS = 1; 50 | END$$ 51 | 52 | -- 恢复默认分隔符 53 | DELIMITER ; 54 | 55 | -- 调用存储过程 56 | CALL truncate_all_tables(); 57 | 58 | -- 删除存储过程(可选) 59 | DROP PROCEDURE truncate_all_tables; 60 | ``` 61 | -------------------------------------------------------------------------------- /docs/web/harmony/show.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Harmony 控制组件是否可见 3 | description: 鸿蒙控制组件是否可见 4 | --- 5 | 6 | # Harmony 控制组件是否可见 7 | 8 | ## 使用条件渲染 9 | ::: info 使用if和else 10 | > 类似于 `vue` 的 `v-if` 11 | ```js 12 | build() { 13 | Column() { 14 | Row() { 15 | if (this.boon) { // [!code error] 16 | Text('使用了文字') 17 | } else { // [!code error] 18 | Button('切换了Button') 19 | } 20 | } 21 | .margin({ top: 200 }) 22 | Toggle({ type: ToggleType.Switch , isOn: $$this.boon }) 23 | .margin({ top: 20 }) 24 | } 25 | .width('100%') 26 | .height('100%') 27 | } 28 | ``` 29 | ::: 30 | 31 | ## visibility属性 32 | > [官网说明](https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/ts-universal-attributes-visibility-0000001428061704-V2) 33 | ::: info 借助`visibility`属性 34 | > 类似于 `vue` 的 `v-show` 35 | - 控制组件是否可见 36 | - `visibility` 效果等效 `css` 的`dispaly: none;` 37 | ```js 38 | build() { 39 | Column() { 40 | Row() { 41 | Text('使用了文字') 42 | .visibility(this.boon ? Visibility.Visible : Visibility.None) // [!code error] 43 | } 44 | .margin({ top: 200 }) 45 | Toggle({ type: ToggleType.Switch , isOn: $$this.boon }) 46 | .margin({ top: 20 }) 47 | } 48 | .width('100%') 49 | .height('100%') 50 | } 51 | ``` 52 | ::: 53 | 54 | ## 其他方案 55 | > 不推荐 56 | - 借助属性`opacity` 57 | - 设置属性元素 `width` 和 `height` 为0 -------------------------------------------------------------------------------- /docs/other/system/linux/command.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: linux常用命令 3 | description: linux系统的常用命令 4 | --- 5 | 6 | # linux常用命令 7 | 8 | ## 个人常用linux命令 9 | 10 | ```bash 11 | ssh-keygen -R ip # 清理服务器密钥 12 | unzip file.zip -d /etc/nginx # 解压文件到指定目录 13 | touch myscript.sh # 新建脚本 14 | mkdir fileName # 新建文件夹 15 | mv moveFileName /path/to/package # 移动文件夹到某个位置 16 | rm -rf fileName # 删除文件夹和文以及子内容 17 | scp fileName root@ip:/root/ # 本地传递文件到服务器/root目录下 18 | ``` 19 | 20 | ## linux文件管理常用命令 21 | ::: info 文件管理 22 | * ls: 列出当前目录下的文件和文件夹。 23 | * cd: 改变当前目录。 24 | * pwd: 显示当前工作路径。 25 | * mkdir: 创建目录。 26 | * rmdir: 删除空目录。 27 | * touch: 创建文件或更新文件的时间戳。 28 | * cp: 复制文件或文件夹。 29 | * mv: 移动或重命名文件或文件夹。 30 | * rm: 删除文件或文件夹。 31 | * rm -rf: 删除文件夹以及子文件。 32 | * cat: 显示文件内容。 33 | * less: 分页查看文件内容。 34 | * more: 逐行查看文件内容。 35 | * head: 显示文件的前几行内容。 36 | * tail: 显示文件的最后几行内容。 37 | * find: 查找文件。 38 | ::: 39 | 40 | ## linux系统管理常用命令 41 | ::: info 系统管理 42 | * whoami: 显示当前登录用户名。 43 | * sudo: 以管理员身份执行命令。 44 | * reboot: 重启系统。 45 | * shutdown: 关闭系统。 46 | * ps: 查看进程状态。 47 | * kill: 终止进程。 48 | * top: 显示系统资源使用情况。 49 | * df: 显示磁盘空间使用情况。 50 | * free: 显示内存使用情况。 51 | * date: 显示日期和时间。 52 | * cal: 显示日历。 53 | ::: 54 | 55 | ## linux网络管理常用命令 56 | ::: info 网络管理 57 | * ping: 测试网络连接。 58 | * ifconfig: 查看网络接口信息。 59 | * netstat: 查看网络连接状态。 60 | * ssh: 建立安全远程连接。 61 | * wget: 下载文件。 62 | * curl: 传输数据。 63 | ::: 64 | 65 | ## linux其他常用命令 66 | ::: info 其他常用命令 67 | * man: 查看命令手册。 68 | * help: 显示命令帮助信息。 69 | * history: 查看命令历史记录。 70 | ::: 71 | -------------------------------------------------------------------------------- /docs/other/blog/up/up-https.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 网站升级https 3 | description: http的网站如何升级到https 4 | --- 5 | 6 | # 网站升级https 7 | 8 | > seo会优先收录具有ssl证书的 9 | 10 | ## 主流证书平台 11 | 12 | * freessl:便宜实惠。  [官网链接   🚘](https://freessl.cn/) 13 | * 阿里云 14 | * 华为云 15 | 16 | ## 申请 17 | 18 | > 可以先试用一下免费证书申请 19 | 20 | 证书域名添加自己的网站: `www.jwblog.cn` 21 | 22 | 进入订单详情里边,点击详情 23 | 24 | 出现3个值 25 | 26 | - 主机记录 27 | - 记录类型 28 | - 记录值 29 | 30 | ## 获取证书 31 | 32 | 1. 进入服务器域名配置页面 33 | 34 | 2. 进入当前域名的解析设置页面 35 | - 当前已经存在一个服务器ip配置的主机记录 36 | 3. 添加一条主机记录 37 | - 将上面的3个值。主机记录、记录类型、记录值添加入相应的内容里边 38 | 39 | 这里配置完成之后生效需要一定的时间,生效之后我们可以获取证书 40 | 41 | > 最快10-30分钟左右生效。如进行过DNS服务器名称修改,则一般需要24-48小时左右生效 42 | 43 | 点击下载证书。服务器平台我们使用的nginx,就下载nginx的证书格式 44 | 45 | 证书内容需要部署到服务器nginx里边 46 | 47 | ## 部署配置证书 48 | 49 | 进入服务器nginx配置文件夹 50 | 51 | 新建 `cert` 文件,linux执行 `mkdir cert` 52 | 53 | cert文件夹下新建两个文件 54 | 55 | > linux使用 `touch full_chain.pem` 命令新建文件 56 | 57 | - full_chain.pem。填入证书文件的 `.pem` 文件的内容 58 | - private.key。填入证书文件的 `.key` 文件的内容 59 | 60 | ::: tip nginx添加证书配置 61 | ```nginx 62 | server { 63 | listen 443 ssl; 64 | server_name www.jwblog.cn; 65 | 66 | if ($server_port !~ 443){ 67 | rewrite ^(/.*)$ https://$host$1 permanent; 68 | } 69 | 70 | # 证书地址 71 | ssl_certificate cert/full_chain.pem; 72 | ssl_certificate_key cert/private.key; 73 | ssl_prefer_server_ciphers on; 74 | } 75 | ``` 76 | ::: 77 | 78 | 执行 `nginx -s reload` -------------------------------------------------------------------------------- /docs/web/vue/packaging-format.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 常见的打包格式 3 | description: 探索Vue项目中的主流打包格式,包括ES6 Modules、CommonJS、UMD等,以及它们的特点、适用场景和配置方法,帮助开发者做出更合适的技术选型。 4 | outline: [2, 3] 5 | --- 6 | 7 | # 常见的打包格式 8 | 9 | ## 打包格式 10 | 11 | ### ESModules 12 | 13 | `ES6 Modules` 14 | 15 | 这是ECMAScript 2015(ES6)提出的模块化标准,使用import和export关键字来导入和导出模块。这种格式在现代浏览器和Node.js中得到了支持,并且是Vue项目中推荐使用的 `模块化标准`。 16 | 17 | ### CommonJS 18 | 19 | `CommonJS` 20 | 21 | 这是Node.js环境中的模块化标准,通过require和module.exports来导入和导出模块。虽然在Vue项目中不常用,但在一些工具和库中仍然可以看到。 22 | 23 | ### UMD 24 | 25 | `UMD` **(Universal Module Definition)** 26 | 27 | > 常用于打包vue的组件库 28 | 29 | 这种格式可以在任何JavaScript环境中使用,包括浏览器环境和Node.js环境。它允许模块在各种环境中工作,但通常不是Vue项目的首选,因为它不是最现代的模块化标准。 30 | 31 | ### System 32 | 33 | `System.js` 34 | 35 | 这是一种动态模块加载器,它支持**多种模块化标准**,包括ES6 Modules、AMD和CommonJS。它允许在浏览器中动态加载模块。 36 | 37 | ### IIFE 38 | 39 | `IIFE` **(Immediately Invoked Function Expression)** 40 | 41 | 这不是一个模块化标准,而是一种在浏览器中创建局部作用域的方式。它通常用于避免全局变量污染,但在现代Vue项目中使用较少。 42 | 43 | 44 | ## 总结 45 | 46 | * 在打包工具(如Webpack、Rollup等)中,你可以指定输出的模块化格式。例如,Webpack允许你在配置文件中设置output部分的libraryTarget选项来定义打包后的格式,如umd、amd、system、commonjs2等。 47 | 48 | * 在Vue项目中,`ESModules` 是最常用的打包格式,因为它提供了更好的树摇 `(tree-shaking)` 支持,可以减少最终打包文件的大小,并且是 `未来JavaScript` 模块化的方向。Vue CLI默认支持ES6模块,使得在Vue项目中使用ES6模块变得非常简单和直接。 49 | 50 | 选择哪种打包格式取决于你的目标环境和需求。例如,如果你需要在浏览器中使用模块,并且需要支持旧版本的浏览器,那么UMD可能是一个不错的选择。如果你的项目是一个库,并且希望它能够在各种环境中被使用,那么UMD也是一个通用的选择。然而,如果你正在构建一个现代的前端应用,并且主要关注现代浏览器,那么ES6 Modules可能是更好的选择。 51 | -------------------------------------------------------------------------------- /docs/web/vue/preview/core.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 封装图片预览功能 3 | description: 在vue中封装一个图片预览功能 4 | --- 5 | 6 | # 封装图片预览功能 7 | 8 | ## 使用 9 | 10 | ::: info 代码 11 | ```js-vue 12 | import preview from './preview.vue' 13 | 14 | 15 | ``` 16 | ::: 17 | 18 | ## 示例 19 | 20 |
21 | 24 |
25 | 26 | 27 | 52 | 53 | 64 | -------------------------------------------------------------------------------- /docs/web/knowledge/npm-publish.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 发布npm包 3 | description: 二次封装或开发js库,发布到npm 4 | outline: [2, 3] 5 | --- 6 | 7 | # 发布npm包 8 | 9 | > 访问 `npmjs` 官网需要魔法 10 | 11 | ## 准备工作 12 | 13 | 注册npmjs账号 14 | 15 | 查看你的 `.npmrc` 设置,确保你的 `registry` 是 [https://www.npmjs.com/](https://www.npmjs.com/), 而不是淘宝源 16 | 17 | ## 发布 18 | 19 | > 每次发布新版本 `package.json` 配置文件的 `version` 都要改变不然无法发版 20 | 21 | * 在项目终端输入 `npm login` 登录你的账号 22 | 23 | * 需要依次输入自己的 npm账号名字,密码,邮箱 24 | 25 | * 之后需要邮箱的动态验证码校验 26 | 27 | * 执行 `npm publish` 即可发布 28 | 29 | ## 验证 30 | 31 | 在自己的npm账号下打开个人信息的 `packages` 进入查看自己已发布的包 32 | 33 | 确认发布信息没问题就可以使用npm去下载使用了 34 | 35 | ## package.json字段说明 36 | 37 | ::: info 常用字段 38 | * name 39 | * version 40 | * description 41 | * keywords 42 | * author 43 | * license 44 | * repository 45 | * main 46 | * unpkg 47 | * module 48 | * scripts 49 | * engines 50 | ::: 51 | 52 | `main` 定义了包的入口文件,导入包文件就是解析main定义的文件. 53 | 54 | `name` 就是发布到npm上的包名,也即别人安装时输入的名字npm i ${name}, 包名应该是kebab-case, 即英文单词全小写,中划线分割(lower case and dash-separated) 55 | 56 | `version` 是代表版本的意思,每次重新发版版本号都应该不一致。定义版本号应遵循小版本兼容的文件,以优化、修复为主。大版本是添加新的功能。 57 | 58 | `description` 是对包的描述,在npmjs.com上搜索时会显示,良好的描述信息有助于用户在搜索时进行筛选 59 | 60 | `author` 作者的格式一般是${your name} ${email}, 当然也可以是一个github地址 61 | 62 | `repository` 的格式参考如下: 63 | 64 | ```json 65 | "repository": { 66 | "type": "git", 67 | "url": "https://github.com/FEMessage/el-data-table.git" 68 | } 69 | ``` 70 | 71 | 这样在你的npm包主页面就有会多出一个github的入口 72 | 73 | `engines` 可以告诉用户运行你的包对NodeJs版本的要求,这是非常重要的,不然你使用了NodeJs新版本特性,却没有定义该字段,导致低版本NodeJs用户运行报错,让人摸不着头脑。 74 | 75 | -------------------------------------------------------------------------------- /docs/web/vue/project-template.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Vue3 + ts项目小技巧 3 | description: 作者开发Vue3 + ts项目的一些小技巧 4 | --- 5 | 6 | # Vue3 + ts项目小技巧 7 | 8 | ## 建议标准初始化模版 9 | 10 | ```js-vue 11 | 14 | 15 | 28 | 29 | 30 | ``` 31 | 32 | 33 | 34 | ### 用户代码片段code 35 | > 建议添加快捷方式使用`tem3t`自动生成模板 36 | 37 | ```json 38 | "Vue3TS-初始化模板": { 39 | "prefix": "tem3t", 40 | "body": [ 41 | "", 44 | "", 45 | "", 58 | "", 59 | "" 60 | ], 61 | "description": "初始化Vue3-模板" 62 | } 63 | ``` 64 | 65 | 66 | ## 打包省略console | debugger 67 | ```js-vue 68 | export default defineConfig({ 69 | // 打包之后没有,不会影响开发环境 70 | esbuild: { 71 | pure: ['console.log'], 72 | drop: ['debugger'] 73 | }, 74 | }) 75 | ``` 76 | -------------------------------------------------------------------------------- /docs/web/harmony/use-image.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Harmony 使用Image资源的4种方法 3 | description: 鸿蒙使用Image资源的4种方法 4 | --- 5 | 6 | # Harmony 使用Image资源的4种方法 7 | 8 | ## 具体使用 9 | ::: info 方法一:`assets` 目录 10 | - 1.新建 `src/main/ets/assets/image` 目录 11 | - 2.添加 `startIcon.png` 图片文件 12 | ```js 13 | Image('/assets/image/startIcon.png') // [!code error] 14 | .width(100) 15 | .aspectRatio(1) 16 | ``` 17 | ::: 18 | 19 | ::: info 方法二:使用网络图片 20 | ```js 21 | Image('https://www.jwblog.cn/images/blog/update-after.jpg') // [!code error] 22 | .width(100) 23 | .aspectRatio(1) 24 | ``` 25 | ::: 26 | 27 | ::: info 方法三:`media` 目录 28 | > 固定用法`$r('app.media.图片名字')` 29 | - 1.ets目录下新建 `src/main/resources/base/media` 目录 30 | - 2.添加 `startIcon.png` 图片文件 31 | ```js 32 | Image($r('app.media.startIcon')) // [!code error] 33 | .width(100) 34 | .aspectRatio(1) 35 | ``` 36 | ::: 37 | 38 | ::: info 方法四:`rawfile` 目录 39 | > 固定用法`$r('$rawfile.图片名字')` 40 | - 1.在 `src/main/resources/rawfile` 目录下 41 | - 2.添加 `startIcon.png` 图片文件 42 | ```js 43 | Image($rawfile("startIcon.png")) // [!code error] 44 | .width(100) 45 | .aspectRatio(1) 46 | ``` 47 | ::: 48 | 49 | ## 优缺点对比 50 | | 区别 | assets | 网络图片 | media | rawfile | 51 | |:---|:---|:---|:---|:---| 52 | | 优点 | 1.可以有二级目录
2.利于维护 | | 1.使用简单 | 1.使用简单 | 53 | | 缺点 | | 需要有网络 | 1.不可以有二级目录
2.不可以有文件后缀
3.必须简写(无后缀) | 1.资源必须是全路径(有后缀) | 54 | 55 | ## 网络资源遇到的问题 56 | > 网络资源的图片在模拟器和真机上边不显示 57 | - 在鸿蒙中在模拟器和真实项目中,必须申请网络权限 58 | - 在 `src/main/module.json5` 文件添加以下代码 59 | ```json 60 | "requestPermissions": [{ 61 | "name":"ohos.permission.INTERNET" 62 | }], 63 | ``` -------------------------------------------------------------------------------- /docs/web/basics/code-safety.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 前端加密安全 3 | description: 前端怎么做数据接口的加密安全处理 4 | outline: [2, 3] 5 | --- 6 | 7 | # 前端加密安全 8 | 9 | > 核心使用了前端js库 `CryptoJS` 10 | 11 | ## 加密流程 12 | 13 | ### 加密场景和加密方式 14 | * 前端加密场景有哪些? 15 | - 请求接口 16 | - 路由跳转携带参数 17 | 18 | * 常用加密方式 19 | - base64 20 | - Sha256 21 | - AES 22 | - ... 23 | 24 | ### 简单的Base64加密使用场景 25 | 26 | * 浏览器url地址栏 27 | 28 | ![浏览器url地址栏](https://www.jwblog.cn/images/code/share/encryptionShare001.png) 29 | 30 | * 区别&缺陷 31 | 32 | ![区别&缺陷](https://www.jwblog.cn/images/code/share/encryptionShare002.png) 33 | 34 | ::: tip Base64优缺点(Base64本质是一种编码方式,而非加密方式) 35 | * 优点 36 | - 使用简单,javascript语言支持 37 | - 对称性加密(加密之后可以解密) 38 | * 缺点 39 | - 加解密会改变基础类型(Number 变成String),仅支持ASCII 40 | - 编码后的大小会比原文件大小大1/3 41 | - 加密单一,内容相同的密文加密解密对一样的 42 | - 会造成文件体积增加,影响文件的加载速度 43 | - 兼容性的问题,ie8以前的浏览器不支持 44 | ::: 45 | 46 | ### Sha256加密简介 47 | 48 | - 比较流行,也是最强的加密函数之一 49 | - 非对称性加密(加密之后,无法通过密文解密) 50 | - 应用场景:比特币等加密货币 51 | 52 | 加密、解密过程演示 53 | 54 | ![加密、解密过程演示](https://www.jwblog.cn/images/code/share/encryptionShare003.png) 55 | 56 | ### AES加密简介 57 | 58 | 加密、解密过程演示 59 | 60 | ![加密、解密过程演示](https://www.jwblog.cn/images/code/share/encryptionShare004.png) 61 | 62 | ::: warning 前端加密步骤 63 | 64 | * 获取当前时间戳 65 | * 拼接密钥字符串(eg:token + 时间戳) 66 | * 哈希算法对拼接后的字符串进行哈希 67 | - 借助sha256生成非对称性加密 68 | - 生成结果64位 69 | * 取哈希结果前32位生成完整的密钥(utf8格式) 70 | * 使用前端js库CryptoJS生成密文 71 | ::: 72 | 73 | ### 如何加密 74 | 75 | ![如何加密](https://www.jwblog.cn/images/code/share/encryptionShare006.png) 76 | 77 | ### 如何解密 78 | 79 | ![如何解密](https://www.jwblog.cn/images/code/share/encryptionShare007.png) 80 | -------------------------------------------------------------------------------- /docs/web/basics/exist-key.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: javascript(js)判断对象是否包含某个 key 3 | description: javascript(js)判断对象是否包含某个 key 4 | --- 5 | 6 | # javascript(js)判断对象是否包含某个 key 7 | 8 | ## 方法对比 9 | 10 | | 方法 | 特点 | 11 | | ------------- | :-----------: | 12 | | in 操作符 | 会检查对象的原型链 | 13 | | hasOwnProperty() 方法 | 不会检查对象的原型链 | 14 | | Object.hasOwn() 方法 | 不会检查对象的原型链(旨在取代 hasOwnProperty方法) | 15 | | Reflect.has() 方法 | es6方法,不会受对象的 Symbol 属性的影响 | 16 | 17 | ## in 操作符 18 | ```js 19 | key in object 20 | 21 | // eg 22 | const obj = { 23 | name: 'John', 24 | age: 30 25 | }; 26 | 27 | console.log('name' in obj); // true 28 | console.log('age' in obj); // true 29 | console.log('gender' in obj); // false 30 | ``` 31 | 32 | ## hasOwnProperty() 方法 33 | ```js 34 | object.hasOwnProperty(key) 35 | 36 | // eg 37 | const obj = { 38 | name: 'John', 39 | age: 30 40 | }; 41 | 42 | console.log(obj.hasOwnProperty('name')); // true 43 | console.log(obj.hasOwnProperty('age')); // true 44 | console.log(obj.hasOwnProperty('gender')); // fal 45 | ``` 46 | 47 | ## Object.hasOwn() 方法 48 | ```js 49 | Object.hasOwn(object, key) 50 | 51 | // eg 52 | const obj = { 53 | name: 'John', 54 | age: 30 55 | }; 56 | 57 | console.log(Object.hasOwn(obj, 'name')); // true 58 | console.log(Object.hasOwn(obj, 'age')); // true 59 | console.log(Object.hasOwn(obj, 'gender')); // false 60 | ``` 61 | 62 | ## Reflect.has() 方法 63 | 64 | ```js 65 | const obj = { 66 | name: 'John', 67 | age: 30 68 | }; 69 | 70 | console.log(Reflect.has(obj, 'name')); // true 71 | console.log(Reflect.has(obj, 'age')); // true 72 | console.log(Reflect.has(obj, 'gender')); // false 73 | ``` -------------------------------------------------------------------------------- /.github/workflows/run_script.yml: -------------------------------------------------------------------------------- 1 | name: Run Root Script # 工作流名称 2 | 3 | on: 4 | push: 5 | branches: 6 | - master # 监控 master 分支上的推送事件 7 | workflow_dispatch: # 手动触发工作流 8 | 9 | jobs: 10 | run-script: 11 | runs-on: ubuntu-latest # 使用最新版本的 Ubuntu 作为运行环境 12 | 13 | steps: 14 | - name: Checkout code # 步骤1:检出代码 15 | uses: actions/checkout@v2 # 使用官方的 checkout 动作 16 | 17 | - name: Install SSH client and sshpass # 步骤2:安装 SSH 客户端和 sshpass 18 | run: | 19 | sudo apt-get update # 更新包列表 20 | sudo apt-get install -y openssh-client sshpass # 安装 openssh-client 和 sshpass 21 | 22 | - name: Run script on server # 步骤3:在服务器上运行脚本 23 | env: 24 | SSH_HOST: ${{ secrets.SSH_HOST }} # 从 GitHub Secrets 中读取 SSH 主机名 25 | SSH_USER: ${{ secrets.SSH_USER }} # 从 GitHub Secrets 中读取 SSH 用户名 26 | SSH_PASSWORD: ${{ secrets.SSH_PASSWORD }} # 从 GitHub Secrets 中读取 SSH 密码 27 | run: | 28 | # 使用 sshpass 和 SSH 密码进行 SSH 连接,并在服务器上运行脚本 29 | sshpass -p "$SSH_PASSWORD" ssh -o StrictHostKeyChecking=no $SSH_USER@$SSH_HOST 'nohup /root/update.sh > /root/update_output.log 2>&1' 30 | 31 | echo "The build command was executed successfully" 32 | 33 | ## 监视服务器,时间过长 34 | # # 捕获脚本的退出状态 35 | # EXIT_STATUS=$? 36 | 37 | # # 从服务器获取输出日志文件 38 | # sshpass -p "$SSH_PASSWORD" scp -o StrictHostKeyChecking=no $SSH_USER@$SSH_HOST:/root/update_output.log . 39 | 40 | # # 显示输出日志文件内容 41 | # cat update_output.log 42 | 43 | # # 输出脚本执行结果 44 | # if [ $EXIT_STATUS -ne 0 ]; then 45 | # echo "Script execution failed with exit status $EXIT_STATUS" # 如果脚本执行失败,输出错误状态并退出 46 | # exit $EXIT_STATUS 47 | # else 48 | # echo "Script executed successfully" # 如果脚本执行成功,输出成功消息 49 | # fi 50 | -------------------------------------------------------------------------------- /docs/.vitepress/custom/components/MyLayout.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 46 | 47 | -------------------------------------------------------------------------------- /docs/web/wechat/life-cycle.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 小程序生命周期 3 | description: 微信小程序生命周期的全解 4 | --- 5 | 6 | # 小程序生命周期 7 | 8 | ## 页面生命周期 9 | ```js 10 | 代码执行顺序 11 | onLoad() → onShow() → onshow() → 页面完全渲染完成 → onReady() 12 | 13 | 生命周期函数--监听页面加载 14 | onLoad(options) { }, 15 | 1.执行一次,子页面back()跳转回来不会触发, 16 | 2.只有页面销毁或者返回上一页,在进入页面才会触发 17 | 3.请求的静态数据方法可以写在这里 18 | 4.options 可以拿到页面的传参 19 | 20 | 生命周期函数--监听页面初次渲染完成 21 | onReady() { }, 22 | 1.执行一次,子页面back()跳转回来不会触发, 23 | 2.只有页面销毁或者返回上一页,在进入页面才会触发, 24 | 3.特殊情况有用,自动获取验证码 25 | eg:在当前页面有验证码的校验,在这个生命周期可以调用获取验证码的方法,自动获取验证码简化用户操作 26 | 27 | 生命周期函数--监听页面 28 | onShow() { }, 29 | 1.当前页面被唤醒就会触发一次 30 | 2.通常需要动态刷新的数据方法请求,写在这里 31 | 3.通过方法可以拿到传参 32 | 4.通过 33 | 34 | 生命周期函数--监听页面隐藏 35 | onHide() { }, 36 | 37 | 生命周期函数--监听页面卸载 38 | onUnload() { }, 39 | 1.通常用于销毁定时器 40 | 41 | 页面相关事件处理函数--监听用户下拉动作 42 | onPullDownRefresh() { }, 43 | 44 | 页面上拉触底事件的处理函数 45 | onReachBottom() { }, 46 | 1.通常用户触底加载更多数据,列表的上拉加载更多数据 47 | 48 | 用户点击右上角分享 49 | onShareAppMessage() { } 50 | 1.不要小看他,是一个坑,页面最好都有 51 | eg:分享功能,多数情况下都可以用到,而且全局封装分享功能,每个页面都需要有这个分享的方法 52 | ``` 53 | 54 | 55 | 56 | ## 组件生命周期 57 | ```js 58 | 代码执行顺序 59 | created() → attached() → 组件渲染完成 → ready() 60 | 61 | 在组件实例进入页面节点树时执行 62 | attached() { }, 63 | 1.执行一次,组件实例初始化触发 64 | 2.通常用于写请求 65 | 66 | 在组件实例被从页面节点树移除时执行 67 | detached() { }, 68 | 1.执行一次,组件实例被销毁时触发 69 | 70 | 特殊的生命周期(不常用) 71 | 1.created(在组件实例刚刚被创建时执行) 72 | 2.ready(在组件在视图层布局完成后执行) 73 | ``` 74 | 75 | 76 | ## 组件生命周期 77 | ```js 78 | 组件的的生命周期建议在 lifetimes 字段内进行声明(这是推荐的方式,其优先级最高) 79 | 80 | Component({ = 81 | lifetimes: { 82 | attached: function() { 83 | // 在组件实例进入页面节点树时执行 84 | }, 85 | detached: function() { 86 | // 在组件实例被从页面节点树移除时执行 87 | }, 88 | }) 89 | 90 | // 以下是旧式的定义方式,可以保持对 2.2.3 版本基础库的兼容 91 | attached: function() { 92 | // 在组件实例进入页面节点树时执行 93 | }, 94 | detached: function() { 95 | // 在组件实例被从页面节点树移除时执行... 96 | } 97 | ``` 98 | -------------------------------------------------------------------------------- /docs/web/harmony/holy-grail.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Harmony 实现双飞翼(圣杯)布局 3 | description: 鸿蒙一行代码实现双飞翼布局 4 | --- 5 | 6 | # Harmony 实现双飞翼(圣杯)布局 7 | > 一行代码实现双飞翼布局 8 | 9 | ## 什么是双飞翼(圣杯) 10 | 11 | > 两个盒子中间夹着一个盒子,形状类似一个圣杯效果 12 | 13 |
14 |
15 |
16 |
17 |
18 | 19 | 20 | ## layoutWeight属性 21 | ::: info 借助`layoutWeight`属性 22 | > `layoutWeight` 效果等效 `flex` 布局里的 `flex: 1` 23 | ```js 24 | build() { 25 | Row() { 26 | Row() 27 | .width(100) 28 | .height(100) 29 | .backgroundColor(Color.Orange) 30 | 31 | Row() 32 | .width(100) 33 | .height(100) 34 | .backgroundColor(Color.Blue) // [!code error] 35 | .layoutWeight(1) 36 | 37 | Row() 38 | .width(100) 39 | .height(100) 40 | .backgroundColor(Color.Red) 41 | } 42 | .height('100%') 43 | } 44 | ``` 45 | ::: 46 | 47 | ## Blank标签 48 | ::: info 借助`Blank`标签 49 | > [官网说明](https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/ts-basic-components-blank-0000001428061724-V2) 50 | - `Blank` 效果等效 `flex` 布局里的 `flex: 1` 51 | - 空白填充组件,在容器主轴方向上,空白填充组件具有自动填充容器空余部分的能力。 52 | - 仅当父组件为Row/Column/Flex时生效 53 | ```js 54 | build() { 55 | Row() { 56 | Row() 57 | .width(100) 58 | .height(100) 59 | .backgroundColor(Color.Orange) 60 | 61 | Blank() // [!code error] 62 | 63 | Row() 64 | .width(100) 65 | .height(100) 66 | .backgroundColor(Color.Red) 67 | } 68 | } 69 | ``` 70 | ::: 71 | 72 | -------------------------------------------------------------------------------- /docs/other/blog/up/setup-oss.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: nginx搭建对象存储OSS 3 | description: 在云服务器借助nginx搭建对象存储OSS,使用nginx做图片服务器 4 | outline: [2, 3] 5 | --- 6 | 7 | # 搭建个人的对象存储OSS 8 | 9 | ## 什么是对象存储OSS 10 | 11 | 对象存储 OSS (Object Storage Service) 是一种云存储服务,它提供了一种存储海量数据的安全、可靠、经济高效的方式。简单来说,它就像一个巨大的在线仓库,你可以用来存储各种类型的数字文件。 12 | 13 | ### 示例 14 | * 图片:产品照片、用户头像、视频截图等 15 | * 视频:电影、电视剧、短视频等 16 | * 音频:音乐、播客、语音文件等 17 | * 文档:合同、账单、用户手册等 18 | * 代码:源代码、配置文件等 19 | * 备份数据:数据库备份、系统日志等 20 | 21 | ### 特点 22 | 23 | * 使用简单 24 | * 例如小程序项目图片必须使用oss存储 25 | * 大部分厂商提供的oss上传免费,存储空间不限大小,但是`下行流量收费` 26 | - 下行流量:访问这个图片的流量 27 | - 一张图片大小 `100kb`,那么访问一次这个图片就是 `100kb` 下行流量 28 | 29 | ## windows系统搭建oss 30 | 31 | > 这里我们可以借助 `nginx` 做代理 32 | 33 | ### 修改nginx配置文件 34 | 35 | > 访问链接 `/image` 的资源访问都被转接到 `alias 配置的文件地址目录下` 36 | 37 | ::: info `conf/nginx.conf` 文件 38 | ```nginx 39 | location /image { 40 | alias C:/Users/picture/; # 使用 alias 而不是 root 41 | } 42 | 43 | location / { 44 | root html; 45 | index index.html index.htm; 46 | } 47 | ``` 48 | ::: 49 | 50 | 修改nginx配置文件,生效需要执行 `nginx -s reload` 51 | 52 | ### 如何看效果 53 | 54 | - 在本地 `C:/Users/picture/` 文件夹下放入一张图片001.png 55 | - 执行 `nginx -s reload` 56 | - 验证 > 浏览器访问 `C:/Users/picture/001.png` 是否可以看到图片 57 | - 验证 > `localhost/image/001.jpg` 可以访问就是转接成功 58 | - 在自己的私人电脑通过浏览器访问图片,进行验证 > http://公网ip/image/001.jpg 59 | 60 | 如果可以通过公网ip可以访到图片,那么就可以了,后续域名绑定ip之后,我们就可以通过域名 `http://www.jwblog.cn/image/001.jpg` 进行访问 61 | 62 | ### 注意事项 63 | 64 | - 这里配置图片的转接地址是用 `alias` 而不是 `root` 65 | - 修改了nginx配置文件或者添加的新的图片,必须执行 `nginx -s reload` 66 | 67 | ## linux系统搭建oss 68 | 69 | linux的oss搭建,nginx内容同windows一样 70 | 71 | * Ubunto配置文件在 72 | ```nginx 73 | /etc/nginx/sites-available 74 | ``` 75 | * CentOs配置文件在 76 | ```nginx 77 | /etc/nginx/nginx.conf 78 | ``` 79 | 80 | 添加oss配置代码 81 | 82 | ```nginx 83 | location /image { 84 | root /path/to/images; 85 | } 86 | ``` -------------------------------------------------------------------------------- /docs/web/vue/plugins.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Vue项目常用插件 3 | description: 精选Vue项目开发中必备的插件和工具库,涵盖UI组件、开发辅助、表格处理、数学计算和性能优化等多个方面,助力开发者提高效率和项目质量。 4 | outline: [2, 3] 5 | --- 6 | 7 | # Vue项目常用插件 8 | 9 | ### UI篇 10 | 11 | `Element Plus` 12 | 13 | > 兼容性最好,使用最广泛 14 | 15 | `Ant Design of Vue` 16 | 17 | > 未来的设计标准,缺陷很明显社区维护BUG较多,代码开发上略有缺陷 18 | 19 | `Vant` 20 | 21 | > 移动端H5首选,不适用于混合开发模式 22 | 23 | ### 开发辅助篇 24 | 25 | `VueUse` 26 | 27 | > Vue组合式API的实用工具集 28 | 29 | `unplugin-auto-import` 30 | 31 | > 自动按需引入 vue|vue-router|pinia 等的 api 32 | 33 | `unplugin-vue-components` 34 | 35 | > 自动按需引入 第三方的组件库组件(elementUI) 和 我们自定义的组件 36 | 37 | `pinia-plugin-persistedstate` 38 | 39 | > 持久化pinia数据,中文官网,使用简单,绝对的后起之秀 40 | 41 | `vuex-persistedstate` 42 | 43 | > 持久化pinia|vuex数据,vue2时代的产物,主要用于vuex 44 | 45 | `Lodash` 46 | 47 | > 封装了常用的js函数,不过使用率在下降 48 | 49 | `Day.js` 50 | 51 | > 操作和显示日期和时间 52 | 53 | ### table篇 54 | 55 | `vxe-table` 56 | 57 | > 复杂表格业务需求首选 58 | 59 | ### js计算篇 60 | 61 | `bignumber.js` 62 | 63 | > 推荐使用 64 | 65 | `mathjs` 66 | 67 | > 强大且易于使用,使用最广泛的js计算库 68 | 69 | `big.js` 70 | 71 | > 一个小型,快速,易于使用的库,用于任意精度的十进制算术运算 72 | 73 | #### 对比 74 | 75 | | 包 | 特点 | 缺点 | 76 | | ------------- | :------------- |:------------- | 77 | | `bignumber.js` | 专为大数运算设计,支持任意精度的加减乘除、开方等运算 | 功能相对简单,不支持复杂数学运算 | 78 | | mathjs | 功能非常全面,支持符号计算、矩阵运算、复数运算等。除了高精度计算,还提供了丰富的数学函数 | 包大小相对较大,如果仅需高精度计算,引入整个库可能有些臃肿。 | 79 | | big.js | 与 bignumber.js 类似,但 API 设计有所不同 | 功能相对简单 | 80 | 81 | ### 优化篇 82 | 83 | `vite-plugin-compression` 84 | 85 | gzip压缩,需要nginx开启GZIP,打包之后可以明显提高项目的打开速度 86 | 87 | 类似还有br压缩,不过br压缩存在兼容性问题,压缩效率比Gzip压缩能提高15% 88 | 89 | `vite-plugin-imagemin` 90 | 91 | 本地静态图片压缩 92 | 93 | ### 扩展篇 94 | 95 | `vite-plugin-vue-inspector` 96 | 97 | 快捷键开启和关闭,点击page元素可以打开对应的.vue文件 98 | 99 | `avue` 100 | 101 | 搬砖神器, 更加贴合企业开发, 包含了大量基于vue + elementui的常用组件库以及插件库。 102 | -------------------------------------------------------------------------------- /docs/web/basics/download.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: JS实现文件下载 3 | description: JS实现文件下载 4 | --- 5 | 6 | # JS实现文件下载 7 | 8 | ## 示例 9 | 10 | ## location.href 或 window.open 11 | 12 | * 优点 13 | - 单文件下载 14 | - 使用简单 15 | * 缺点 16 | - 多次调用前面的下载会被覆盖掉 17 | 18 | ```js 19 | window.location.href = url; 20 | // 或者 21 | window.open(url) 22 | ``` 23 | 24 | 25 | ## a标签封装 26 | ```js 27 | /** 28 | * @param [String] url 文件地址 29 | * @param [String] fileName 文件name 30 | */ 31 | function downFile(url: string, fileName?: string) { 32 | // 文件名必带有格式,eg: cs.txt, cs.pdf 33 | if (!url) { 34 | return 35 | } 36 | const name: string = fileName ? fileName : url.split('/')[url.split('/').length - 1] 37 | const callback = (url: string) => { 38 | const link = document.createElement('a') 39 | const objectUrl = window.URL.createObjectURL(new Blob([url])) 40 | link.style.display = 'none' 41 | link.href = objectUrl 42 | link.download = name 43 | document.body.appendChild(link) 44 | link.click() 45 | window.URL.revokeObjectURL(objectUrl) 46 | } 47 | const xhr = new XMLHttpRequest() 48 | xhr.open('get', url, true) 49 | xhr.responseType = 'blob' 50 | xhr.onload = () => { 51 | callback(xhr.response) 52 | } 53 | xhr.send() 54 | } 55 | ``` 56 | 57 | ## 图片下载 58 | ```js 59 | // 图片下载 60 | function imgDown(imgsrc: string, CustomName?: string) { 61 | if (!imgsrc) { 62 | return 63 | } 64 | const name: string = CustomName ? CustomName : imgsrc.split('/')[imgsrc.split('/').length - 1] 65 | fetch(imgsrc).then(res => { 66 | res.blob().then(myBlob => { 67 | const href = URL.createObjectURL(myBlob) 68 | const a: HTMLAnchorElement = document.createElement('a') 69 | a.href = href 70 | a.download = name 71 | a.click() 72 | a.remove() 73 | }) 74 | }) 75 | } 76 | ``` -------------------------------------------------------------------------------- /docs/public/image/cont.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 内容丰富 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /docs/web/vue/upgradation/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import vue from '@vitejs/plugin-vue2' 3 | import vueJsx from '@vitejs/plugin-vue2-jsx' 4 | import createSvgSpritePlugin from 'vite-plugin-svg-sprite' 5 | const path = require('path') 6 | import legacy from '@vitejs/plugin-legacy' 7 | 8 | export default defineConfig(({ mode }) => { 9 | const configFile = require(`./config/${mode}.env.js`) 10 | const defineMap = {} 11 | // 解决vite不兼容process.env 12 | Object.keys(configFile).forEach(key => { 13 | defineMap[`process.env.${key}`] = JSON.stringify(configFile[key]) 14 | }) 15 | return { 16 | build: { 17 | target: 'es2015' 18 | }, 19 | plugins: [ 20 | vue(), 21 | vueJsx(), // 兼容jsx语法 22 | createSvgSpritePlugin({ 23 | symbolId: 'icon-[name]' 24 | }), // 兼容svg图片 25 | legacy({ 26 | targets: ['chrome >= 65', 'edge >= 79', 'safari >= 11.1', 'firefox >= 67'], 27 | ignoreBrowserslistConfig: true, 28 | renderLegacyChunks: false, 29 | additionalLegacyPolyfills: ['regenerator-runtime/runtime'], 30 | modernPolyfills: true 31 | }) // 兼容部分老旧浏览器 32 | ], 33 | server: { 34 | host: '0.0.0.0', 35 | port: 9700, 36 | open: false, //自动打开 37 | proxy: { 38 | '/web': { 39 | target: 'http://www.dev.com', // 开发环境 40 | // target: 'http://www.test.com', // 测试环境 41 | changeOrigin: true 42 | } 43 | } 44 | }, 45 | define: defineMap, 46 | esbuild: { 47 | pure: ['console.log'], 48 | drop: ['debugger'], 49 | target: 'es2015' 50 | }, 51 | resolve: { 52 | alias: { 53 | '@': path.resolve(__dirname, 'src') 54 | }, 55 | extensions: ['.vue', '.mjs', '.js', '.ts', '.jsx', '.tsx', '.json'] 56 | } 57 | } 58 | }) 59 | -------------------------------------------------------------------------------- /docs/other/tools/git-command.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 如何使用git提交代码 3 | description: 如何使用git提交代码,把git代码提交应用于实际项目 4 | outline: [2, 3] 5 | --- 6 | 7 | # 如何使用git提交代码 8 | 9 | > 工欲善其事,必先利其器 10 | 11 | ## git操作软件推荐 12 | 13 | ::: info GitHub Desktop 14 | > 支持 `mac` 和 `win`   [官网直通车   🚘](https://desktop.github.com) 15 | ```js 16 | 优点:可以复制操作代码 17 | 缺点:没有中文界面 18 | ``` 19 | ::: 20 | 21 | ::: info sourcetree 22 | > 支持 `mac` 和 `win`   [官网直通车   🚘](https://www.sourcetreeapp.com) 23 | ```js 24 | 优点:支持中文界面 25 | 缺点:不可以复制操作代码 26 | ``` 27 | ::: 28 | 29 | ## git提交代码流程 30 | 31 | ::: info 推送代码到远端 32 | ```js 33 | 1.首先在项目目录下初始化本地仓库 34 | git init 35 | 36 | 2.添加所有文件( . 表示所有) 37 | git add . 38 | 39 | 3.提交所有文件到本地仓库 40 | git commit -m "备注信息" 41 | 42 | 4.连接到远程仓库 43 | git remote add origin 你的远程仓库地址 44 | 45 | 5.将项目推送到远程仓库,(失败,可以先拉去远端代码到本地,再提交) 46 | git push -u origin master 47 | 48 | 6.拉取代码到本地,再推送代码到远端 49 | git pull --rebase origin master 50 | ``` 51 | ::: 52 | 53 | ## git回滚代码的方式 54 | 55 | ### git revert 56 | 57 | ```sh 58 | git revert HEAD 59 | ``` 60 | 61 | `git revert` 会创建一个新的提交,并且不会改变提交历史,适合已经共享到远程仓库的情况。 62 | 63 | ### git reset 64 | * 回滚到特定提交并保留更改: 65 | ```sh 66 | git reset --soft 67 | ``` 68 | * 回滚到特定提交并丢弃更改: 69 | ```sh 70 | git reset --hard 71 | ``` 72 | 73 | 此命令将分支指针重置到 `commit-hash`,并丢弃所有未提交的更改。 74 | 75 | ## ssh链接 76 | 77 | ### 生成 SSH 密钥对 78 | 79 | 如果还没有 SSH 密钥,可以通过以下命令生成: 80 | 81 | ```sh 82 | ssh-keygen -t rsa -b 4096 -C "your_email@example.com" 83 | ``` 84 | 85 | 按提示操作,生成密钥对后,公钥会保存在 ~/.ssh/id_rsa.pub 中,私钥会保存在 ~/.ssh/id_rsa 中。 86 | 87 | ### 将公钥添加到 GitHub 88 | 89 | * 复制公钥内容: 90 | ```sh 91 | cat ~/.ssh/id_rsa.pub 92 | ``` 93 | * 登录 GitHub,进入 `SSH and GPG keys` 页面。 94 | * 点击 "New SSH key",将公钥内容粘贴到 Key 字段中,并设置一个 Title,点击 "Add SSH key"。 95 | * id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。 96 | 97 | ### 配置 Git 使用 SSH 98 | 99 | 确保 Git 使用 SSH 方式连接 GitHub,可以使用以下命令: 100 | 101 | ```sh 102 | cd /path/to/your/repository 103 | git remote set-url origin git@github.com:username/repository.git 104 | ``` -------------------------------------------------------------------------------- /docs/web/basics/hidden.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: CSS处理一行或多行文字超出用省略号 3 | description: CSS处理一行或多行文字超出用省略号 4 | --- 5 | 6 | # CSS处理一行或多行文字超出用省略号 7 | 8 | ## 一行文字 9 | 10 | ```css 11 | { 12 | width: 400px; 13 | white-space: nowrap; 14 | overflow: hidden; 15 | text-overflow: ellipsis; 16 | } 17 | ``` 18 | >效果对比: 19 |
时间最会骗人,但也能让你明白,这个世界没有什么是不能失去的,留下的尽力珍惜,得不到的都不重要。
20 |
时间最会骗人,但也能让你明白,这个世界没有什么是不能失去的,留下的尽力珍惜,得不到的都不重要。
21 | 22 | ## 多行文字 23 | 24 | ```css 25 | { 26 | display: -webkit-box; 27 | -webkit-box-orient: vertical; 28 | -webkit-line-clamp: 3; 29 | overflow: hidden; 30 | } 31 | ``` 32 | > 效果对比: 33 |
北凉王府龙盘虎踞于清凉山,千门万户,极土木之盛。 作为王朝硕果仅存的异姓王,在庙堂和江湖都是毁誉参半的北凉王徐骁作为一名功勋武臣,可谓得到了皇帝宝座以外所有的东西,在西北三州,他就是当之无愧的主宰,只手遮天,翻云覆雨。 难怪朝廷中与这位异姓王政见不合的大人们私下都会文绉绉骂一声徐蛮子,而一些居心叵测的,更诛心地丢了顶“二皇帝”的帽子。 今天王府很热闹,位高权重的北凉王亲自开了中门,摆开辉煌仪仗,迎接一位仙风道骨的老者,府中下人们只听说是来自道教圣地龙虎山的神仙,相中了痴痴傻傻的小王爷,要收作闭关弟子,这可是天大的福缘,北凉王府都解释成傻人有傻福。 可不是,小王爷自打出生起便没哭过,读书识字一窍不通,六岁才会说话,名字倒是威武气派,徐龙象,传闻还是龙虎山的老神仙当年给取的,说好十二年后再来收徒,这不就如约而至了。 王府内一处院落,龙虎山师祖一级的道门老祖宗捻着一缕雪白胡须,眉头紧皱,背负一柄不常见的小钟馗式桃木剑,配合他的相貌,确实当得出尘二字,谁看都要由衷赞一声世外高人呐。 但此番收徒显然遇到了不小的阻碍,倒不是王府方面有异议,而是他的未来徒弟犟脾气上来了,蹲在一株梨树下,用屁股对付他这个天下道统中论地位能排前三甲的便宜师傅,至于武功嘛,咳咳,前三十总该有的吧。
34 |
北凉王府龙盘虎踞于清凉山,千门万户,极土木之盛。 作为王朝硕果仅存的异姓王,在庙堂和江湖都是毁誉参半的北凉王徐骁作为一名功勋武臣,可谓得到了皇帝宝座以外所有的东西,在西北三州,他就是当之无愧的主宰,只手遮天,翻云覆雨。 难怪朝廷中与这位异姓王政见不合的大人们私下都会文绉绉骂一声徐蛮子,而一些居心叵测的,更诛心地丢了顶“二皇帝”的帽子。 今天王府很热闹,位高权重的北凉王亲自开了中门,摆开辉煌仪仗,迎接一位仙风道骨的老者,府中下人们只听说是来自道教圣地龙虎山的神仙,相中了痴痴傻傻的小王爷,要收作闭关弟子,这可是天大的福缘,北凉王府都解释成傻人有傻福。 可不是,小王爷自打出生起便没哭过,读书识字一窍不通,六岁才会说话,名字倒是威武气派,徐龙象,传闻还是龙虎山的老神仙当年给取的,说好十二年后再来收徒,这不就如约而至了。 王府内一处院落,龙虎山师祖一级的道门老祖宗捻着一缕雪白胡须,眉头紧皱,背负一柄不常见的小钟馗式桃木剑,配合他的相貌,确实当得出尘二字,谁看都要由衷赞一声世外高人呐。 但此番收徒显然遇到了不小的阻碍,倒不是王府方面有异议,而是他的未来徒弟犟脾气上来了,蹲在一株梨树下,用屁股对付他这个天下道统中论地位能排前三甲的便宜师傅,至于武功嘛,咳咳,前三十总该有的吧。
35 | 36 | 37 | 55 | -------------------------------------------------------------------------------- /docs/other/blog/basics/deploy.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 网站的部署发布 3 | description: 博客的部署发布工作流程,以及详细的介绍 4 | outline: [2, 3] 5 | --- 6 | 7 | # 网站的部署发布 8 | 9 | ## 前置准备工作 10 | 11 | 如果不想花钱可以使用 [`github pages`](/other/blog/up/use-page.html) 12 | 13 | ::: tip 所需 14 | - 云服务器 (年花费200rmb左右) 15 | - 域名 (年花费50rmb左右) 16 | ::: 17 | 18 | ## 云服务器 19 | 20 | ::: tip 注意事项 21 | 1. 初次使用云服务器建议先买一年最便宜的华为云试试 22 | 2. 初次购买建议 `windows server` 服务器,可以快速上手。云服务器可以随时刷其他系统,也可以刷 `linux` 系统 23 | 3. 充分掌握云服务器之后再换其他 `linux` 服务器 24 | 3. 服务器配置 `2核2G3M` 够用了 25 | ::: 26 | 27 | ::: info 云服务器种类 28 | - `阿里云` 29 | - 有过云服务器使用经验的首选,也是博主现在使用的云服务器厂商 30 | - 个人感觉使用体验最好的 31 | - 服务器限制不多 32 | - `华为云` 33 | - 新用户有个`28rmb/年` 34 | - `腾讯云` 35 | ::: 36 | 37 | ### 关于费用问题 38 | - 博主目前服务器年消费在200以内 39 | - 每个服务器厂商也会有新用户活动,但是推荐 *`618`* 或 *`双11`* 活动的时候购买 40 | - 活动买一年用完了就换一家厂商的服务器即可,不行也可以用家人的身份信息购买 41 | - 现在 *`618`* 或 *`双11`* 都有连续几年的服务器便意出售 42 | 43 | ## 域名 44 | 45 | > 推荐第一次使用的话可以先买一个便宜的`.top`,`.dev`等,`华为云`、`阿里云`等均有售卖 46 | 47 | ::: info 云服务器种类 48 | 1. `三大顶级域名` 49 | - `.com` 商业机构(commercial),诸如`apple.com`, `google.com` 50 | - `.net` 网络服务提供商(network)诸如网站后台接口地址 51 | - `.org` 非营利组织(organization) 诸如`vuejs.org` 52 | 2. `国家顶级域名` 53 | - `.cn` 中国 54 | - `.us` 美国 55 | - `.jp` 日本 56 | ::: 57 | 58 | ## 配置nginx 59 | 60 | * 建议先用windows电脑本地先熟悉一下 `nginx` 的使用 61 | * 命令都需要在 `nginx文件目录下` 执行 62 | 63 | [官网直通车   🚘](https://nginx.org/en/) 64 | 65 | [nginx的详细使用   🚘](/other/blog/up/use-nginx.html) 66 | 67 | ## 网站备案 68 | 69 | - 服务器是香港或者国外是不需要进行备案的 70 | - 服务器在国内是需要进行备案 71 | - 备案周期大概是 `15-30` 天 72 | 73 | [关于网站如何备案,参考链接   🚘](https://beian.aliyun.com/) 74 | 75 | ## 部署到云服务器 76 | 77 | > 这里假设购买的是 `windows server` 云服务器 78 | 79 | - 买完服务器,在自己电脑操作使用过nginx 80 | - 在服务器下载nginx,在服务器的浏览器里测试nginx是否可用 81 | - 代码上传云服务器,建议通过 `git clone` 的方式 82 | - 这里需要注意 `vitepress` 打包后 `dist打包文件` 也需要上传的代码仓库 83 | - 云服务器电脑安装git工具,拉取代码 84 | - 两种方式启动博客项目 85 | - `方式一:` 将dist目录复制到 `nginx/html` 文件夹下 86 | - `方式二:` 修改nginx配置文件,将项目地址映射到git拉取的dist目录下 87 | - 推荐使用地址映射,可以省去复制粘贴代码,后续升级linux服务器,我们将通过执行脚本方式,`一键完成` 拉取,部署,重载 88 | - 重载nginx,在服务器浏览器访问 `localhost` 看网站效果 89 | 90 | ## 如何使用linux云服务器 91 | 92 | [参考链接](/other/blog/up/use-linux.html) -------------------------------------------------------------------------------- /docs/web/vue/upload-image/core.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 函数式封装上传图片组件 3 | description: 在vue中使用函数式封装上传图片组件 4 | --- 5 | 6 | # 函数式封装上传图片组件 7 | 8 | > Vue3 + ts函数式封装支持 `函数式|组件` 两种使用方式 9 | 10 | ## 演示 11 | 12 | 13 | {{ disabled ? '上传中...' : '上传' }} 14 | 15 | 清空图片 16 | 17 |
18 | 21 |
22 | 23 | 56 | 57 | 67 | 68 | ## 挂载使用 69 | 70 | ### 全局挂载 71 | ```js-vue 72 | // vue2全局挂载 73 | Vue.prototype.$upload = uploadImage 74 | 75 | // vue3全局挂载 76 | app.config.globalProperties.$upload = uploadImage 77 | ``` 78 | 79 | 80 | ### 使用 81 | ```js-vue 82 | // vue2 83 | this.$upload().then(()=> {}).catch(err => {}) 84 | 85 | // vue3 86 | > 必须使用proxy,正式环境ctx是获取不到的所以不能使用const { ctx } = getCurrentInstance() 87 | const { proxy } = getCurrentInstance() 88 | proxy.$upload().then(()=> {}).catch(err => {}) 89 | ``` 90 | 91 | 92 | ::: details 源代码 93 | <<< ./upload.js 94 | ::: -------------------------------------------------------------------------------- /docs/web/basics/regExp.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 常用的正则表达式 3 | description: 前端常用的正则表达式 4 | --- 5 | 6 | # 常用的正则表达式 7 | 8 | ## 代码演示 9 | 10 | ::: info 一、开头不为0的数字 11 | 12 | 13 | ```js 14 | oninput="value = value.replace(/[^\d]/gi,'').replace(/^[0]+[0-9]*$/gi,'').substr(0,11)" 15 | 16 | 采用双重replace方法 17 | 1.replace(/[^\d]/gi,'') 18 | 限制用户只能输入数字 19 | 2.replace(/^[0]+[0-9]*$/gi,'') 20 | 限制第一位不能输入0 21 | 3.substr(0,11) 22 | 限制长度11位数 23 | 24 | 还有一种方式,多个value的判断 25 | oninput="if(value<1){value=null};value=value.replace(/[^0-9]/g,'')" 26 | ``` 27 | ::: 28 | 29 | ::: info 二、输入2位小数 30 | 35 | 36 | ```js 37 | .replace(/[^\d.]/gi, '') 38 | .replace('.', '$#$') 39 | .replace(/\./g, '') 40 | .replace('$#$', '.') 41 | .replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3') 42 | ``` 43 | ::: 44 | 45 | ::: info 三、手机号码格式正则校验 46 | 47 | ```js 48 | /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/ 49 | ``` 50 | ::: 51 | 52 | ::: info 四、Emoji表情正则校验 53 | 54 | ```js 55 | value = value.replace(/[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/gi, '') 56 | ``` 57 | ::: 58 | 59 | -------------------------------------------------------------------------------- /docs/web/wechat/code-watch.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 借助Object.defineProperty实现小程序的watch 3 | description: 微信小程序page没有watch监听,借助Object.defineProperty实现小程序的watch 4 | --- 5 | 6 | # 借助Object.defineProperty实现小程序的watch 7 | 8 | ## 使用示例 9 | 10 | ```js{7-12} 11 | page() { 12 | onLoad(options) { 13 | // 将页面注入到setWatcher中 14 | getApp().setWatcher(this) // [!code --] 15 | }, 16 | 17 | watch: { 18 | val(newVal, oldVal) { 19 | console.log('111::', newVal) 20 | }, 21 | obj(newVal, oldVal) { 22 | console.log('222::', newVal) 23 | } 24 | } 25 | } 26 | ``` 27 | 28 | 29 | ## 封装setWatcher函数 30 | 31 | ```js 32 | // 自定义watch 33 | function setWatcher(page) { 34 | const data = page.data; 35 | const watch = page.watch; 36 | Object.keys(watch).forEach(v => { 37 | const key = v.split('.'); // 将watch中的属性以'.'切分成数组 38 | let nowData = data; // 将data赋值给nowData 39 | for (let i = 0; i < key.length - 1; i++) { // 遍历key数组的元素,除了最后一个! 40 | nowData = nowData[key[i]]; // 将nowData指向它的key属性对象 41 | } 42 | const lastKey = key[key.length - 1]; 43 | const watchFun = watch[v].handler || watch[v]; // 兼容带handler和不带handler的两种写法 44 | const deep = watch[v].deep; // 若未设置deep,则为undefine 45 | observe(nowData, lastKey, watchFun, deep, page); // 监听nowData对象的lastKey 46 | }) 47 | } 48 | 49 | function observe(obj, key, watchFun, deep, page) { 50 | let val = obj[key]; 51 | // 判断deep是true 且 val不能为空 且 typeof val==='object'(数组内数值变化也需要深度监听) 52 | if (deep && val != null && typeof val === 'object') { 53 | Object.keys(val).forEach(childKey => { // 遍历val对象下的每一个key 54 | observe(val, childKey, watchFun, deep, page); // 递归调用监听函数 55 | }) 56 | } 57 | 58 | Object.defineProperty(obj, key, { 59 | configurable: true, 60 | enumerable: true, 61 | set: function (value) { 62 | // 用page对象调用,改变函数内this指向,以便this.data访问data内的属性值 63 | watchFun.call(page, value, val); // value是新值,val是旧值 64 | val = value; 65 | if (deep) { // 若是深度监听,重新监听该对象,以便监听其属性。 66 | observe(obj, key, watchFun, deep, page); 67 | } 68 | }, 69 | get: function () { 70 | return val; 71 | } 72 | }) 73 | } 74 | 75 | module.exports = { 76 | setWatcher 77 | } 78 | ``` 79 | 80 | 引入挂载 81 | 82 | ```js 83 | import { setWatcher } from './utils/custom/watch' 84 | 85 | App({ 86 | onLaunch() { 87 | }, 88 | 89 | // watch 监听的封装,使用需要注入 onLoad(options) { getApp().setWatcher(this) } 90 | setWatcher(pageData) { 91 | setWatcher(pageData) 92 | }, 93 | 94 | globalData: { 95 | } 96 | }) 97 | ``` -------------------------------------------------------------------------------- /docs/other/tools/link/logo.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: GitHub徽标 3 | description: md文件里边使用GitHub徽标 4 | --- 5 | 6 | # GitHub徽标 7 | 8 | > GitHub Badge 也可以叫它徽章 9 | 10 | `Shields.io` 是一个非常流行的在线服务,它可以帮助你为你的项目生成各种各样的徽章。这些徽章通常被嵌入到项目的 `README` 文件、文档网站或其他地方,用来展示项目的各种信息,比如: 11 | 12 | * **构建状态:** 显示你的项目是否构建成功,以及最近一次构建的时间。 13 | 14 | * **代码覆盖率:** 展示你的代码测试覆盖率,反映代码质量。 15 | 16 | * **许可证信息:** 显示你的项目使用的许可证类型。 17 | 18 | * **依赖版本:** 展示项目所依赖的库和它们的版本。 19 | 20 | * **GitHub 星标数量:** 显示项目在 GitHub 上获得的星标数量。 21 | 22 | * **自定义信息:** 你可以自定义徽章的内容,展示任何你想展示的信息。 23 | 24 | ## Shields.io 的优势 25 | 26 | * **种类丰富:** `Shields.io` 提供了大量的徽章模板,涵盖了项目开发的各个方面。 27 | 28 | * **定制灵活:** 你可以自定义徽章的颜色、样式、大小等,以符合你的项目风格。 29 | 30 | * **易于使用:** `Shields.io` 提供了简单易用的 URL 生成方式,你只需按照格式输入相应的信息,即可生成徽章的 URL。 31 | 32 | * **开源:** `Shields.io` 是一个开源项目,你可以自由地使用和定制它。 33 | 34 | ## GithubLink 35 | 36 | [官网直通车   🚘](https://shields.io) 37 | 38 | * **选择徽章类型:** 在 Shields.io 的官网上,你可以找到各种类型的徽章模板。 39 | 40 | * **自定义徽章:** 根据你的需求,选择合适的颜色、样式和内容。 41 | 42 | * **获取徽章链接:** 系统会生成一个包含徽章信息的 URL。 43 | 44 | * **嵌入到 `Markdown` 中:** 将生成的 URL 嵌入到你的 Markdown 文件中,通常使用以下格式: 45 | - Markdown 46 | 47 | ```md 48 | ![一条懒羊羊的GitHub徽标](https://img.shields.io/badge/%E4%BD%9C%E8%80%85-%E4%B8%80%E6%9D%A1%E6%87%92%E7%BE%8A%E7%BE%8A-%233366ff) 49 | ``` 50 | 51 | ![一条懒羊羊的GitHub徽标](https://img.shields.io/badge/%E4%BD%9C%E8%80%85-%E4%B8%80%E6%9D%A1%E6%87%92%E7%BE%8A%E7%BE%8A-%233366ff) 52 | 53 | - html标签 54 | 55 | ```md 56 | 一条懒羊羊的GitHub徽标 57 | ``` 58 | 59 | 一条懒羊羊的GitHub徽标 60 | 61 | ## 如何使用 Shields.io 62 | 63 | ::: info 使用 64 | 65 | > 支持 .svg,.png等可以自定义 66 | 67 | ```md 68 | 一条懒羊羊的GitHub徽标 69 | ``` 70 | 71 | 一条懒羊羊的GitHub徽标 72 | 73 | ```html 74 | 一条懒羊羊的GitHub徽标 75 | ``` 76 | 一条懒羊羊的GitHub徽标 77 | 78 | ::: 79 | 80 | ## 为什么使用 Shields.io 81 | 82 | * **提升项目专业度:** 徽章可以让你的项目看起来更加专业和有吸引力。 83 | 84 | * **提供快速信息:** 用户可以通过徽章快速了解项目的相关信息,而无需查看详细的文档。 85 | 86 | * **促进交流:** 徽章可以引发讨论和交流,帮助你获得更多的反馈。 87 | 88 | ## 总结 89 | 90 | `Shields.io` 是一个非常实用的工具,可以帮助你为你的项目增添光彩。通过使用 `Shields.io`,你可以轻松地创建各种各样的徽章,以展示项目的相关信息,提升项目的专业度。 91 | 92 | -------------------------------------------------------------------------------- /docs/web/basics/reflow-repaint.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 浏览器的回流与重绘 3 | description: 浏览器的回流与重绘 4 | --- 5 | 6 | # 浏览器的回流与重绘 7 | 8 | > 核心就是`