设计初衷
我现在也是个非计算机专业的大四在校生,平时前端都是自学的,所以从初学到现在基本上都是通过白嫖网上的视频、买书或从图书馆借书看、逛技术博客长长见识等等。这期间我会看到很多实用的工具网站或一些有趣的网站,我都会把他们收藏下来,生怕之后找不到了,但是随着时间的推移,收藏的网站越来越多,我的浏览器收藏夹可能变成了这样
这些都是我很久之前收藏夹收藏的,要是按照这个势头,我的收藏夹不出半年就爆满了,到时候找网站都不方便,所以我就想做一个我自己的网站导航栏,要求不高 : 简单大方、方便快捷
于是就有了现在这个项目,如下图所示:
项目功能 && 特色
毕竟是个网址导航栏,所以功能非常的简单,但之后我会尽可能地去完善该项目的一些额外的功能
项目的功能:
✅ 标签的添加、修改、删除
✅ 网址的添加、修改、删除
✅ 搜索功能
✅ 配置的导入、导出
项目的特色:
⭐ 基于 Vue3
开发
⭐ 页面简单大方
⭐ 提供网站图标、名称的获取接口
⭐ 标签栏支持多种 icon
选择
⭐ 通过 localStorage
存储,无需配置数据库
⭐ 用 Vue3
封装了 Element UI
的 message
、dialog
、button
、input
、popover
组件
⭐ 通过 Vuex 4
进行状态管理
⭐ 页面的滚动动画
⭐ 支持一键保存导出数据、一键导入数据
项目文件结构
整个项目主要的文件都在 src
文件夹下,结构目录如下:
├── src ├── assets // 存放静态资源 ├── components // 各种组件 │ ├── main // 页面主要内容相关组件 │ ├── tabs // 标签栏相关组件 │ └── public // 全局公共组件 ├── network // 网络请求 ├── store // Vuex ├── utils // 存放自己封装的工具 ├── APP.vue └── main.jsss
重点介绍
对于项目的逻辑代码,你们可以直接查看我的源码,全部都是用的 Vue3
语法写的
在最初做这个项目时,还没找到合适的 Vue3
组件库,所以我就根据自己的需求,封装了 message
、dialog
、input
、button
、popover
这样五个组件,其中重点讲一下 message
和 dialog
吧,另外还有这个项目的亮点:配置导入与导出
Dilog组件
首先是组件内容:
// lp-dialog.vue <template> <div class="lp-confirm-container" ref="lpConfirmAlert"> <div class="lp-confirm-box"> <div class="lp-confirm-title"> <span class="lp-confirm-title-txt">{{ title }}</span> <span class="lp-confirm-title-close" @click="closeConfirm">✖</span> </div> <div class="lp-confirm-content"> <span class="lp-confirm-content-txt">{{ content }}</span> </div> <div class="lp-confirm-btn-groups"> <lp-button type="primary" class="lp-confirm-btn" @_click="sureConfirm">确定</lp-button> <lp-button type="default" class="lp-confirm-btn lp-confirm-btn-cancel" @_click="closeConfirm">取消</lp-button> </div> </div> </div> </template> <script> import lpButton from '../lp-button/lp-button' import {ref} from 'vue' export default { components: { lpButton }, props: { title: { type: String, default: '提示' }, content: { type: String, default: '确定关闭吗?' } }, setup() { const status = ref(-1) // 存储用户点的状态,-1:未点击;0:取消;1:确定 const lpConfirmAlert = ref(null) function removeElement() { lpConfirmAlert.value.parentNode.removeChild(lpConfirmAlert.value) } function closeConfirm() { status.value = 0 removeElement() } function sureConfirm() { status.value = 1 removeElement() } return {removeElement, closeConfirm, sureConfirm, status, lpConfirmAlert} } } </script> <style scoped> /* 样式见源码,此处省略 */ </style>
这里我在 dialog
组件内设定了一个组件的状态变量 status
,用于确认用户的点击情况
再来看看组件的处理代码:
// lp-dialog.js import lp_dialog from './lp-dialog.vue' import {defineComponent, createVNode, render, toRef, watch} from 'vue' const confirmConstructor = defineComponent(lp_dialog) export const createDialog = (options) => { if(!Object.prototype.toString.call(options) === '[Object Object]') { console.error('Please enter an object as a parameter'); } options = options ? options : {} // 生成组件实例 const instance = createVNode( confirmConstructor, options ) // 渲染挂载组件 const container = document.createElement('div') render(instance, container) document.querySelector('#app').appendChild(instance.el) // 初始化组件参数 const props = instance.component.props Object.keys(options).forEach(key => { props[key] = options[key] }) // 获取组件的 status 状态变量 const status = toRef(instance.component.setupState, 'status') // 返回 promise,方便外部调用 return new Promise((resolve, reject) => { // 监听组件的按钮点击情况 watch(status, (now) => { if(now == 0) reject(); else if(now == 1) resolve() }) }) }
接下来把 dialog
作为一个方法注册到全局中,这个我就把它放在了 App.vue
文件中,通过 Vue3
的 provide
方法暴露在全局
<template> <div id="app"></div> </template> <script> import { provide } from 'vue' import createDialog from './components/public/lp-dialog/lp-dialog.js' export default { setup() { // 全局暴露创建 dialog 组件的方法 provide('confirm', createDialog) } } </script>
然后在别的组件中使用 dialog
组件
<template> <div class="tabs" @click="btnConfirm"></div> </template> <script> import { inject } from 'vue' export default { setup() { // 接收创建 dialog 组件的方法 let $confirm = inject('confirm') btnConfirm() { // 调用方法 $confirm({ title: '提示', // 确认框的标题 content: '确认关闭吗?', // 消息内容 }) .then(() => { console.log('确认') }) .catch(() => { console.log('取消') }) } return { btnConfirm } } } </script>
这样就实现了一个基于 promise
的链式调用,可以设定用户点击了 确认 或 取消 之后的处理代码
还有下文~