В течение Первомая я потратил 3 дня на изучение Vue3 и Vite2 и рефакторинг собственных проектов, наконец, я закончил рефакторинг с Vue3 + TypeScript + Vite2 + Vuex4 + Vue-Router4 + element-plus!
Наконец-то достиг годовой цели на 2021 год, о которой я думал ✌️
адрес проекта:
Эффект
Изображение эффекта:
- ПК сторона
- мобильный
Для полного эффекта, пожалуйста, смотрите:
Функция
функция завершена
- Авторизоваться
- регистр
- Список статей
- Архив статей
- Этикетка
- о
- Нравится и комментарий
- сообщение
- курс
- Детали статьи (подсветка синтаксиса кода поддержки)
- Каталог сведений о статье
- Адаптация мобильного терминала
- Авторизованный вход на github
Передняя основная технология
Все технологии актуальны и актуальны.
- Вью: ^ 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
- отмечено: ^ 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, вы можете пропустить второй шаг.
Присоединиться к зависимости
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"
]
}
Добавьте новый файл shim.d.ts в каталог src.
/* 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
@typescript-eslint/parser @typescript-eslint/eslint-plugin
Поддержка машинописного текста для eslint.
yarn add --dev eslint prettier eslint-config-prettier eslint-plugin-prettier eslint-plugin-vue @typescript-eslint/parser @typescript-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-маршрутизатор, 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')
компоненты/модификация 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
Создайте router/index.ts в каталоге src со следующим содержимым:
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;
Создайте новый файл component/About.vue со следующим содержимым:
<template>
<img
alt="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. Присоединяйтесь к Элемент Плюс
5.1 Установка element-plus
Установить глобально
npm install element-plus --save
5.2 Знакомство с Element Plus
Вы можете импортировать весь Element Plus или только некоторые компоненты по мере необходимости. Давайте сначала представим, как ввести полный элемент.
полный импорт
Напишите в 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:
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-индекс поля (по умолчанию: 2000). Конкретная операция заключается в следующем:
Импортируйте элемент целиком:
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 });
Импортируйте элементы по мере необходимости:
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
Размер компонентов свойства по умолчанию — «маленький», а начальный z-индекс всплывающего окна — 3000.
5.4 Настройка vite.config.ts
Среди них прокси и псевдоним сильно отличаются от 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
Когда сообщается об ошибке, сборка будетnode_modules
Файлы внутри также скомпилированы, поэтому многие файлы типа element-plus сообщают об ошибках.
Пучокtsconfig.json
внутриinclude
а такжеexclude
Измените его и он не будет работать, конфигурация следующая
{
"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,5 МБ был напрямую изменен на 1,8 МБ, удивительно!
наконец
Большая часть кода проекта написана 2 года назад, и есть еще много областей, которые можно оптимизировать.Этот процесс рефакторинга не внес никаких изменений в исходный стиль и код, поэтому у меня не было столько времени, плюс я я ленивая 😂
На этот раз я обновил основной фреймворк и соответствующую библиотеку пользовательского интерфейса.Посмотрев API в Vue3, я обнаружил, что многие новые API в Vue3 недоступны.Главное - уметь строить проекты Vue3 и Vite2. награда.
См. исходный код конкретного проекта:
На данный момент создана среда разработки на основе Vue3 Family Bucket + Vite2 + TypeScript + Element Plus, и теперь вы можете писать код.Пожалуйста, обратитесь к их соответствующей документации для использования каждого компонента.
Я должен сказать, что Vue3 + Element Plus + Vite + TypeScript действительно ароматны!
Рекомендуется краткое изложение материалов, связанных с Vue3:Резюме учебного пособия по Vue3, проект объяснения исходного кода, поддерживаемая библиотека компонентов пользовательского интерфейса, высококачественные практические проекты, Я верю, вы будете копать мины!
Справочная статья:vue3 + vite + typescript + eslint + практика настройки проекта jest
Рекомендуемое чтение
Добро пожаловать в публичный аккаунт: "Полная практика стека",Отвечать "электронная книга" чтобы получить300Эта книга по технической сущности, о кот, брат wx: CB834301747