Vue3 Family Bucket + TS+ Vite2 + element-plus для создания простого и стильного блог-сайта.

Vue.js Vite
Vue3 Family Bucket + TS+ Vite2 + element-plus для создания простого и стильного блог-сайта.

В течение Первомая я потратил 3 дня на изучение Vue3 и Vite2 и рефакторинг собственных проектов, наконец, я закончил рефакторинг с Vue3 + TypeScript + Vite2 + Vuex4 + Vue-Router4 + element-plus!

Наконец-то достиг годовой цели на 2021 год, о которой я думал ✌️

адрес проекта:

GitHub.com/Tablesink нужно…

Эффект

Изображение эффекта:

  • ПК сторона

  • мобильный

Для полного эффекта, пожалуйста, смотрите:

biaochenxuying.cn

Функция

функция завершена

  • Авторизоваться
  • регистр
  • Список статей
  • Архив статей
  • Этикетка
  • о
  • Нравится и комментарий
  • сообщение
  • курс
  • Детали статьи (подсветка синтаксиса кода поддержки)
  • Каталог сведений о статье
  • Адаптация мобильного терминала
  • Авторизованный вход на 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. награда.

См. исходный код конкретного проекта:

GitHub.com/Tablesink нужно…

На данный момент создана среда разработки на основе Vue3 Family Bucket + Vite2 + TypeScript + Element Plus, и теперь вы можете писать код.Пожалуйста, обратитесь к их соответствующей документации для использования каждого компонента.

Я должен сказать, что Vue3 + Element Plus + Vite + TypeScript действительно ароматны!

Рекомендуется краткое изложение материалов, связанных с Vue3:Резюме учебного пособия по Vue3, проект объяснения исходного кода, поддерживаемая библиотека компонентов пользовательского интерфейса, высококачественные практические проекты, Я верю, вы будете копать мины!

Справочная статья:vue3 + vite + typescript + eslint + практика настройки проекта jest

Рекомендуемое чтение

Добро пожаловать в публичный аккаунт: "Полная практика стека",Отвечать "электронная книга" чтобы получить300Эта книга по технической сущности, о кот, брат wx: CB834301747