2.0.0
我的项目阐明
该我的项目为web单页面利用,外围性能为显示工夫。
技术栈应用 pnpm、Vite、Vue3、typescript、tailwind、github/api
性能需要
- 显示工夫
- 显示随机壁纸
- 每日热词录入
非性能需要
- 挪动端自适应
- 查看日前工夫具体属性
页面比照
新我的项目预览
旧我的项目预览
旧页面
新页面
开发记录
Vscode Extension
- Vue 3 Pack
- Vue Extension Pack
- Tailwind CSS Extension Pack
alias设置
'@'默认失效、其余门路须要同时配置vite和typescript才失效,配置完最好重启ide
1.配置vite.config文件
{resolve: { alias: { '@': path.resolve(__dirname, './src'), '#': path.resolve(__dirname, './src/views'), '$': path.resolve(__dirname, './src/components'), }, }}
2.配置tsconfig.json文件
{ "compilerOptions": { "paths": { "/@/*": ["src/*"], "/#/*": ["src/views/*"], "/$/*": ["src/components/*"] } },}
script setup
<script setup lang="ts"> import { reactive, watchEffect, computed, ref } from 'vue'; import gitPut from '$/gitPut.vue'; // 组件引入即可间接应用,不须要componet注册 // 以下变量都能够在template中应用 const menu = [...routes]; //非动静绑定 const menuShow = ref(false); //动静绑定,set/get时须要应用menuShow.value const state = reactive({ //动静绑定。相似store/state,保护一组参数 imgUrl: '', now: Date.now(), twDate: computed(() => new TwDate(state.now)), /*应用computed代替filter*/ weekMix: computed(() => state.twDate.getWeekEn() + '|' + state.twDate.getWeekZh()), seasonMix: computed(() => state.twDate.getSeasonEn() + '|' + state.twDate.getSeasonZh()), }) // watchEffect, 区别于watch只监听一个变量 watchEffect(() => { // 能够定义所有变量监听,此处只监听了state.now state.localStr = new TwDate(state.now).toLocaleString(); });<script/>
Vue3 Hooks
最大区别就是勾销了destroyed 改为 unMounted
创立hook.ts
log工具
import { onBeforeMount, onMounted, // onBeforeUpdate, // onUpdated, onBeforeUnmount, onUnmounted, // onDeactivated, // onActivated, // onRenderTracked, // onRenderTriggered} from 'vue';const HOOK_LIST: Map<string, any> = new Map([ ['BeforeMount', onBeforeMount], ['Mounted', onMounted], // ['BeforeUpdate', onBeforeUpdate], // ['Updated', onUpdated], ['BeforeUnmount', onBeforeUnmount], ['Unmounted', onUnmounted], // ['Deactivated', onDeactivated], // ['Activated', onActivated] // ['RenderTracked', onRenderTracked], // ['RenderTriggered', onRenderTriggered]]);/** * @description Hook 日志与回调 * @param cb */export default ( cb: | { afterBeforeMount: () => void; afterMounted: () => void; afterUnmounted: () => void; afterBeforeUnmount: () => void; } | any) => { HOOK_LIST.forEach((hook, key) => { hook(() => { console.log(`#Hook////${key}`); let afterCb = cb?.[`after${key}`]; afterCb && afterCb(); }); });};
应用hook.ts
<script setup lang="ts"> import hook from '@/common/hook'; import { reactive } from 'vue'; const state = reactive({ now: Date.now() }) // timeInterval let timer = setInterval(() => { state.now = Date.now(); }, 800); // test hook hook({ afterUnmounted: () => { clearInterval(timer); timer = 0; }, });
Class Date Extend
import dateEnum from './../enums/dateEnum';export default class TwDate extends Date { // 返回当天是当年的第几天 getDayInYear = () => { return ( (Date.now() - new TwDate(new TwDate().getFullYear(), 0, 1, 0, 0, 0).getTime()) / (24 * 3600 * 1000) ); }; // 返回以后时刻是当天的第几毫秒 getMillSecInDay = () => { const y = new TwDate().getFullYear(); const m = new TwDate().getMonth(); const d = new TwDate().getDate(); return Date.now() - new TwDate(y, m, d, 0, 0, 0).getTime(); }; // 返回当天/当年占比 getRatioYear = () => { return this.getDayInYear() / 365; }; // 返回当天/当月占比 getRatioMonth = () => { const y = new TwDate().getFullYear(); const m = new TwDate().getMonth(); return new TwDate().getDate() / new TwDate(y, m + 1, 0).getDate(); }; // 返回当天/当周占比 getRatioWeek = () => { return (new TwDate().getDay() || 7) / 7; }; // 返回以后时刻/当天占比 getRatioDay = () => { return this.getMillSecInDay() / (24 * 3600 * 1000); }; // 返回文本:周-En getWeekEn = () => { return dateEnum.WEEK_EN[new TwDate().getDay()]; }; // 返回文本:周-Zh getWeekZh = () => { return dateEnum.WEEK_ZH[new TwDate().getDay()]; }; // 返回文本:节令-En getSeasonEn = () => { return dateEnum.SEASON_EN[Math.floor(new TwDate().getMonth() / 3)]; }; // 返回文本:节令-Zh getSeasonZh = () => { return dateEnum.SEASON_ZH[Math.floor(new TwDate().getMonth() / 3)]; };}
随机图片地址
reference
unsplash:收费的高清摄影素材网站
const api = 'https://unsplash.it'; const randomId = Math.random() * 10; const width = 1920; const height = 1080; let url = `${api}/${width}/${height}?random=${parseInt(randomId.toString(), 10)}`;
P.S.
也可用利用api获取Bing壁纸,但因为要解决跨域放弃了。如果是独立部署的话能够思考。
// const bingUrl = 'https://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=zh-CN';
tailwind应用
因为目前应用的是quasar框架,其中也有一些原子类的款式,所以思维上还是能了解。
但不习惯api的话起手比拟吃力,有肯定门槛,对与团队推广还是有肯定难度。
个人感觉作为我的项目落地的话将来可能会有应用上的瓶颈,作为集体开发的话我目前还是比拟中意的,有种中庸之美。
github/api
每日热词需要由 github/issue
实现,即输出热词回车后将参数由github/api
传递给github。
写入操作须要token验证,能够在github/开发者设置里创立。
因为token不可显性显示在代码中,所以对token采纳非对称加密,每次申请要输出密钥,解码后获取token。
P.S.如果token间接裸露在代码中,该token会主动删除。
1.创立token,输出note即可,checkbox勾选repo即可
2.在github/repo/issue里创立新label,次要用于辨别。
3.配置用户、我的项目 package.json
{ "config": { "owner": "Mulander-J", "repo": "timeWaster", "label": "heart" }}
4.应用api
import axios from 'axios';import pkg from './../../package.json';const { owner, repo, label } = pkg.config;const url = `https://api.github.com/repos/${owner}/${repo}`;export default class Api { static getIssueList = (since?: string): Promise<any> => { since = since ? '&since=' + since : ''; return axios.get(`${url}/issues?filter=created&labels=${label + since}`); }; static addIssue = (body: string, token: string): any => { return axios.post(`${url}/issues?access_token=${token}`, { labels: [label], title: 'TW/' + new Date().toLocaleDateString(), body, }); };}
打包及部署
打包前要依据仓库地址批改根目录属性
// [guide](https://vitejs.dev/config/)export default defineConfig({ base: '/timeWaster'});
应用github-page部署,这里用到了gh-pages
插件,两行命令间接部署。
{ "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "predeploy": "vite build", "deploy": "gh-pages -d dist" }, "devDependencies": { "gh-pages": "^3.1.0" },}
结语
本意是紧跟潮流学点新货色,利用空闲工夫查资料等了一周,理论开发用了两天左右。
对于vue3没波及具体业务还不分明,对于vite的速度真的很喜爱。