赞
踩
开启2021学习之旅,主要介绍学习vite2和vue3的实战过程。
本篇主要介绍从零开始搭建Vite2 + Vue3+Element-Plus + Vue-router4 + Vuex + Eslint。
Vite (法语意为 "快速的",发音 /vit/)是一种全新的前端构建工具。
由一个开箱即用的开发服务器 + 一套构建 指令组成。
Vite 利用浏览器原生的 ES 模块支持和基于 esbuild 的依赖预打包来显著提升前端开发体验。
# npm 6.x
npm init @vitejs/app my-vue-app --template vue
# npm 7+, 需要额外的双横线:
npm init @vitejs/app my-vue-app -- --template vue
# yarn
yarn create @vitejs/app my-vue-app --template vue
修改vite.config.js
import path from 'path'
export default defineConfig({
...,
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
components: path.resolve(__dirname, 'src/components'),
assets: path.resolve(__dirname, 'src/assets'),
views: path.resolve(__dirname, 'src/views'),
utils: path.resolve(__dirname, 'src/utils'),
apis: path.resolve(__dirname, 'src/apis'),
},
}
})
scss是一款css预处理语言,是sass的一个升级版本,SCSS 是 Sass 3 引入新的语法,其语法完全兼容 CSS3,并且继承了 Sass 的强大功能。
npm i -d sass node-sass sass-loader
# vite.config.js
export default defineConfig({
...,
css: {
preprocessorOptions: {
scss: {
// @/ 是 src/ 的别名
// 所以这里假设你有 `src/assets/scss/variables.scss` 这个文件
additionalData: `@import "@/assets/scss/variables.scss";`
},
},
}
})
开始引入UI框架,这里使用Element适配vue3版本的element-plus
npm i -s element-plus
借助 vite-plugin-style-import实现按需加载组件,以达到减小项目体积的目
npm install vite-plugin-style-import -D
import styleImport from 'vite-plugin-style-import' plugins: [ vue(), styleImport({ libs: [ { libraryName: 'element-plus', esModule: true, ensureStyleFile: true, resolveStyle: (name) => { name = name.slice(3); return `element-plus/packages/theme-chalk/src/${name}.scss`; }, resolveComponent: (name) => { return `element-plus/lib/${name}`; }, }, ], }) ]
// 如果要使用.scss样式文件,则需要引入base.scss文件 // import 'element-plus/packages/theme-chalk/src/base.scss' import 'element-plus/packages/theme-chalk/src/base.scss' import { ElAlert, ElAside, ElAutocomplete, ElAvatar, ElBacktop, ElBadge, ElBreadcrumb, ElBreadcrumbItem, ElButton, ElButtonGroup, ElCalendar, ElCard, ElCarousel, ElCarouselItem, ElCascader, ElCascaderPanel, ElCheckbox, ElCheckboxButton, ElCheckboxGroup, ElCol, ElCollapse, ElCollapseItem, ElCollapseTransition, ElColorPicker, ElContainer, ElDatePicker, ElDialog, ElDivider, ElDrawer, ElDropdown, ElDropdownItem, ElDropdownMenu, ElFooter, ElForm, ElFormItem, ElHeader, ElIcon, ElImage, ElInput, ElInputNumber, ElLink, ElMain, ElMenu, ElMenuItem, ElMenuItemGroup, ElOption, ElOptionGroup, ElPageHeader, ElPagination, ElPopconfirm, ElPopover, ElPopper, ElProgress, ElRadio, ElRadioButton, ElRadioGroup, ElRate, ElRow, ElScrollbar, ElSelect, ElSlider, ElStep, ElSteps, ElSubmenu, ElSwitch, ElTabPane, ElTable, ElTableColumn, ElTabs, ElTag, ElTimePicker, ElTimeSelect, ElTimeline, ElTimelineItem, ElTooltip, ElTransfer, ElTree, ElUpload, ElInfiniteScroll, ElLoading, ElMessage, ElMessageBox, ElNotification, } from 'element-plus'; const components = [ ElAlert, ElAside, ElAutocomplete, ElAvatar, ElBacktop, ElBadge, ElBreadcrumb, ElBreadcrumbItem, ElButton, ElButtonGroup, ElCalendar, ElCard, ElCarousel, ElCarouselItem, ElCascader, ElCascaderPanel, ElCheckbox, ElCheckboxButton, ElCheckboxGroup, ElCol, ElCollapse, ElCollapseItem, ElCollapseTransition, ElColorPicker, ElContainer, ElDatePicker, ElDialog, ElDivider, ElDrawer, ElDropdown, ElDropdownItem, ElDropdownMenu, ElFooter, ElForm, ElFormItem, ElHeader, ElIcon, ElImage, ElInput, ElInputNumber, ElLink, ElMain, ElMenu, ElMenuItem, ElMenuItemGroup, ElOption, ElOptionGroup, ElPageHeader, ElPagination, ElPopconfirm, ElPopover, ElPopper, ElProgress, ElRadio, ElRadioButton, ElRadioGroup, ElRate, ElRow, ElScrollbar, ElSelect, ElSlider, ElStep, ElSteps, ElSubmenu, ElSwitch, ElTabPane, ElTable, ElTableColumn, ElTabs, ElTag, ElTimePicker, ElTimeSelect, ElTimeline, ElTimelineItem, ElTooltip, ElTransfer, ElTree, ElUpload, ]; const plugins = [ ElInfiniteScroll, ElLoading, ElMessage, ElMessageBox, ElNotification, ]; const option = { size: 'small', zIndex: 3000 } export default (app) => { // element全局配置 app.config.globalProperties.$ELEMENT = option components.forEach((component) => { app.component(component.name, component); }); plugins.forEach((plugin) => { app.use(plugin); }); };
import useElement from '@/utils/element.js';
const app = createApp(App)
useElement(app)
app.mount('#app')
# 如果报错 Error: @use rules must be written before any other rules.
# 修改vite.config.js
- additionalData: `@import "assets/scss/variables.scss";`
+ additionalData: `@use "assets/scss/variables.scss" as *;`
Vue Router 是 Vue的路由管理器,它和 Vue.js 的核心深度集成,是Vue的核心插件之一。
npm i -s vue-router@4.0.10
src目录下新建router目录文件夹
router目录下新建index.js
// 引入vue-router对象 import { createRouter, createWebHistory } from "vue-router"; import Layout from '@/layout' /** * 定义路由数组 */ const routes = [ {// 404路由 name: '404', path: '404', component: () => import('/@/views/error/404.vue') }, {// 401路由 name: '401', path: '401', component: () => import('@/views/error/401.vue'), hidden: true }, { name: 'home', path: "home", component: () => import("/@/views/home/home.vue"), } ]; /** * 创建路由 */ const router = createRouter({ // hash模式:createWebHashHistory, // history模式:createWebHistory history: createWebHistory("/"), // history:createWebHashHistory(), routes, }); /** * 路由守卫 */ router.beforeEach((guard) => { beforeEach.checkAuth(guard, router); }); /** * 路由错误回调 */ router.onError((handler) => { console.log("error:", handler); }); /** * 输出对象 */ export default router
import { createApp } from 'vue'
import App from './App.vue'
import useElement from '@/utils/element.js';
import router from '@/router/index.js'
const app = createApp(App)
useElement(app)
app.use(router)
app.mount('#app')
npm i vuex@4 -s
在src目录下新建store目录
store目录下新建index.js文件
import { createStore, Store } from 'vuex';
import user from './modules/user';
import getters from './getters'
const store = createStore({
modules: { user },
getters
});
export default store
// src/store/modules/user.js const state = { name: 'hello vue3', age: 18 } const mutations = { SET_NAME: (state, name) => { state.name = name }, SET_AGE: (state, age) => { state.age = age } } const actions = { setName({ commit }, name) { commit('SET_NAME', name) }, setAge({ commit }, age) { commit('SET_AGE', age) } } export default { namespaced: true, state, mutations, actions }
import { createApp } from 'vue'
import App from './App.vue'
import useElement from '@/utils/element.js';
import router from '@/router/index.js'
import i18n from '@/i18n/index.js'
import store from '@/store/index.js' //++++
const app = createApp(App)
app.use(router)
app.use(store) //++++
app.use(i18n)
useElement(app)
app.mount('#app')
通过vue-i18n实现国际化
npm i vue-i18n@next -s
src目录下新建i18n目录,新建cn.js、en.js多语言配置文件
// src/i18n/cn.js export default { message: { hello: '你好,欢迎使用Vue3' } }; // src/i18n/en.js export default { message: { hello: 'Hello Vue3' } };
i18n目录下新建index.js
// src/i18n/index.js import { createI18n } from 'vue-i18n'; import cn from './cn.js'; import en from './en.js'; const messages = { en: { ...en }, 'zh-cn': { ...cn } } const i18n = createI18n({ locale: localStorage.getItem('lang') || 'zh-cn', messages }); export default i18n;
import { createApp } from 'vue'
import App from './App.vue'
import useElement from '@/utils/element.js';
import router from '@/router/index.js'
import i18n from '@/i18n/index.js'
const app = createApp(App)
app.use(router)
app.use(i18n)
useElement(app)
app.mount('#app')
编码过程中,代码规范很重要,采用ESLint可以避免很多编码错误,提高代码可读性,这里采用Airbnb JavaScript 这套代码规范。
npm i -d eslint eslint-config-airbnb-base eslint-plugin-import eslint-plugin-vue
# src目录下新建.eslintrc.js文件,参考如下配置:
module.exports = {
extends: ['plugin:vue/vue3-essential', 'airbnb-base'],
parserOptions: {
sourceType: 'module',
ecmaVersion: 2020,
},
plugins: ['vue'],
rules: {
...
},
};
# 配置ESLint忽略文件,根目录创建.eslintignore文件,内如根据需求添加配置,例如:
/node_modules
/dist
折腾了一两天,基本上按照官网指南进行操作,按步骤即可完成搭建。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。