提交 afd50e58 编写于 作者: TheWayYouMakeMeFeel's avatar TheWayYouMakeMeFeel

fix error

上级 097bfc2a
# 任务二:开源项目开发与运行
## 一、任务介绍
1024程序员节结合开源大趋势,开发者可根据自己情况选择业界知名开源项目或自研可开源项目结合GitCode和Cloud IDE进行开发与适配,需要在IDE中能够运行起来为标准获得CSDN定制书包奖励。
特别提醒:不可直接使用官方提供的demo项目参赛(官方demo: [前端项目2048](https://gitcode.net/cloud-ide/2048)[后端项目CnOCR](https://gitcode.net/cloud-ide/cnocr)
## 二、任务步骤 (请按照步骤提示操作,并自行检查是否遗漏哦~)
| 顺序 | 步骤名称 | 步骤描述 | 示意图 |
| ---- | ---- | ---- | ---- |
| 1 | 任务报名 | Fork创建项目,在项目中右上角点击Fork按钮,完成后即报名成功 | ![](https://gitcode.net/gitcode/1024opensource/uploads/8db3366911695d7e1c6851833634deb7/%E4%BC%81%E4%B8%9A%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_f43ff07c-d546-4dc3-8e00-07fde528d955.png) |
| 2 | 项目导入 | 上传开源项目或自研可开源项目至Fork项目中 | ![](https://gitcode.net/theo789/upload_project/uploads/9280a335d186801ece171b56ee83ad0c/image.png) |
| 3 | IDE打开项目 | 使用Cloud IDE打开项目,Fork项目链接地址中快速启动IDE | ![](https://gitcode.net/theo789/upload_project/uploads/ca739c3c5252cd6f25d0e4d01656afbf/image.png) |
| 4 | IDE中项目运行 | 项目下载完成后,需要下载对应扩展,需要能够运行启动项目 | 前端项目可执行预览,后端项目可展示启动 ![](https://gitcode.net/theo789/upload_project/uploads/4fabe699f2ae7d3870a0562a44ae2505/image.png) |
| 5 | 配置自动运行脚本 | 编写preview.yml文件,能够让项目自动运行 | 可参考 [前端项目2048](https://gitcode.net/cloud-ide/2048)[后端项目CnOCR](https://gitcode.net/cloud-ide/cnocr)|
| 6 | 回传至开源项目 | 完成项目开发后,使用IDE的Git操作完成push代码 | ![](https://gitcode.net/theo789/upload_project/uploads/f29bf06cd2b96e07b67b47873fbe278f/image.png) |
| 7 | 项目完成 | 至此项目已完成开发,可自行检查是否合格,**检验方法:自己新建空间,然后测试能不能自动运行。** | CSDN官方会每周末统一核查确认奖励,希望大家都可以获得CSDN定制书包 ![](https://img-home.csdnimg.cn/images/20221013053300.png) |
## 三、奖品发放规则
**奖品发放时间点**
| 次数 | 公布中奖名单 |
| ------ | ------ |
| 第一次 | 2022-10-31 |
| 第二次 | 2022-11-07 |
| 第三次 | 2022-11-14 |
**活动参与和获奖规则**
- 本项任务,开发者只能获得一次奖励。
- 官方工作人员会通过私信或短信通知获奖开发者填写收货地址。
- 发货时间:活动结束后30个工作日内发货
## 四、活动交流
开源活动官方交流群(仅参与者之间讨论和交流)。扫码进入选手沟通群。活动重要节点通知会在群内第一时间告知,请所有参与者尽量加群。
<img src="/uploads/45be870f33053a686cb60b7c8cca38c4/b435ccc7d422528ad8212ca53d687687.jpg" width="400px" style="border: 6px solid #fff;border-radius: 2px;">
## 五、活动点评
### 活动建议
如果大家对本次活动有建议,可以直接在本项目中提交issue,我们会认真对待每一个评论,非常感谢大家!!!
### 活动点赞👍
如果大家喜欢本次开源挑战赛活动,可以点击本项目的star,我们会根据大家的star数作为后期是否长期举办的重要依据,非常感谢大家!!!
## 六 英文字体工具简介
一个生成各种英文字体的工具
例如:
1. 𝙡𝙤𝙫𝙚 𝙖𝙣𝙙 𝙥𝙚𝙖𝙘𝙚
2. 𝐥𝐨𝐯𝐞 𝐚𝐧𝐝 𝐩𝐞𝐚𝐜𝐞
3. ˡᵒᵛᵉ ᵃⁿᵈ ᵖᵉᵃᶜᵉ
4. 𝑙𝑜𝑣𝑒 𝑎𝑛𝑑 𝑝𝑒𝑎𝑐𝑒
5. 𝓵𝓸𝓿𝓮 𝓪𝓷𝓭 𝓹𝓮𝓪𝓬𝓮
6. 𝕝𝕠𝕧𝕖 𝕒𝕟𝕕 𝕡𝕖𝕒𝕔𝕖
等等多达10多种字体
### 使用
在输入框输入英文即可自动生成
点击想要的字体即可复制
<!-- ![在这里插入图片描述](https://img-blog.csdnimg.cn/d8227adcc424498fa8a446389b036ce6.jpeg#pic_center) -->
const proPlugins = []
// 如果当前是测试环境或者是生产环境,则使用去掉 console 的插件
if (process.env.NODE_ENV === 'test' || process.env.NODE_ENV === 'production') {
proPlugins.push('transform-remove-console')
}
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset',
],
plugins: [...proPlugins],
}
{
"compilerOptions": {
"strict": true,
"target": "es5",
"module": "es2020",
"moduleResolution": "node",
"baseUrl": "./",
"paths": {
"@/*": ["src/*"],
"@admin/*": ["src/pages/admin/*"],
},
},
"exclude": ["node_modules"]
}
{
"name": "vue-mpa-project-template",
"version": "0.1.0",
"private": true,
"description": "",
"scripts": {
"cz": "cz",
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"config": "vue inspect > output.js"
},
"dependencies": {
"axios": "^0.21.1",
"core-js": "^3.8.3",
"vue": "^2.6.12",
"vue-router": "^3.5.1",
"vuex": "^3.6.2",
"vant": "^2.12.21"
},
"devDependencies": {
"@commitlint/cli": "^12.1.1",
"@commitlint/config-conventional": "^12.1.1",
"@vue/cli-plugin-babel": "^4.5.12",
"@vue/cli-plugin-eslint": "^4.5.12",
"@vue/cli-plugin-router": "^4.5.12",
"@vue/cli-plugin-vuex": "^4.5.12",
"@vue/cli-service": "^4.5.12",
"@vue/eslint-config-standard": "^5.1.2",
"babel-eslint": "^10.1.0",
"babel-plugin-import": "^1.13.0",
"babel-plugin-transform-remove-console": "^6.9.4",
"commitizen": "^4.2.3",
"compression-webpack-plugin": "^4.0.0",
"cz-conventional-changelog": "^3.3.0",
"eslint": "^6.7.2",
"eslint-config-better": "^0.0.12",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"eslint-plugin-vue": "^6.2.2",
"husky": "^6.0.0",
"postcss-pxtorem": "^5.1.1",
"sass": "1.39.0",
"sass-loader": "^8.0.2",
"style-resources-loader": "^1.3.3",
"stylelint": "^13.6.1",
"stylelint-config-standard": "^20.0.0",
"stylelint-scss": "^3.19.0",
"stylelint-webpack-plugin": "^2.1.1",
"svg-sprite-loader": "^6.0.11",
"vue-template-compiler": "^2.6.12",
"webpack-bundle-analyzer": "^3.8.0"
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
}
此差异已折叠。
# preview.yml
autoOpen: true # 打开工作空间时是否自动开启所有应用的预览
apps:
- port: 8082 # 应用的端口
run: pnpm i --registry=https://registry.npmmirror.com && pnpm serve # 应用的启动命
command: # 使用此命令启动服务,且不执行run
root: ./ # 应用的启动目录
name: 花式字体 # 应用名称
description: 一个生成各种英文字体的工具 # 应用描述
autoOpen: true # 打开工作空间时是否自动开启预览(优先级高于根级 autoOpen
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="renderer" content="webkit">
<meta name="force-rendering" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover,user-scalable=no">
<meta name="referrer" content="no-referrer" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title></title>
</head>
<body>
<div id="app"></div>
</body>
</html>
<template>
<div id="app">
<router-view :key="key" />
</div>
</template>
<script>
export default {
name: 'App',
computed: {
key () {
return this.$route.path
},
},
}
</script>
<style lang="scss">
#app {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: $text-color-primary;
height: 100%;
min-height: 100vh;
}
</style>
import Vue from 'vue'
import router from './router'
import App from './App.vue'
import '@/styles/index.scss'
import 'vant/lib/index.css'
// 全部引入 vant 组件
import Vant, { Lazyload } from 'vant'
Vue.use(Vant)
Vue.use(Lazyload)
Vue.config.productionTip = false
Vue.config.performance = process.env.NODE_ENV !== 'production'
new Vue({
router,
render: h => h(App),
}).$mount('#app')
import Vue from 'vue'
import VueRouter from 'vue-router'
import font from '@/views/font/index.vue'
// 移除 router 的报错信息
const originalPush = VueRouter.prototype.push
const originalReplace = VueRouter.prototype.replace
VueRouter.prototype.push = function push (...args) {
return originalPush.call(this, ...args).catch(err => err)
}
VueRouter.prototype.replace = function replace (...args) {
return originalReplace.call(this, ...args).catch(err => err)
}
Vue.use(VueRouter)
// 初始化的路由列表
export const tabBars = [
{
name: 'Font',
path: '/',
component: font,
meta: { title: '字体转换', icon: 'icon-yingyong', keepAlive: false },
},
]
const createRouter = () => new VueRouter({
scrollBehavior: () => ({
y: 0,
}),
routes: tabBars,
})
// 实例化 router
const router = createRouter()
export default router
/**
* 前置路由守卫
* @param {*} to
* @param {*} from
* @param {*} next
* @returns
*/
export const routerBeforeEach = async (to, from, next) => {
next()
}
/**
* 后置路由守卫
* @param {*} to
*/
export const routerAfterEach = (to) => {
document.title = `${to.query.title || to.meta?.title || ''}`
}
.flex-start-start {
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
align-items: flex-start;
}
.flex-start-end {
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
align-items: flex-end;
}
.flex-start-center {
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
align-items: center;
}
.flex-start-baseline {
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
align-items: baseline;
}
.flex-start-stretch {
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
align-items: stretch;
}
.flex-end-start {
display: flex;
flex-flow: row nowrap;
justify-content: flex-end;
align-items: flex-start;
}
.flex-end-end {
display: flex;
flex-flow: row nowrap;
justify-content: flex-end;
align-items: flex-end;
}
.flex-end-center {
display: flex;
flex-flow: row nowrap;
justify-content: flex-end;
align-items: center;
}
.flex-end-baseline {
display: flex;
flex-flow: row nowrap;
justify-content: flex-end;
align-items: baseline;
}
.flex-end-stretch {
display: flex;
flex-flow: row nowrap;
justify-content: flex-end;
align-items: stretch;
}
.flex-center-start {
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: flex-start;
}
.flex-center-end {
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: flex-end;
}
.flex-center-center {
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
}
.flex-center-baseline {
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: baseline;
}
.flex-center-stretch {
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: stretch;
}
.flex-between-start {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: flex-start;
}
.flex-between-end {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: flex-end;
}
.flex-between-center {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
}
.flex-between-baseline {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: baseline;
}
.flex-between-stretch {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: stretch;
}
.flex-around-start {
display: flex;
flex-flow: row nowrap;
justify-content: space-around;
align-items: flex-start;
}
.flex-around-end {
display: flex;
flex-flow: row nowrap;
justify-content: space-around;
align-items: flex-end;
}
.flex-around-center {
display: flex;
flex-flow: row nowrap;
justify-content: space-around;
align-items: center;
}
.flex-around-baseline {
display: flex;
flex-flow: row nowrap;
justify-content: space-around;
align-items: baseline;
}
.flex-around-stretch {
display: flex;
flex-flow: row nowrap;
justify-content: space-around;
align-items: stretch;
}
.flex-wrap-start-start {
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
align-items: flex-start;
}
.flex-wrap-start-end {
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
align-items: flex-end;
}
.flex-wrap-start-center {
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
align-items: center;
}
.flex-wrap-start-baseline {
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
align-items: baseline;
}
.flex-wrap-start-stretch {
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
align-items: stretch;
}
.flex-wrap-end-start {
display: flex;
flex-flow: row wrap;
justify-content: flex-end;
align-items: flex-start;
}
.flex-wrap-end-end {
display: flex;
flex-flow: row wrap;
justify-content: flex-end;
align-items: flex-end;
}
.flex-wrap-end-center {
display: flex;
flex-flow: row wrap;
justify-content: flex-end;
align-items: center;
}
.flex-wrap-end-baseline {
display: flex;
flex-flow: row wrap;
justify-content: flex-end;
align-items: baseline;
}
.flex-wrap-end-stretch {
display: flex;
flex-flow: row wrap;
justify-content: flex-end;
align-items: stretch;
}
.flex-wrap-center-start {
display: flex;
flex-flow: row wrap;
justify-content: center;
align-items: flex-start;
}
.flex-wrap-center-end {
display: flex;
flex-flow: row wrap;
justify-content: center;
align-items: flex-end;
}
.flex-wrap-center-center {
display: flex;
flex-flow: row wrap;
justify-content: center;
align-items: center;
}
.flex-wrap-center-baseline {
display: flex;
flex-flow: row wrap;
justify-content: center;
align-items: baseline;
}
.flex-wrap-center-stretch {
display: flex;
flex-flow: row wrap;
justify-content: center;
align-items: stretch;
}
.flex-wrap-between-start {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
align-items: flex-start;
}
.flex-wrap-between-end {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
align-items: flex-end;
}
.flex-wrap-between-center {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
align-items: center;
}
.flex-wrap-between-baseline {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
align-items: baseline;
}
.flex-wrap-between-stretch {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
align-items: stretch;
}
.flex-wrap-around-start {
display: flex;
flex-flow: row wrap;
justify-content: space-around;
align-items: flex-start;
}
.flex-wrap-around-end {
display: flex;
flex-flow: row wrap;
justify-content: space-around;
align-items: flex-end;
}
.flex-wrap-around-center {
display: flex;
flex-flow: row wrap;
justify-content: space-around;
align-items: center;
}
.flex-wrap-around-baseline {
display: flex;
flex-flow: row wrap;
justify-content: space-around;
align-items: baseline;
}
.flex-wrap-around-stretch {
display: flex;
flex-flow: row wrap;
justify-content: space-around;
align-items: stretch;
}
.flex-col-start-start {
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
align-items: flex-start;
}
.flex-col-start-end {
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
align-items: flex-end;
}
.flex-col-start-center {
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
align-items: center;
}
.flex-col-start-baseline {
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
align-items: baseline;
}
.flex-col-start-stretch {
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
align-items: stretch;
}
.flex-col-end-start {
display: flex;
flex-flow: column nowrap;
justify-content: flex-end;
align-items: flex-start;
}
.flex-col-end-end {
display: flex;
flex-flow: column nowrap;
justify-content: flex-end;
align-items: flex-end;
}
.flex-col-end-center {
display: flex;
flex-flow: column nowrap;
justify-content: flex-end;
align-items: center;
}
.flex-col-end-baseline {
display: flex;
flex-flow: column nowrap;
justify-content: flex-end;
align-items: baseline;
}
.flex-col-end-stretch {
display: flex;
flex-flow: column nowrap;
justify-content: flex-end;
align-items: stretch;
}
.flex-col-center-start {
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: flex-start;
}
.flex-col-center-end {
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: flex-end;
}
.flex-col-center-center {
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
}
.flex-col-center-baseline {
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: baseline;
}
.flex-col-center-stretch {
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: stretch;
}
.flex-col-between-start {
display: flex;
flex-flow: column nowrap;
justify-content: space-between;
align-items: flex-start;
}
.flex-col-between-end {
display: flex;
flex-flow: column nowrap;
justify-content: space-between;
align-items: flex-end;
}
.flex-col-between-center {
display: flex;
flex-flow: column nowrap;
justify-content: space-between;
align-items: center;
}
.flex-col-between-baseline {
display: flex;
flex-flow: column nowrap;
justify-content: space-between;
align-items: baseline;
}
.flex-col-between-stretch {
display: flex;
flex-flow: column nowrap;
justify-content: space-between;
align-items: stretch;
}
.flex-col-around-start {
display: flex;
flex-flow: column nowrap;
justify-content: space-around;
align-items: flex-start;
}
.flex-col-around-end {
display: flex;
flex-flow: column nowrap;
justify-content: space-around;
align-items: flex-end;
}
.flex-col-around-center {
display: flex;
flex-flow: column nowrap;
justify-content: space-around;
align-items: center;
}
.flex-col-around-baseline {
display: flex;
flex-flow: column nowrap;
justify-content: space-around;
align-items: baseline;
}
.flex-col-around-stretch {
display: flex;
flex-flow: column nowrap;
justify-content: space-around;
align-items: stretch;
}
.flex-col-wrap-start-start {
display: flex;
flex-flow: column wrap;
justify-content: flex-start;
align-items: flex-start;
}
.flex-col-wrap-start-end {
display: flex;
flex-flow: column wrap;
justify-content: flex-start;
align-items: flex-end;
}
.flex-col-wrap-start-center {
display: flex;
flex-flow: column wrap;
justify-content: flex-start;
align-items: center;
}
.flex-col-wrap-start-baseline {
display: flex;
flex-flow: column wrap;
justify-content: flex-start;
align-items: baseline;
}
.flex-col-wrap-start-stretch {
display: flex;
flex-flow: column wrap;
justify-content: flex-start;
align-items: stretch;
}
.flex-col-wrap-end-start {
display: flex;
flex-flow: column wrap;
justify-content: flex-end;
align-items: flex-start;
}
.flex-col-wrap-end-end {
display: flex;
flex-flow: column wrap;
justify-content: flex-end;
align-items: flex-end;
}
.flex-col-wrap-end-center {
display: flex;
flex-flow: column wrap;
justify-content: flex-end;
align-items: center;
}
.flex-col-wrap-end-baseline {
display: flex;
flex-flow: column wrap;
justify-content: flex-end;
align-items: baseline;
}
.flex-col-wrap-end-stretch {
display: flex;
flex-flow: column wrap;
justify-content: flex-end;
align-items: stretch;
}
.flex-col-wrap-center-start {
display: flex;
flex-flow: column wrap;
justify-content: center;
align-items: flex-start;
}
.flex-col-wrap-center-end {
display: flex;
flex-flow: column wrap;
justify-content: center;
align-items: flex-end;
}
.flex-col-wrap-center-center {
display: flex;
flex-flow: column wrap;
justify-content: center;
align-items: center;
}
.flex-col-wrap-center-baseline {
display: flex;
flex-flow: column wrap;
justify-content: center;
align-items: baseline;
}
.flex-col-wrap-center-stretch {
display: flex;
flex-flow: column wrap;
justify-content: center;
align-items: stretch;
}
.flex-col-wrap-between-start {
display: flex;
flex-flow: column wrap;
justify-content: space-between;
align-items: flex-start;
}
.flex-col-wrap-between-end {
display: flex;
flex-flow: column wrap;
justify-content: space-between;
align-items: flex-end;
}
.flex-col-wrap-between-center {
display: flex;
flex-flow: column wrap;
justify-content: space-between;
align-items: center;
}
.flex-col-wrap-between-baseline {
display: flex;
flex-flow: column wrap;
justify-content: space-between;
align-items: baseline;
}
.flex-col-wrap-between-stretch {
display: flex;
flex-flow: column wrap;
justify-content: space-between;
align-items: stretch;
}
.flex-col-wrap-around-start {
display: flex;
flex-flow: column wrap;
justify-content: space-around;
align-items: flex-start;
}
.flex-col-wrap-around-end {
display: flex;
flex-flow: column wrap;
justify-content: space-around;
align-items: flex-end;
}
.flex-col-wrap-around-center {
display: flex;
flex-flow: column wrap;
justify-content: space-around;
align-items: center;
}
.flex-col-wrap-around-baseline {
display: flex;
flex-flow: column wrap;
justify-content: space-around;
align-items: baseline;
}
.flex-col-wrap-around-stretch {
display: flex;
flex-flow: column wrap;
justify-content: space-around;
align-items: stretch;
}
$direction: (
row: row,
col: column,
);
$justify: (
start: flex-start,
end: flex-end,
center: center,
between: space-between,
around: space-around,
);
$align: (
start: flex-start,
end: flex-end,
center: center,
baseline: baseline,
stretch: stretch,
);
$wrap: (
nowrap: nowrap,
wrap: wrap,
);
@each $d in map-keys($direction) {
$dir: #{if($d == 'row', '', -$d)};
@each $w in map-keys($wrap) {
$wra: #{if($w == nowrap, '', -$w)};
@each $j in map-keys($justify) {
@each $a in map-keys($align) {
.flex#{$dir}#{$wra}-#{$j}-#{$a} {
display: flex;
flex-flow: map-get($direction, $d) map-get($wrap, $w);
justify-content: map-get($justify, $j);
align-items: map-get($align, $a);
}
}
}
}
}
@import './mixins.scss';
// 本文件为全局样式配置
// 单行显示省略号
.g-ellipsis {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
// 两行显示省略号
.g-ellipsis-2 {
@include multiline-ellipsis(2);
}
// 三行显示省略号
.g-ellipsis-3 {
@include multiline-ellipsis(3);
}
// 旋转动画关键帧
@keyframes g-keyframes-rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
// 旋转 class
.g-rotate {
animation: 0.8s g-keyframes-rotate linear infinite;
}
// 基础按钮样式
.g-btn-reset {
border: 0;
outline: 0;
&::after {
border: 0;
outline: 0;
display: none;
}
}
// 绝对定位且水平垂直居中
.g-absolute-center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
// 滚动条样式
.g-scroll-style {
overflow-y: auto;
&::-webkit-scrollbar {
/* 滚动条整体样式 */
width: 6px; /* 高宽分别对应横竖滚动条的尺寸 */
height: 1px;
}
&::-webkit-scrollbar-track {
/* 滚动条里面轨道 */
border-radius: 10px;
background: transparent;
}
&::-webkit-scrollbar-thumb {
/* 滚动条里面小方块 */
border-radius: 6px;
background: #DCE6F1;
}
// &:hover {
// &::-webkit-scrollbar-thumb {
// /* 滚动条里面小方块 */
// border-radius: 6px;
// background: #DCE6F1;
// }
// }
}
// END
.g-delete-btn {
color: $color-danger !important;
}
.g-border-bottom {
border-bottom: 1px solid #e5e5e5;
}
// 背景透明度
.g-bg-opacity {
opacity: 0.9;
}
// radio box
.g-radio-checked {
width: 14px;
height: 14px;
background-color: #fff;
border-radius: 50%;
border: 5px solid #2487F6;
}
.g-radio-no-checked {
width: 14px;
height: 14px;
background-color: #fff;
border-radius: 50%;
border: 1px solid #dcdfe6;
}
@import "./root.scss";
@import "./flex.scss";
@import './global.scss';
@import './transition.scss';
// @import './pxtorem.scss';
// 旋转动画关键帧
@keyframes g-keyframes-rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
// 按钮
@mixin btn ($bg: #448ACA, $txt-color: #ffffff, $width: 100%, $fontSize: 14px) {
text-align: center;
background: $bg;
color: $txt-color;
width: $width;
font-size: $fontSize;
padding: 0.5em 0;
border-radius: 5px;
&:hover {
background: #559bdb;
}
}
// 单行显示省略号
@mixin singleline-ellipsis () {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
// 多行显示省略号
@mixin multiline-ellipsis ($count: 2) {
display: -webkit-box;
-webkit-line-clamp: $count;
-webkit-box-orient: vertical;
overflow: hidden;
word-break: break-all;
word-wrap: break-word;
text-overflow: ellipsis;
white-space: normal;
}
// 渐变色文字
@mixin linear-gradient-text ($params...) {
background: linear-gradient($params);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
}
html {
font-size: calc(100vw / 19.2);
min-height: 768px;
min-width: 1366px;
}
// 宽度小于 1600px 时
@media screen and (max-width: 1600px) {
html {
// 1600 / 1920
font-size: 83.33px;
}
}
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: inherit;
min-height: 0;
min-width: 0;
}
html,
body,
#app {
position: relative;
overflow: hidden;
margin: 0;
padding: 0;
width: 100%;
height: 100%;
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif;
-webkit-font-smoothing: antialiased;
-webkit-tap-highlight-color: transparent;
background-color: $color-page-back;
font-size: $font-size-14;
color: $text-color-primary;
}
// global transition css
/* fade */
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.28s;
}
.fade-enter,
.fade-leave-active {
opacity: 0;
}
/* fade-transform */
.fade-transform-leave-active,
.fade-transform-enter-active {
transition: all 0.5s;
}
.fade-transform-enter {
opacity: 0;
transform: translateX(-30px);
}
.fade-transform-leave-to {
opacity: 0;
transform: translateX(30px);
}
/* breadcrumb transition */
.breadcrumb-enter-active,
.breadcrumb-leave-active {
transition: all 0.5s;
}
.breadcrumb-enter,
.breadcrumb-leave-active {
opacity: 0;
transform: translateX(20px);
}
.breadcrumb-move {
transition: all 0.5s;
}
.breadcrumb-leave-active {
position: absolute;
}
// 需扩展变量时,在对应类型设置语义化的变量名,并写注释说明。
// 字体
$text-color-primary: #2c353e; // 全局默认字体颜色
$text-color-placeholder: #a8abb2; // 占位符字体颜色
$text-color-disabled: #c0c4cc; // 禁用字体颜色
// 边框
$border-color: #dcdfe6; // 边框颜色
$border-color-hover: $text-color-disabled; // 边框hover颜色
// icon 颜色
$color-icon: #828992;
$color-pink: #eea2a4;
// 背景色
$color-page-back: #eee;
// 盒子
$box-color: #fff;
$box-color-hover: #f5f7fa; // 盒子hover颜色
// 主题色
$color-theme: #2487f6; // 全局默认主题色
$color-theme-light-3: #79bbff;
$color-theme-light-5: #a0cfff;
$color-theme-light-7: #c6e2ff;
$color-theme-light-8: #d9ecff;
$color-theme-light-9: #ecf5ff;
// 成功辅助色
$color-success: #67c23a; // 成功颜色
$color-success-light-3: #95d475;
$color-success-light-5: #b3e19d;
$color-success-light-7: #d1edc4;
$color-success-light-8: #e1f3d8;
$color-success-light-9: #f0f9eb;
// 警告辅助色
$color-warning: #e6a23c;
$color-warning-light-3: #eebe77;
$color-warning-light-5: #f3d19e;
$color-warning-light-7: #f8e3c5;
$color-warning-light-8: #faecd8;
$color-warning-light-9: #fdf6ec;
// 危险辅助色
$color-danger: #f56c6c;
$color-danger-light-3: #f89898;
$color-danger-light-5: #fab6b6;
$color-danger-light-7: #fcd3d3;
$color-danger-light-8: #fde2e2;
$color-danger-light-9: #fef0f0;
// 信息辅助色
$color-info: #909399;
$color-info-light-3: #b1b3b8;
$color-info-light-5: #c8c9cc;
$color-info-light-7: #dedfe0;
$color-info-light-8: #e9e9eb;
$color-info-light-9: #f4f4f5;
// 字体大小
$font-size-2: 2px;
$font-size-4: $font-size-2 * 2;
$font-size-12: $font-size-2 * 6;
$font-size-14: $font-size-2 * 7; // 全局默认文本大小14px,通常不需要手动设置
$font-size-16: $font-size-2 * 8;
$font-size-18: $font-size-2 * 9;
$font-size-20: $font-size-2 * 10;
$font-size-22: $font-size-2 * 11;
$font-size-24: $font-size-2 * 12;
// padding 与 margin
$space-2: 2px;
$space-4: $space-2 * 2;
$space-6: $space-2 * 3;
$space-8: $space-2 * 4;
$space-10: $space-2 * 5;
$space-12: $space-2 * 6;
$space-14: $space-2 * 7;
$space-16: $space-2 * 8; // 边距一般为16px
$space-18: $space-2 * 9;
$space-20: $space-2 * 10;
// radius
$radius-2: 2px;
$radius-4: $radius-2 * 2;
$radius-6: $radius-2 * 3;
$radius-8: $radius-2 * 4;
$radius-10: $radius-2 * 5;
$radius-circle: 50%;
// 边框宽度
$border-width-1px: 1px;
$border-width-2px: 2px;
// layout header高度
$header-height: 60px;
import { Toast } from 'vant'
// 获取数据类型
export const getType = value => Object.prototype.toString.call(value).slice(8, -1)
// 将钱转换为 ¥xx.yy
export const currency = val => `¥${val.toFixed(2)}`
// 十六进制颜色字符串转 rgba 字符串
export const hexToRgba = (hexColor, alpha = 1) => {
const reg = /^#(?<hex>[0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/iu
let sColor = hexColor.toLowerCase()
if (sColor && reg.test(sColor)) { // 如果是十六进制颜色 '#fff' '#ffffff'
if (sColor.length === 4) { // 如果是 缩写,转为全写
let sColorNew = '#'
for (let i = 1; i < 4; i++) {
sColorNew += `${sColor[i]}${sColor[i]}`
}
sColor = sColorNew
}
const sColorChange = []
for (let i = 1; i < 7; i += 2) {
sColorChange.push(parseInt(`0x${sColor.slice(i, i + 2)}`))
}
return `rgba(${sColorChange[0]}, ${sColorChange[1]}, ${sColorChange[2]}, ${alpha})`
}
return sColor
}
export const getRandomNumber = (start, end) => Number.parseInt((Math.random() * (end - start)) + start)
export const getUniqueKey = (length = 10) => {
const num = '0123456789'
const lowercase = 'abcdefghijklmnopqrstuvwxyz'
const uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
const chars = `${num}${lowercase}${uppercase}`
const end = chars.length
let result = ''
for (let i = 0; i < length; i++) {
result += chars[getRandomNumber(0, end)]
}
return result
}
/**
* 构造树型结构数据
* @param {*} data 数据源
* @param {*} id id字段 默认 'id'
* @param {*} parentId 父节点字段 默认 'parentId'
* @param {*} children 孩子节点字段 默认 'children'
*/
export const handleTree = (data, id, parentId, children) => {
const config = {
id: id || 'id',
parentId: parentId || 'parentId',
childrenList: children || 'children',
}
const childrenListMap = {}
const nodeIds = {}
const tree = []
const adaptToChildrenList = o => {
if (childrenListMap[o[config.id]] !== null) {
o[config.childrenList] = childrenListMap[o[config.id]]
}
if (o[config.childrenList]) {
for (const c of o[config.childrenList]) {
adaptToChildrenList(c)
}
}
}
for (const d of data) {
const parentId = d[config.parentId]
if (childrenListMap[parentId] === undefined) {
childrenListMap[parentId] = []
}
nodeIds[d[config.id]] = d
childrenListMap[parentId].push(d)
}
for (const d of data) {
const parentId = d[config.parentId]
if (nodeIds[parentId] === undefined) {
tree.push(d)
}
}
for (const t of tree) {
adaptToChildrenList(t)
}
return tree
}
/**
* blob 下载
* @param { Blob } blob 文件流
* @param { String } filename 文件名称
*/
export const blobDownload = (blob, filename) => {
if ('download' in document.createElement('a')) {
const elink = document.createElement('a')
elink.download = filename
elink.style.display = 'none'
elink.href = URL.createObjectURL(blob)
document.body.appendChild(elink)
elink.click()
URL.revokeObjectURL(elink.href)
document.body.removeChild(elink)
} else {
navigator.msSaveBlob(blob, filename)
}
}
/**
* 通用文件下载
* @param { String } url 文件url
* @param { String } filename 文件名称
* @return { Promise }
*/
export const download = (url, filename = Date().valueOf()) => new Promise((resolve, reject) => {
if (!url) {
// 展示错误消息
Toast({
message: '文件路径为空',
type: 'fail',
duration: 3 * 1000,
})
reject(new Error('文件路径为空'))
return
}
fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
responseType: 'blob',
}).then(response => {
if (response.status !== 200) {
Toast({
message: `文件下载失败 code:${response.status}`,
type: 'error',
duration: 3 * 1000,
})
reject(Error(`${response.status} ${response.type}`))
return
}
const suffix = url?.slice(url.lastIndexOf('.'))
response.blob().then(blob => {
blobDownload(blob, `${filename}${suffix}`)
resolve()
})
}).catch(err => {
// 展示错误消息
Toast({
message: '文件下载失败',
type: 'error',
duration: 3 * 1000,
})
reject(err)
})
})
/**
* 通用文件导入
* @param { String } accept 文件格式
* @param { Boolean } false 是否多选
* @return { Promise } files 文件列表
*/
export const importFile = (accept = '*', multiple = false) => new Promise((resolve, reject) => {
const input = document.createElement('input')
input.type = 'file'
input.accept = accept
input.multiple = accept
try {
input.oninput = () => {
resolve(input.files)
}
} catch (error) {
reject(error)
}
input.click()
})
/**
* 变量类型判断
* @param { String } type - 需要判断的类型
* @param { any } value - 需要判断的值
* @returns { Boolean } - 是否该类型
*/
export const isType = (type, value) => Object.prototype.toString.call(value).slice(8, -1) === type
/**
* 深拷贝变量-递归算法(recursive algorithm)
* 支持 String,Number,Boolean,null,undefined,Object,Array,Date,RegExp,Error 类型
* @param { any } arg - 需要深拷贝的变量
* @returns { any } - 拷贝完成的值
*/
export const deepCopyRA = arg => {
const newValue = isType('Object', arg) // 判断是否是对象
? {}
: isType('Array', arg) // 判断是否是数组
? []
: isType('Date', arg) // 判断是否是日期对象
? new arg.constructor(+arg)
: isType('RegExp', arg) || isType('Error', arg) // 判断是否是正则对象或错误对象
? new arg.constructor(arg)
: arg
// 判断是否是数组或对象
if (isType('Object', arg) || isType('Array', arg)) {
// 循环遍历
// eslint-disable-next-line
for (const key in arg) {
// 防止原型链的值
Object.prototype.hasOwnProperty.call(arg, key) && (newValue[key] = deepCopyRA(arg[key]))
}
}
return newValue
}
import { Toast } from 'vant'
/**
* 复制
* @param { String } text 文本
*/
export const copy = text => new Promise((resolve, reject) => {
const copyInput = document.createElement('input') // 创建input元素
document.body.appendChild(copyInput)// 向页面底部追加输入框
copyInput.setAttribute('value', text)// 添加属性,将url赋值给input元素的value属性
copyInput.select() // 选择input元素
document.execCommand('Copy') // 执行复制命令
copyInput.remove() // 删除动态创建的节点
Toast.success('复制成功快去使用吧')
resolve()
})
export const setSession = (key, value) => sessionStorage.setItem(key, JSON.stringify(value))
export const setLocal = (key, value) => localStorage.setItem(key, JSON.stringify(value))
export const getSession = key => JSON.parse(sessionStorage.getItem(key))
export const getLocal = key => JSON.parse(localStorage.getItem(key))
export const removeSession = key => sessionStorage.removeItem(key)
export const removeLocal = key => localStorage.removeItem(key)
export const removeAllSession = () => sessionStorage.clear()
export const removeAllLocal = () => localStorage.clear()
<template>
<div class="font-div">
<div class="rule flex-col-start-start">
<p class="line">使用方法:</p>
<p class="line">1. 输入英文即可自动生成各式字体</p>
<p class="line">2. 点击喜欢的字体即可复制</p>
</div>
<div class="input-box">
<div class="title">字体转换</div>
<van-field
v-model="message"
rows="1"
class="van-field"
type="textarea"
:show-confirm-bar="false"
clearable
autosize
placeholder="输入字母自动生成(只支持英文)"
/>
</div>
<div
v-for="(text, index) in reversedMessage"
:key="index"
class="text"
:class="{active: copyIndex === index}"
@click="handleCopy(text, index)"
>
{{ text }}
</div>
</div>
</template>
<script>
import { copy } from '@/utils/project'
import uniCodeMap from './uniCodeMap'
import { getSession, removeSession } from '../../utils/storage'
export default {
name: 'FontView',
data () {
return {
message: '',
uniCodes: uniCodeMap,
copyIndex: null,
}
},
computed: {
reversedMessage ({ uniCodes, message }) {
message = message || 'love and peace'
return uniCodes.map(([lower, uppercase, special, toLower]) => {
let text = ''
for (let codePoint of message) {
toLower && (codePoint = codePoint.toLowerCase())
if (special && special[codePoint] !== undefined) {
codePoint = special[codePoint]
} else {
codePoint = codePoint.charCodeAt()
}
if (codePoint >= 65 && codePoint <= 90) {
codePoint += uppercase
text += String.fromCodePoint(codePoint)
} else if (codePoint >= 97 && codePoint <= 122) { // a - z 转换
codePoint += lower
text += String.fromCodePoint(codePoint)
} else {
text += String.fromCodePoint(codePoint)
}
}
return text
})
},
},
created () {
const text = getSession('text')
this.message = text
removeSession('text')
},
methods: {
handleCopy (text, index) {
this.copyIndex = index
copy(text)
},
},
}
</script>
<style lang="scss" scoped>
.font-div {
padding: $space-8;
background-color: $color-page-back;
height: 100vh;
box-sizing: border-box;
overflow-y: auto;
.input-box {
background-color: $box-color;
border-radius: $radius-4;
overflow: hidden;
.title {
padding: $space-8 $space-16;
border-bottom: $border-width-1px solid $color-page-back;
}
}
.rule {
background-color: $box-color;
padding: $space-8 $space-16;
border-radius: $radius-4;
margin-bottom: $space-8;
.line {
padding-bottom: 2.5px;
}
}
.van-field {
border-radius: $radius-4;
}
.text {
background-color: $box-color;
padding: $space-8 $space-16;
border-radius: $radius-4;
margin-top: $space-8;
font-size: $font-size-16;
text-align: center;
word-break: break-all;
word-wrap: break-word;
box-sizing: border-box;
}
.active {
border: $border-width-1px solid $color-pink;
}
}
</style>
/* eslint-disable */
export default [
[120309, 120315], // 𝙖 𝘼
[119737, 119743], // 𝐚 𝐀
[7396, 7428, { 'a': 7491, 'h': 688, 'q': 7601, 'w': 7514, 'r': 691, 't': 7511, 'y': 696, 'u': 7512, 'i': 7590, 'l': 737, 'o': 7506, 'p': 7510, 's': 738, 'f': 7584, 'g': 7501, 'j': 690, 'z': 7611, 'x': 739, 'c': 7580, 'v': 7515, 'b': 7495, 'n': 8319, 'm': 7504 }, true], // ᵅ ᵅ
[119789, 119795, { 'h': 8462 }], // 𝑎 𝐴
[119945, 119951], // 𝓪 𝓐
[120257, 120263], // 𝘢 𝘈
[119893, 119899, { 'e': 120046, 'o': 120056, 'g': 120048, 'E': 120020, 'R': 120033, 'I': 120024, 'F': 120021, 'H': 120023, 'B': 120017, 'O': 119978, 'L': 120027, 'M': 120028 }], // 𝒶 𝒜
[119841, 119847], // 𝒂 𝑨
[119997, 120029], // 𝔞 𝔞
[120205, 120211], // 𝗮 𝗔
[120049, 120055, { 'Q': 8474, 'R': 8477, 'P': 8473, 'H': 8461, 'Z': 8484, 'C': 8450, 'N': 8469 }], // 𝕒 𝔸
[120361, 120367], // 𝚊 𝙰
[9327, 9333], // ⓐ Ⓐ
[127215, 127247], // 🅐 🅐
[127183, 127215], // 🄰 🄰
[127247, 127279], // 🅰 🅰
[65248, 65248], // a A
// [9275, 9307], // ⒜ ⒜
// [0, 8355], // a⃤ ⃤A⃤
[-32, 0], // A A
// [975, 979], // а Д
[4524, 4556], // ል ል
[3491, 3523], // ค ค
]
const path = require('path')
const CompressionWebpackPlugin = require('compression-webpack-plugin')
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
const StylelintWebpackPlugin = require('stylelint-webpack-plugin')
// 环境变量获取
const { NODE_ENV, ENV_PX_TO_REM } = process.env
// 是否是生产环境
const isProduction = NODE_ENV === 'production'
// 访问绝对路径
const pathJoin = dir => path.join(__dirname, dir)
module.exports = {
lintOnSave: 'warning',
publicPath: '/',
outputDir: 'dist',
productionSourceMap: false,
configureWebpack (config) {
config.resolve = {
extensions: ['.vue', '.js', '.json'],
alias: {
'@': pathJoin('src'),
'@utils': pathJoin('src/utils'),
},
}
// 从外部引入的库,比如在 index.html 中引入 cdn 地址
config.externals = {
// key 表示 import x from 'key'
// value 表示外部引入的库暴露的全局变量名
// 'vue': 'Vue',
// 'vue-router': 'VueRouter',
// 'vuex': 'Vuex',
// 'axios': 'axios',
// 'element-ui': 'ELEMENT',
// 'echarts': 'echarts',
// 'BMap': 'BMap',
// 'lodash': '_',
// 'xlsx': 'XLSX',
// 'tinymce': 'tinymce',
// 'nprogress': 'NProgress',
}
// 生产环境配置
if (isProduction) {
// 打包分析
config.plugins.push(new BundleAnalyzerPlugin({
analyzerMode: 'disabled', // static | disabled
openAnalyzer: false,
}))
// terser debugger
config.optimization.minimizer[0].options.terserOptions.compress.drop_debugger = true
}
},
chainWebpack (config) {
const svgRule = config.module.rule('svg')
// 清空默认svg规则
svgRule.uses.clear()
// 针对svg文件添加svg-sprite-loader规则
svgRule
.test(/\.svg$/)
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]',
})
config
.plugin('stylelint-webpack-plugin')
.use(StylelintWebpackPlugin, [{
files: ['**/*.{vue,html,css,scss,sass,less,style}'],
failOnError: false,
failOnWarning: false,
emitWarning: true,
emitError: false,
cache: false,
}])
// 生产环境的配置
config.when(isProduction, config => {
// 启用 gzip 压缩插件
config
.plugin('compression-webpack-plugin')
.use(CompressionWebpackPlugin, [{
test: /\.js$|\.html$|\.css$/u,
threshold: 4096, // 超过 4kb 压缩
}])
})
},
css: {
loaderOptions: {
postcss: {
plugins: ENV_PX_TO_REM === 'open'
? [
require('postcss-pxtorem')({
rootValue: 100, // rem 大小
propList: ['*'],
}),
]
: [],
},
scss: {
prependData: '@use "~@/styles/variables.scss" as *;@use "~@/styles/mixins.scss" as *;',
},
sass: {
sassOptions: {
outputStyle: 'expanded'
}
}
},
},
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册