vit2 здесь
Vite1
Еще не пользовался,Vite2
был обновлен, с новой архитектурой плагинов, удобным опытом разработки иVue3
идеальное сочетание. Первая пуля в 2021 году, староста деревни планирует начать всеобщее обучение с темы Vite2 + Vue3.
В 2021 году правильно выучить вите первым
Цель этой статьи
-
vite2
анализ изменений - Общие задачи в проекте
vite2+vue3
упражняться
Создайте проект Vite2
Излишне говорить сплетни, давайте перечислим герояvite2
Используйте NPM:
$ npm init @vitejs/app
Укажите имя проекта и шаблон по запросу или напрямую
$ npm init @vitejs/app my-vue-app --template vue
Основные изменения в Vite2
Я отметил все те, которые оказали большее влияние на наши предыдущие проекты:
- Изменения параметров конфигурации:
vue特有选项
, параметры создания, параметры css, параметры jsx и т. д. -
别名行为变化
: больше не требуется/
начать или закончить -
Vue支持
:пройти через@vitejs/plugin-vueПоддержка плагинов - Реагировать на поддержку
- Изменения API HMR
- Изменения формата списка
插件API重新设计
Поддержка Vue
Интеграция Vue также достигается с помощью плагинов, как и в других фреймворках:
В определении SFC используется значение по умолчанию.setup script
, синтаксис радикальнее, но лаконичнее, хвала!
Определение псевдонима
больше не нужно что-то вродеvite1
Добавьте то же самое до и после псевдонима/
,с участиемwebpack
Конфигурация проекта может быть последовательной и легко трансплантируемой, хвала!
import path from 'path'
export default {
alias: {
"@": path.resolve(__dirname, "src"),
"comps": path.resolve(__dirname, "src/components"),
},
}
App.vue
Попробуйте внутри
<script setup>
import HelloWorld from 'comps/HelloWorld.vue'
</script>
Редизайн API плагина
Vite2
Основное изменение коснулось системы подключаемых модулей, которая стала более стандартизированной и легко расширяемой.Vite2
API плагина расширяется отRollup
подключаемая система, поэтому она совместима с существующимиRollup
Плагины, написанные плагины Vite, также могут работать в разработке и создании одновременно, хвала!
Я открою специальную дискуссию о написании плагинов, и вы можете обратить на меня внимание.
Поддержка Vue3 JSX
vue3
серединаjsx
Поддержка требует внедрения плагинов:@vitejs/plugin-vue-jsx
$ npm i @vitejs/plugin-vue-jsx -D
зарегистрировать плагин,vite.config.js
import vueJsx from "@vitejs/plugin-vue-jsx";
export default {
plugins: [vue(), vueJsx()],
}
Есть также требования для использования, реформировать егоApp.vue
<!-- 1.标记为jsx -->
<script setup lang="jsx">
import { defineComponent } from "vue";
import HelloWorld from "comps/HelloWorld.vue";
import logo from "./assets/logo.png"
// 2.用defineComponent定义组件且要导出
export default defineComponent({
render: () => (
<>
<img alt="Vue logo" src={logo} />
<HelloWorld msg="Hello Vue 3 + Vite" />
</>
),
});
</script>
Мок-плагин
я познакомил тебя раньшеvite-plugin-mockРефакторинг для поддержки Vite2.
Установить плагин
npm i mockjs -S
npm i vite-plugin-mock cross-env -D
настроить,vite.config.js
import { viteMockServe } from 'vite-plugin-mock'
export default {
plugins: [ viteMockServe({ supportTs: false }) ]
}
установить переменные окружения,package.json
{
"scripts": {
"dev": "cross-env NODE_ENV=development vite",
"build": "vite build"
},
}
Инфраструктура проекта
маршрутизация
Установитьvue-router 4.x
npm i vue-router@next -S
настройка маршрутизации,router/index.js
import { createRouter, createWebHashHistory } from 'vue-router';
const router = createRouter({
history: createWebHashHistory(),
routes: [
{ path: '/', component: () => import('views/home.vue') }
]
});
export default router
импорт,main.js
import router from "@/router";
createApp(App).use(router).mount("#app");
не забудьте создать
home.vue
и изменитьApp.vue
Использование маршрутизации немного изменилось,видеоурок
государственное управление
Установитьvuex 4.x
npm i vuex@next -S
Конфигурация магазина,store/index.js
import {createStore} from 'vuex';
export const store = createStore({
state: {
couter: 0
}
});
импорт,main.js
import store from "@/store";
createApp(App).use(store).mount("#app");
Использование в основном такое же, как и раньше,видеоурок
организация стиля
установить sass
npm i sass -D
styles
Каталог содержит различные стили
index.scss
Организуйте эти стили как экспорт при написании некоторых глобальных стилей.
Наконец вmain.js
импорт
import "styles/index.scss";
обрати внимание на
vite.config.js
Добавить кstyles
псевдоним
библиотека пользовательского интерфейса
просто используйте насКоманда Хуагошаньсобственныйelement3.
Установить
npm i element3 -S
полный импорт,main.js
import element3 from "element3";
import "element3/lib/theme-chalk/index.css";
createApp(App).use(element3)
импорт по требованию,main.js
import "element3/lib/theme-chalk/button.css";
import { ElButton } from "element3"
createApp(App).use(ElButton)
Было бы лучше извлечь его как плагин.plugins/element3.js
// 完整引入
import element3 from "element3";
import "element3/lib/theme-chalk/index.css";
// 按需引入
// import { ElButton } from "element3";
// import "element3/lib/theme-chalk/button.css";
export default function (app) {
// 完整引入
app.use(element3)
// 按需引入
// app.use(ElButton);
}
тестовое задание
<el-button>my button</el-button>
Базовая компоновка
Нашему приложению нужна базовая страница макета, как показано на рисунке ниже.В будущем каждая страница может взять страницу макета в качестве родительской страницы:
страница макета,layout/index.vue
<template>
<div class="app-wrapper">
<!-- 侧边栏 -->
<div class="sidebar-container"></div>
<!-- 内容容器 -->
<div class="main-container">
<!-- 顶部导航栏 -->
<navbar />
<!-- 内容区 -->
<app-main />
</div>
</div>
</template>
<script setup>
import AppMain from "./components/AppMain.vue";
import Navbar from "./components/Navbar.vue";
</script>
<style lang="scss" scoped>
@import "../styles/mixin.scss";
.app-wrapper {
@include clearfix;
position: relative;
height: 100%;
width: 100%;
}
</style>
не забудьте создать
AppMain.vue
а такжеNavbar.vue
настройка маршрутизации,router/index.js
{
path: "/",
component: Layout,
children: [
{
path: "",
component: () => import('views/home.vue'),
name: "Home",
meta: { title: "首页", icon: "el-icon-s-home" },
},
],
},
Динамическая навигация
боковая навигация
Динамически создавать боковые навигационные меню на основе таблиц маршрутизации.
Сначала создайте компонент боковой панели, рекурсивно выведитеroutes
Конфигурация представляет собой многоуровневое меню,layout/Sidebar/index.vue
<template>
<el-scrollbar wrap-class="scrollbar-wrapper">
<el-menu
:default-active="activeMenu"
:background-color="variables.menuBg"
:text-color="variables.menuText"
:unique-opened="false"
:active-text-color="variables.menuActiveText"
mode="vertical"
>
<sidebar-item
v-for="route in routes"
:key="route.path"
:item="route"
:base-path="route.path"
/>
</el-menu>
</el-scrollbar>
</template>
<script setup>
import SidebarItem from "./SidebarItem.vue";
import { computed } from "vue";
import { useRoute } from "vue-router";
import { routes } from "@/router";
import variables from "styles/variables.module.scss";
const activeMenu = computed(() => {
const route = useRoute();
const { meta, path } = route;
if (meta.activeMenu) {
return meta.activeMenu;
}
return path;
});
</script>
Уведомление:
sass
Многомерный анализ экспорта файлов необходимо использоватьcss module
,следовательноvariables
файл для добавленияmodule
инфикс.
Добавьте связанные стили:
styles/variables.module.scss
styles/sidebar.scss
-
styles/index.scss
введен в
СоздайтеSidebarItem.vue
Компонент, определяет, является ли текущий маршрут навигационной ссылкой или родительским меню:
Панировочные сухари
Хлебные крошки могут быть динамически сгенерированы с помощью массивов сопоставления маршрутов.
компонент панировочных сухарей,layouts/components/Breadcrumb.vue
<template>
<el-breadcrumb class="app-breadcrumb" separator="/">
<el-breadcrumb-item v-for="(item, index) in levelList" :key="item.path">
<span
v-if="item.redirect === 'noRedirect' || index == levelList.length - 1"
class="no-redirect"
>{{ item.meta.title }}</span>
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
</el-breadcrumb-item>
</el-breadcrumb>
</template>
<script setup>
import { compile } from "path-to-regexp";
import { reactive, ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
const levelList = ref(null);
const router = useRouter();
const route = useRoute();
const getBreadcrumb = () => {
let matched = route.matched.filter((item) => item.meta && item.meta.title);
const first = matched[0];
if (first.path !== "/") {
matched = [{ path: "/home", meta: { title: "首页" } }].concat(matched);
}
levelList.value = matched.filter(
(item) => item.meta && item.meta.title && item.meta.breadcrumb !== false
);
}
const pathCompile = (path) => {
var toPath = compile(path);
return toPath(route.params);
}
const handleLink = (item) => {
const { redirect, path } = item;
if (redirect) {
router.push(redirect);
return;
}
router.push(pathCompile(path));
}
getBreadcrumb();
watch(route, getBreadcrumb)
</script>
<style lang="scss" scoped>
.app-breadcrumb.el-breadcrumb {
display: inline-block;
font-size: 14px;
line-height: 50px;
margin-left: 8px;
.no-redirect {
color: #97a8be;
cursor: text;
}
}
</style>
Не забудьте добавить зависимости:
path-to-regexp
Уведомление:
vue-router4
больше не используетсяpath-to-regexp
Разбирать динамическиpath
, поэтому здесь необходимы дальнейшие улучшения.
инкапсуляция данных
Унифицированная инкапсуляция сервисов запросов данных полезна для решения следующих проблем:
- Единый запрос конфигурации
- Единая обработка запросов и ответов
Готов к работе:
-
Установить
axios
:npm i axios -S
-
Добавить файл конфигурации:
.env.development
VITE_BASE_API=/api
инкапсуляция запроса,utils/request.js
import axios from "axios";
import { Message, Msgbox } from "element3";
// 创建axios实例
const service = axios.create({
// 在请求地址前面加上baseURL
baseURL: import.meta.env.VITE_BASE_API,
// 当发送跨域请求时携带cookie
// withCredentials: true,
timeout: 5000,
});
// 请求拦截
service.interceptors.request.use(
(config) => {
// 模拟指定请求令牌
config.headers["X-Token"] = "my token";
return config;
},
(error) => {
// 请求错误的统一处理
console.log(error); // for debug
return Promise.reject(error);
}
);
// 响应拦截器
service.interceptors.response.use(
/**
* 通过判断状态码统一处理响应,根据情况修改
* 同时也可以通过HTTP状态码判断请求结果
*/
(response) => {
const res = response.data;
// 如果状态码不是20000则认为有错误
if (res.code !== 20000) {
Message.error({
message: res.message || "Error",
duration: 5 * 1000,
});
// 50008: 非法令牌; 50012: 其他客户端已登入; 50014: 令牌过期;
if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
// 重新登录
Msgbox.confirm("您已登出, 请重新登录", "确认", {
confirmButtonText: "重新登录",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
store.dispatch("user/resetToken").then(() => {
location.reload();
});
});
}
return Promise.reject(new Error(res.message || "Error"));
} else {
return res;
}
},
(error) => {
console.log("err" + error); // for debug
Message({
message: error.message,
type: "error",
duration: 5 * 1000,
});
return Promise.reject(error);
}
);
export default service;
обработка бизнеса
Представление структурированных данных
использоватьel-table
Отображать структурированные данные, сотрудничать сel-pagination
Выполните подкачку данных.
Организационная структура документа выглядит следующим образом:list.vue
показать список,edit.vue
а такжеcreate.vue
Редактировать или создавать, повторно использовать внутриdetail.vue
иметь дело с,model
Отвечает за бизнес-обработку данных.
list.vue
отображение данных в
<el-table v-loading="loading" :data="list">
<el-table-column label="ID" prop="id"></el-table-column>
<el-table-column label="账户名" prop="name"></el-table-column>
<el-table-column label="年龄" prop="age"></el-table-column>
</el-table>
list
а такжеloading
Логика сбора данных, вы можете использоватьcompsition-api
извлечь вuserModel.js
export function useList() {
// 列表数据
const state = reactive({
loading: true, // 加载状态
list: [], // 列表数据
});
// 获取列表
function getList() {
state.loading = true;
return request({
url: "/getUsers",
method: "get",
}).then(({ data, total }) => {
// 设置列表数据
state.list = data;
}).finally(() => {
state.loading = false;
});
}
// 首次获取数据
getList();
return { state, getList };
}
list.vue
используется в
import { useList } from "./model/userModel";
const { state, getList } = useList();
обработка пагинации,list.vue
<pagination
:total="total"
v-model:page="listQuery.page"
v-model:limit="listQuery.limit"
@pagination="getList"
></pagination>
данные такжеuserModel
обработка
const state = reactive({
total: 0, // 总条数
listQuery: {// 分页查询参数
page: 1, // 当前页码
limit: 5, // 每页条数
},
});
request({
url: "/getUsers",
method: "get",
params: state.listQuery, // 在查询中加入分页参数
})
обработка формы
Добавление, редактирование и использование пользовательских данныхel-form
иметь дело с
доступен один компонентdetail.vue
Для обработки разница только в том, заливается ли информация обратно в форму при инициализации.
<el-form ref="form" :model="model" :rules="rules">
<el-form-item prop="name" label="用户名">
<el-input v-model="model.name"></el-input>
</el-form-item>
<el-form-item prop="age" label="用户年龄">
<el-input v-model.number="model.age"></el-input>
</el-form-item>
<el-form-item>
<el-button @click="submitForm" type="primary">提交</el-button>
</el-form-item>
</el-form>
Обработка данных также может извлекатьuserModel
в процессе.
export function useItem(isEdit, id) {
const model = ref(Object.assign({}, defaultData));
// 初始化时,根据isEdit判定是否需要获取详情
onMounted(() => {
if (isEdit && id) {
// 获取详情
request({
url: "/getUser",
method: "get",
params: { id },
}).then(({ data }) => {
model.value = data;
});
}
});
return { model };
}
Поддерживающая демонстрация видео
Я специально записал набор видеороликов, чтобы продемонстрировать все операции, проделанные в этой статье, и маленьких друзей, которые любят смотреть обучающее видео движение:«Подготовка к 2021 году» Лучшие практики проекта Vite2 + Vue3
Это не легко сделать, попросите один3连
,关注
Не переусердствуйте! ?
Поддержка раздаточных материалов с исходным кодом
Добро пожаловать, чтобы обратить внимание на публичный аккаунт «Village Head School Front-end», чтобы забрать
Последующий творческий план
Самым важным обновлением vite2 является система плагинов, я планирую сделать это позже, включая, но не ограничиваясь следующим:
- Разбор рабочего механизма vite2
- Анализ механизма плагина vit2
- Практика написания плагина Vite2
Все, ставьте лайки и добавляйте в закладки для дальнейшего изучения.
поддержать старосту села
Это про практику проекта vite2.Этот контент кидал уже давно.Я наступил на много ям и потерял несколько волосков.Друзья,пожалуйста, лайкните и поддержите меня,окей?
Мои последние статьи (спасибо моим друзьям за поддержку и поддержку 🌹🌹🌹):
- 🔥Подготовка к 2021: инженерная практика, рекомендуемая коллекция857 лайков
- 🔥Это еще одна ночь, вы думаете, что эта практика Composition-API коротка?217 любит
- 🔥Чтобы выиграть vue3, вы должны сделать эти приготовления76 лайков
- 🔥Lightning Five Whips: углубленный анализ принципов Composition API54 лайка