推荐一个 Vue3 全家桶 + TS+ Vite2 + element-plus 的网站实战项目

news/2024/5/18 20:43:21/文章来源:https://blog.csdn.net/m0_49394096/article/details/116506849

五一期间,花了 3 天时间,边学 Vue3 和 Vite2,边重构自己的项目,终于都用 Vue3 + TypeScript + Vite2 + Vuex4 + Vue-Router4 + element-plus 重构完啦!

终于完成一项心心念念的 2021 年度目标了 ✌️

项目地址:

https://github.com/biaochenxuying/blog-vue-typescript

效果

效果图:

  • pc 端

  • 移动端

完整效果请看:

https://biaochenxuying.cn

功能

已经完成功能

  • [x] 登录

  • [x] 注册

  • [x] 文章列表

  • [x] 文章归档

  • [x] 标签

  • [x] 关于

  • [x] 点赞与评论

  • [x] 留言

  • [x] 历程

  • [x] 文章详情(支持代码语法高亮)

  • [x] 文章详情目录

  • [x] 移动端适配

  • [x] github 授权登录

前端主要技术

所有技术都是当前最新的。

  • vue:^3.0.5

  • typescript : ^4.1.3

  • element-plus: ^1.0.2-beta.41

  • vue-router : ^4.0.6

  • vite: ^2.2.3

  • vuex: ^4.0.0

  • axios: ^0.21.1

  • highlight.js: ^10.7.2

  • marked:^2.0.3

1. 初化化项目

用 vite-app 创建项目

yarn create vite-app <project-name># 或者
npm init vite-app <project-name>

然后按照提示操作即可!

进入项目,安装依赖

cd <project-name>yarn # 或 npm i

运行项目

yarn dev 

打开浏览器 http://localhost:3000 查看

2. 引入 TypeScript

在创建项目的时候可以 TypeScript 的,如果你选择了 TypeScript ,可以忽略第 2 个步骤。

加入 ts 依赖

yarn add --dev typescript

在 项目根目录下创建 TypeScript 的配置文件 tsconfig.json

{"compilerOptions": {// 允许从没有设置默认导出的模块中默认导入。这并不影响代码的输出,仅为了类型检查。"allowSyntheticDefaultImports": true,// 解析非相对模块名的基准目录"baseUrl": ".","esModuleInterop": true,// 从 tslib 导入辅助工具函数(比如 __extends, __rest等)"importHelpers": true,// 指定生成哪个模块系统代码"module": "esnext",// 决定如何处理模块。"moduleResolution": "node",// 启用所有严格类型检查选项。// 启用 --strict相当于启用 --noImplicitAny, --noImplicitThis, --alwaysStrict, // --strictNullChecks和 --strictFunctionTypes和--strictPropertyInitialization。"strict": true,// 生成相应的 .map文件。"sourceMap": true,// 忽略所有的声明文件( *.d.ts)的类型检查。"skipLibCheck": true,// 指定ECMAScript目标版本 "target": "esnext",// 要包含的类型声明文件名列表"types": [],"isolatedModules": true,// 模块名到基于 baseUrl的路径映射的列表。"paths": {"@/*": ["src/*"]},// 编译过程中需要引入的库文件的列表。"lib": ["ESNext","DOM","DOM.Iterable","ScriptHost"]},"include": ["src/**/*.ts","src/**/*.tsx","src/**/*.vue","tests/**/*.ts","tests/**/*.tsx"],"exclude": ["node_modules"]
}

在 src 目录下新加 shim.d.ts 文件

/* eslint-disable */
import type { DefineComponent } from 'vue'declare module '*.vue' {const component: DefineComponent<{}, {}, any>export default component
}

把 main.js 修改成 main.ts

在根目录,打开 Index.html

<script type="module" src="/src/main.js"></script>
修改为:
<script type="module" src="/src/main.ts"></script>

3. 引入 eslint

安装 eslint prettier 依赖

@typescript-eslint/parser @typescr ipt-eslint/eslint-plugin 为 eslint 对 typescript 支持。

yarn add --dev eslint prettier eslint-config-prettier eslint-plugin-prettier eslint-plugin-vue @typescript-eslint/parser @typescr ipt-eslint/eslint-plugin

在根目录下建立 eslint 配置文件:.eslintrc.js

module.exports = {parser: 'vue-eslint-parser',parserOptions: {parser: '@typescript-eslint/parser',ecmaVersion: 2020,sourceType: 'module',ecmaFeatures: {jsx: true}},extends: ['plugin:vue/vue3-recommended','plugin:@typescript-eslint/recommended','prettier/@typescript-eslint','plugin:prettier/recommended'],rules: {'@typescript-eslint/ban-ts-ignore': 'off','@typescript-eslint/explicit-function-return-type': 'off','@typescript-eslint/no-explicit-any': 'off','@typescript-eslint/no-var-requires': 'off','@typescript-eslint/no-empty-function': 'off','vue/custom-event-name-casing': 'off','no-use-before-define': 'off',// 'no-use-before-define': [//   'error',//   {//     functions: false,//     classes: true,//   },// ],'@typescript-eslint/no-use-before-define': 'off',// '@typescript-eslint/no-use-before-define': [//   'error',//   {//     functions: false,//     classes: true,//   },// ],'@typescript-eslint/ban-ts-comment': 'off','@typescript-eslint/ban-types': 'off','@typescript-eslint/no-non-null-assertion': 'off','@typescript-eslint/explicit-module-boundary-types': 'off','@typescript-eslint/no-unused-vars': ['error',{argsIgnorePattern: '^h$',varsIgnorePattern: '^h$'}],'no-unused-vars': ['error',{argsIgnorePattern: '^h$',varsIgnorePattern: '^h$'}],'space-before-function-paren': 'off',quotes: ['error', 'single'],'comma-dangle': ['error', 'never']}
};

建立 prettier.config.js

module.exports = {printWidth: 100,tabWidth: 2,useTabs: false,semi: false, // 未尾逗号vueIndentScriptAndStyle: true,singleQuote: true, // 单引号quoteProps: 'as-needed',bracketSpacing: true,trailingComma: 'none', // 未尾分号jsxBracketSameLine: false,jsxSingleQuote: false,arrowParens: 'always',insertPragma: false,requirePragma: false,proseWrap: 'never',htmlWhitespaceSensitivity: 'strict',endOfLine: 'lf'
}

4. vue-router、vuex

npm install vue-router@4 vuex

4.1 vuex

在根目录下创建 store/index.ts

import { InjectionKey } from 'vue'
import { createStore, Store } from 'vuex'export interface State {count: number
}export const key: InjectionKey<Store<State>> = Symbol()export const store = createStore<State>({state() {return {count: 0}},mutations: {increment(state) {state.count++}}
})

main.ts 修改

import { createApp } from 'vue'
import { store, key } from './store'
import App from './App'
import './index.css'const app = createApp(App)app.use(store, key)app.mount('#app')

components/HelloWord.vue 修改

<template><h1>{{ msg }}</h1><button @click="inCrement"> count is: </button><p>{{ count }}</p>
</template><script>import { defineComponent, computed } from 'vue'import { useStore } from 'vuex'import { key } from '../store'export default defineComponent({name: 'HelloWorld',props: {msg: {type: String,default: ''}},setup() {const store = useStore(key)const count = computed(() => store.state.count)return {count,inCrement: () => store.commit('increment')}}})
</script>

4.2 vue-router

在 src 目录下建立 router/index.ts,内容如下:

import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";
import HelloWorld from "../components/HelloWorld.vue";const routes: Array<RouteRecordRaw> = [{path: "/",name: "HelloWorld",component: HelloWorld,},{path: "/about",name: "About",// route level code-splitting// this generates a separate chunk (about.[hash].js) for this route// which is lazy-loaded when the route is visited.component: () =>import(/* webpackChunkName: "About" */ "../components/About.vue")}
];const router = createRouter({history: createWebHistory(process.env.BASE_URL),routes,
});export default router;

再新建一个 components/About.vue 文件,内容如下:

<template><imgalt="Vue logo"src="../assets/logo.png"/><h1>{{ msg }}</h1>
</template><script lang="ts">
import { defineComponent } from 'vue'export default defineComponent({name: 'About',data() {return {msg: 'Hello Vue 3.0 + Vite!'}},setup() {}
})
</script>

再修改 main.ts

import { createApp } from 'vue'
import { store, key } from './store'
import router from "./router";
import App from './App'
import './index.css'const app = createApp(App)app.use(store, key)
app.use(router)
app.mount('#app')

再访问 http://localhost:3000/

和 http://localhost:3000/about 即可

5. 加入 Element Plus

5.1 安装 element-plus

全局安装

npm install element-plus --save

5.2 引入 Element Plus

你可以引入整个 Element Plus,或是根据需要仅引入部分组件。我们先介绍如何引入完整的 Element。

完整引入

在 main.js 中写入以下内容:

import { createApp } from 'vue'
import ElementPlus from 'element-plus';
import router from "./router";
import 'element-plus/lib/theme-chalk/index.css';
import App from './App.vue';
import './index.css'const app = createApp(App)
app.use(ElementPlus)
app.use(router)
app.mount('#app')

以上代码便完成了 Element Plus 的引入。需要注意的是,样式文件需要单独引入。


按需引入

借助 babel-plugin-component,我们可以只引入需要的组件,以达到减小项目体积的目的。

首先,安装 babel-plugin-component:

npm install babel-plugin-component -D

然后,将 .babelrc 修改为:

{"plugins": [["component",{"libraryName": "element-plus","styleLibraryName": "theme-chalk"}]]
}

接下来,如果你只希望引入部分组件,比如 Button 和 Select,那么需要在 main.js 中写入以下内容:

import { createApp } from 'vue'
import { store, key } from './store';
import router from "./router";
import { ElButton, ElSelect } from 'element-plus';
import App from './App.vue';
import './index.css'const app = createApp(App)
app.component(ElButton.name, ElButton);
app.component(ElSelect.name, ElSelect);/* or* app.use(ElButton)* app.use(ElSelect)*/app.use(store, key)
app.use(router)
app.mount('#app')
app.mount('#app')

更详细的安装方法请看 快速上手。

5.3 全局配置

在引入 Element Plus 时,可以传入一个全局配置对象。

该对象目前支持 size 与 zIndex 字段。size 用于改变组件的默认尺寸,zIndex 设置弹框的初始 z-index(默认值:2000)。按照引入 Element Plus 的方式,具体操作如下:

完整引入 Element:

import { createApp } from 'vue'
import ElementPlus from 'element-plus';
import App from './App.vue';const app = createApp(App)
app.use(ElementPlus, { size: 'small', zIndex: 3000 });

按需引入 Element:

import { createApp } from 'vue'
import { ElButton } from 'element-plus';
import App from './App.vue';const app = createApp(App)
app.config.globalProperties.$ELEMENT = option
app.use(ElButton);

按照以上设置,项目中所有拥有 size 属性的组件的默认尺寸均为 'small',弹框的初始 z-index 为 3000。

5.4 配置 vite.config.ts

其中 proxy 和 alias 是和 vue-cli 区别比较大的地方。

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import styleImport from 'vite-plugin-style-import'
import path from 'path'// https://vitejs.dev/config/
export default defineConfig({plugins: [vue(),styleImport({libs: [{libraryName: 'element-plus',esModule: true,ensureStyleFile: true,resolveStyle: (name) => {return `element-plus/lib/theme-chalk/${name}.css`;},resolveComponent: (name) => {return `element-plus/lib/${name}`;},}]})],/*** 在生产中服务时的基本公共路径。* @default '/'*/base: './',/*** 与“根”相关的目录,构建输出将放在其中。如果目录存在,它将在构建之前被删除。* @default 'dist'*/// outDir: 'dist',server: {// hostname: '0.0.0.0',host: "localhost",port: 3001,// // 是否自动在浏览器打开// open: true,// // 是否开启 https// https: false,// // 服务端渲染// ssr: false,proxy: {'/api': {target: 'http://localhost:3333/',changeOrigin: true,ws: true,rewrite: (pathStr) => pathStr.replace('/api', '')},},},resolve: {// 导入文件夹别名alias: {'@': path.resolve(__dirname, './src'),views: path.resolve(__dirname, './src/views'),components: path.resolve(__dirname, './src/components'),utils: path.resolve(__dirname, './src/utils'),less: path.resolve(__dirname, "./src/less"),assets: path.resolve(__dirname, "./src/assets"),com: path.resolve(__dirname, "./src/components"),store: path.resolve(__dirname, "./src/store"),mixins: path.resolve(__dirname, "./src/mixins")},}
})

踩到坑

npm run dev 打包时不报错,但是在 npm run build 时却报错了,build 的时候会把 node_modules 里面的文件也编译,所以挺多 element-plus 的类型文件报错了。

tsconfig.json 里面的 includeexclude 修改一下就不会了,配置如下

{"compilerOptions": {"target": "esnext","module": "esnext","moduleResolution": "node","strict": true,"jsx": "preserve","sourceMap": true,// 忽略 this 的类型检查, Raise error on this expressions with an implied any type."noImplicitThis": false,"resolveJsonModule": true,"esModuleInterop": true,"lib": ["esnext", "dom"],"types": ["vite/client"]},"include": ["/src/**/*.ts", "/src/**/*.d.ts", "/src/**/*.tsx", "/src/**/*.vue"],// ts 排除的文件"exclude": ["node_modules"]
}

Vue3 + vite2 打包出来的文件和原来 vue2 版的差别也挺大的,由原来 2.5M 直接变成了 1.8M ,amazing!

最后

项目代码大多都是 2 年前的,还有很多可以优化的地方,这次重构的过程没对原来的样式和代码做什么改动,没那么多时间,加上我懒 ????

这次就升级了主要框架与相应的 ui 库,过了一遍 Vue3 中的 API,发现很多 Vue3 中新的 API 都用不上,主要是要熟练一下 Vue3 和 Vite2 项目搭建,这假期也算有所收获。

具体项目源码请看:

https://github.com/biaochenxuying/blog-vue-typescript

至此,一个基于 Vue3 全家桶 + Vite2 + TypeScript + Element Plus 的开发环境已经搭建完毕,现在就可以编写代码了,各个组件的使用方法请参阅它们各自的文档。

不得不说 Vue3 + Element Plus + Vite + TypeScript 是真的香!

推荐一个 Vue3 相关的资料汇总:Vue3 的学习教程汇总、源码解释项目、支持的 UI 组件库、优质实战项目,相信你会挖到矿哦!

推荐阅读

  • TypeScript 中提升幸福感的 10 个高级技巧

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_705337.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【效率】推荐10个堪称神器的网站!

1、MSDN我告诉你&#xff08;https://msdn.itellyou.cn/&#xff09;想重装系统&#xff0c;但是不知道在哪下载系统镜像&#xff1f;这个网站不仅可以免费下载系统镜像&#xff0c;而且版本特别全&#xff0c;最重要的是没有广告&#xff0c;现在很多网上的电脑系统安装完成后…

【推荐】一下令人惊艳的的网站,绝对会让你爱上历史

点击上方“AI搞事情”关注我们今天向大家推荐一个之前看到的神奇网站&#xff0c;绝对算得上是精心制作、业界良心。这个网站叫&#xff1a;「全历史」https://www.allhistory.com/还有对应的手机版app&#xff1a;全历史官网介绍其是以「AI知识图谱」为核心引擎&#xff0c;通…

PHP开发电脑网站支付宝支付详细流程(沙箱测试篇)

为什么80%的码农都做不了架构师&#xff1f;>>> 1&#xff09;准备工作 1、蚂蚁金服开放平台的商户账号&#xff08;个人账号不行&#xff09; 2、php5.5以上的开发环境 &#xff08;2&#xff09;具体流程 1、demo下载 进入蚂蚁金服开放平台的首页&#xff0c;选择…

【效率】7个免费的PDF文献资源网站,再也不用为搜索文献发愁了!

写论文搜索文献最耗时间了&#xff0c;也常常因为找不到好的文献而发愁。本篇给大家推荐的7个学术资源搜索引擎&#xff0c;经测试均可以正常访问并下载&#xff0c;而且绝大部分网站的文献资源都是免费的。 01SooPat专利搜索引擎介绍&#xff1a;Soopat中的Soo为“搜索”&…

【Python】学习Python的三个神级网站

今天来给大家介绍三个我在学习 Python 路上帮助比较大的堪称神级的网站&#xff0c;尤其是对于刚刚入门的同学来说&#xff0c;绝对不容错过~pythontutor 这个网站对于新手同学理解代码的运行逻辑简直是太好用了首先进入网站我们看到的就是如下这个页面左边是一段 Python 代码&…

【建议收藏】数学建模竞赛网站汇总

前言在数学建模备战学习期间&#xff0c;需要寻找学习资料&#xff0c;查找历年真题&#xff0c;阅读优秀论文等&#xff1b;比赛过程中我们需要去查找有关数据&#xff0c;搜索相关文献等。当不知道如何去搜索时&#xff0c;就会很迷茫。我了解这种心情和紧迫的心理&#xff0…

某数字资源网站哭穷赔不起1200亿,网友:收钱时咋不嫌多

萧箫 发自 凹非寺量子位 | 公众号 QbitAI知网开始哭穷了。就在最近&#xff0c;又一位作家起诉知网侵权时&#xff0c;知网运营方表示&#xff0c;再这样下去真的要“赔不起了”&#xff1a;即使只按200元/千字来算&#xff0c;知网全部在库作品也要赔1200亿元。知网根本不可能…

【学术相关】最新整理!绝对不能错过的130个学术网站和26个科研工具

来源&#xff1a;学术志&#xff08;ID&#xff1a;xueshuzhi001&#xff09;整理&#xff1a;学术志编辑部 编辑&#xff1a;学妹我们平时可以见到不少学术资源&#xff0c;但是很多信息里会有一些重叠网站、无效网站&#xff0c;导致我们虽然收藏了很多网址&#xff0c;但是…

SQL注入攻击再度肆虐殃及大量网站

据研究人员称,上周一个自动SQL注入攻击劫掠了超过70,000个美国网站,并顺带攻击了访问这些网站的大量PC机用户.通过Google可以很容易搜索到受攻击的网站,网页内容千差万别,包括教育网和政府网域,而且几乎全部都是受信任站点.这是一次规模非常大的攻击行为,由于涉及的网站相当多样…

QuickWAP 2005企业WAP网站系统简介

QuickWAP 2005企业WAP网站系统简介 中国被爱可以在线于2006年4月1日发布了QuickWAP 2005&#xff0c;软件中包含了一套“企业WAP网站系统”&#xff0c;该系统完全基于QuickWAP 2005平台。它不仅可以支持手机访问&#xff0c;而且同时支持WEB浏览器访问。 当利用IE浏览器浏览…

【深度学习】搭建人工智能服务网站(安全帽检测)

电力图像分类最典型的场景就是安全帽佩戴识别。针对电网作业现场人员行为的图像数据&#xff0c;采用目标检测、图像识别等人工智能技术&#xff0c;对电网作业现场人员是否规范佩戴安全帽进行检测识别。通过计算平均精确率、漏检率、误检率、平均计算时间等指标进行评测。任务…

[请教]关于超大数据量网站的数据搜索和分页的实现方法

请教像阿里巴巴这样的数据量过百万的网站&#xff0c;其数据搜索和分页是如何实现的&#xff1f;我个人是用全文索引做的&#xff0c;把物品名和物品简介放在一起&#xff0c;检索这个字段。分页是用存储过程做的&#xff0c;CREATEPROCEDUREGetSearchEnterprise(strWherevarch…

如何消除网站安全的七大风险

以工作中某项目的安全改善过程为例&#xff0c;分享了常用网站安全性的典型问题和解决对策&#xff0c;希望对网站开发者有借鉴意义。 有过网站开发经验的朋友都知道网站安全是构建网站时必须要考虑的一个因素&#xff0c;网站安全的重点在于服务器的安全配置管理以及程序脚…

浙江巨丰管业有限公司网站

祝贺浙江巨丰管业网站正式运行2周年&#xff0c; 浙江巨丰管业有限公司&#xff08;以下简称公司&#xff09;成立于2001年&#xff0c;坐落于美丽的西施故里-浙江诸暨-店口工业区&#xff0c;公司距离杭州机场20公里&#xff0c;杭金衢高速公路20公里&#xff0c;沪杭甬高速公…

分享9个最棒的代码片段资源网站

作为一个奋斗在第一线的码农来说&#xff0c;能找到自己能在项目中直接使用的代码无疑是一件天大的喜事。代码片段和代码库到处都有&#xff0c;如何找到自己需要的东西绝对是一个大问题&#xff0c;为了帮助大家更好的找到自己需要的代码&#xff0c;今天我们介绍9个非常不错的…

IIS网站服务器性能优化指南

Windows Server自带的互联网信息服务器&#xff08;Internet Information Server&#xff0c;IIS&#xff09;是架设网站服务器的常用工具&#xff0c;它是一个既简单而又麻烦的东西&#xff0c;新手都可以使用IIS架设一个像模像样的Web站点来&#xff0c;但配置、优化IIS的性能…

Android利用Jsoup解析html 开发网站客户端小记。

这些天业余时间比较多&#xff0c;闲来无事&#xff0c;想起了以前看过开发任意网站客户端的一篇文章&#xff0c;就是利用jsoup解析网站网页&#xff0c;通过标签获取想要的内容。好了废话不多说&#xff0c;用到的工具为 jsoup-1.7.2.jar包&#xff0c;具体jsoup的相关文档&a…

网站架构之架构演化

网站从构建之初的很少有人问津&#xff0c;用户数量较少&#xff0c;并发量较低&#xff0c;到之后的拥有千万上亿用户&#xff0c;数万量级的高并发&#xff0c;之间经历了怎样的过程&#xff0c;小型网站架构是怎样逐步演化的&#xff0c;本文简单探讨下这方面的内容&#xf…

产品推广系统推荐乐云seo_优化推广公司红利产品推荐“爱采购cpc竞价版”

很多优化推广公司都在寻找更好的产品&#xff0c;服务&#xff0c;项目来满足更多客户的需求以及市场认可度&#xff0c;竞争力。有人可能代理过整站优化的产品&#xff0c;有人可能代理过快速排名的产品&#xff0c;有人可能代理过万词霸屏类产品&#xff0c;等等。这些产品都…

网站框构分析 一

Facebook用户量大的问题由它的分布式缓存系统主要解决&#xff0c;剩下的自然是开源的mysql更合适了 &amp;lt;img src"https://pic2.zhimg.com/c6d403f1e89fa46c5567e0cbcbb024ad_b.jpg" data-rawwidth"1310" data-rawheight"333" class&quo…