Что такое автоинъекция маршрута
Самостоятельное обучение концепции автоинъекции маршрутизацииnuxt, нам не нужноrouter.jsКаждый раз, когда вы вручную вводите код для импорта модуля, но автоматически в соответствии с文件目录格式генерироватьrouter.js
Мы разделяем эту функцию наwebpackПлагины и связанные с ними функции были улучшены и реализованыvue-routerВсе основные функции
Более подробные инструкции по использованию и документацию можно найти в нашемрепозиторий github
Приведите простой пример, например длину вашего каталога
src
├── views
│ ├── Login
│ │ └── Index.vue
│ └── User
│ ├── Account
│ │ └── Index.vue
│ ├── Home
│ │ └── Index.vue
│ └── Index.vue
Правила просты, если один уровень справочникаIndex.vue, имя каталога — это текущее имя роутинга, а если это подпапка, то это роутинг второго уровня, который автоматически генерируется после этогоrouter.jsбудет расти так
{
component: () =>
import('@/views/Login/Index.vue'),
name: 'login',
path: '/login'
},
{
component: () =>
import('@/views/User/Index.vue'),
name: 'user',
path: '/user'
},
{
component: () =>
import('@/views/User/Account/Index.vue'),
name: 'user-account',
path: '/user/account'
},
{
component: () =>
import('@/views/User/Home/Index.vue'),
name: 'user-home',
path: '/user/home'
}
Здесь стоит упомянуть, что созданныйrouter.jsНет необходимости добавлять его в систему контроля версий, потому что какая бы ни была разработка (development) или производство (production) При первой сборке проекта он будет сгенерирован автоматически, например, если в вашем проекте используетсяgitа такжеeslint, то его следует поместить в.gitignoreа также.eslintignoreсередина
Зачем использовать автоматическую инъекцию маршрута
- Удобство
Вместо того, чтобы каждый раз обращаться к модулю, просто создайте папку,router.jsбудет автоматически сгенерирован
- Единое наименование маршрута
Если есть полныйcode reviewЭтой проблемы не существует, но мы делаем ее немного проще, покаcode reviewИмя папки хорошее, и окончательно сгенерированный путь маршрутизации будет называться горбом, а сгенерированное имя будет называться горбом и символами соединения.-Соедините маршруты на разных уровнях
- Единая иерархия маршрутизации
Например, на картинке мы не можем судить об уровне маршрута по названию файла, и часто при записи это явно маршрут уровня 2 или уровня 3, но он находится под маршрутом уровня 1, который это очень неправильно и не логично
Сравните маршрутизацию после использования автоматического внедрения для разделения иерархии
src/views
├── Index.vue
├── NotFound.vue
├── Withdraw
<!-- 第一级 -->
│ ├── Index.vue
│ └── Result
│ ├── Description
<!-- 第三级 -->
│ │ └── Index.vue
<!-- 第二级 -->
│ └── Index.vue
└── WithdrawHistory
<!-- 第一级 -->
└── Index.vue
Иерархию маршрутов можно увидеть из структуры каталогов
Еще раз взглянем на сгенерированные маршруты, названия маршрутов на разных уровнях написаны через дефис.-связь, иерархия очень четкая
{
component: () => import('@/views/Withdraw/Index.vue'),
name: 'withdraw',
path: '/withdraw'
},
{
component: () => import('@/views/Withdraw/Result/Index.vue'),
name: 'withdraw-result',
path: '/withdraw/result'
},
{
component: () => import('@/views/Withdraw/Result/Description/Index.vue'),
name: 'withdraw-result-description',
path: '/withdraw/result/description'
},
{
component: () => import('@/views/WithdrawHistory/Index.vue'),
name: 'withdrawHistory',
path: '/withdrawHistory'
},
Почему вы выбираетеvue-router-invoke-webpack-plugin
- Идеальные модульные тесты
- поддержка типов
vue-router-invoke-webpack-pluginУникальное подразделение маршрутизации, мыслящее
Когда у нас слишком много страниц, например, в проекте более 60 или даже более 70 отдельных страниц, невозможно разместить файлы в одном каталоге.Как правило, мы нажимаем功能Поместите маршруты подобных функций в директорию, мы делали это раньше, на самом деле в этом нет никакой проблемы, но под автоматическим внедрением маршрутов мы предлагаем другой способ мышления путем маршрутизации层级делить
На какой уровень деления это простое предложение делится в зависимости от относительного URL-адреса страницы, дайте Liezi, наш дом выглядит следующим образом
Путь на главную страницу/, мы считаем домашнюю страницу корневым маршрутом, то маршруты первого уровня, которые можно ввести, следующие:提现 提现记录 分成数据Подождите, после нажатия на вывод мы вводим маршрут вывода/withdraw
После входа на страницу вывода будет два кликабельных места.Эти два места - страницы второго уровня, которые размещаются в подпапках страницы первого уровня.Согласно тому, что я только что сказал, директория маршрутизации (перехваченная часть) вот так
src/views
├── Bank
<!-- 银行卡管理 -->
│ └── Index.vue
├── DivideData
<!-- 分成数据 -->
│ └── Index.vue
<!- 首页 --->
├── Index.vue
<!-- 404路由 -->
├── NotFound.vue
├── Withdraw
│ ├── BankDetails
<!-- 提现中查看银行卡信息 -->
│ │ └── Index.vue
│ ├── Description
<!-- 提现说明 -->
│ │ └── Index.vue
<!-- 提现页面 -->
│ └── Index.vue
└── WithdrawHistory
<!--提现记录 -->
└── Index.vue
На самом деле, это обычно разделено таким образом. Подобные функции будут находиться под папкой, и идея маршрутизации по функции также реализуется, и это иерархическое разделение проясняется с первого взгляда, и это легко увидеть принадлежность маршрутизации.
Но иногда возникает проблема, что некоторые страницы могут отображаться ниже текущего уровня, следующие могут также появляться на другом уровне, в соответствии с функциональными точками, когда они есть, эта функция может существовать между двумя функциональными точками, на самом деле, этот случай может быть считается под правильным уровнем, на котором мало или сильно пользователь кликает, привыкнув думать, какую позицию поставит немного больше на уровень, ниже которого
vue-router-invoke-webpack-pluginУникальная файловая структура в
Может быть, у вас возникнут сомнения, почему вы должны писать это какIndex.vueИ добавьте дополнительный уровень инкапсуляции папок и назовите его напрямуюvueФайл плохой, использовал егоnuxtстудентов также могут почувствовать разницу, поэтому мыnuxtдополнение кfeature, чтобы инкапсулировать одну страницу более удобно
Например, если ваш проект не ссылается на библиотеку пользовательского интерфейса, многие бизнес-компоненты должны быть написаны вами самостоятельно, за исключением часто используемых компонентов, которые будут размещены в самой внешней части каталога.componentsфайл, где вы размещаете остальные бизнес-компоненты, соответствующие одной странице? Это место, которое мы резервируем. Например, структура каталогов выглядит следующим образом
src/views
├── Audit
│ ├── Index.vue
│ ├── components
│ │ └── AuditItem.vue
│ └── images
│ └── AuditIntro.png
Auditнаша страница утверждения, которая использует страницу, которая используется только текущей страницейAuditItem.vueкомпонент, который также ссылается на изображение, которое используется только текущей страницейAuditIntro.png, Для этого требования рождается уникальная файловая структура, понятнее будет поместить картинки компонентов текущей страницы в папку, но стоит упомянуть, что это тоже нужно установить в плагинеignoreЧтобы игнорировать каталоги, которые не анализируются нами, такие как этот
plugins: [
new VueRouterInvokeWebpackPlugin({
dir: 'src/views',
alias: '@/views',
language: 'javascript',
ignore: ['images', 'components', 'template.vue']
})
];
Такimages components template.vueбудет игнорироваться без разбора
Поговорим о контроле разрешений маршрутизации
Что касается разрешений маршрутизации внешнего интерфейса, я видел статью некоторое время назад, и я чувствую, что идея реализации немного сложнее.beforeEachХук на совпадение, если нет разрешения, просто пропустите 404 или страницу без разрешения.vue-router-invoke-webpack-pluginнапиши вот так
apis.getForbiddenRoute
export default {
// 请求当前没有权限的路由列表
async getForbiddenRoute() {
return ['/single/user'];
}
};
plugins: [
new VueRouterInvokePlugin({
// 观察的目录
dir: 'demos/src',
// 观察目录的别名
alias: '@/src',
// 当前语言
language: 'javascript',
// 生成router.js的位置
routerDir: 'demos',
// 忽略文件夹
ignore: ['images', 'template.vue', 'components', 'notfound.vue'],
// 404路由地址
notFound: '@/src/NotFound.vue',
// 引用的模块
modules: [
{
name: 'apis',
package: '@/apis'
}
],
// 同scrollBehavior
scrollBehavior: (to, from, savedPosition) => {
if (savedPosition) {
return savedPosition;
} else {
return { x: 0, y: 0 };
}
},
<!-- 主要是这段代码 -->
/* eslint-disable */
beforeEach: async (to, from, next) => {
// 通过绑定在静态属性上的_cachedForbiddenRoute判断是否请求过接口
if (!Vue._cachedForbiddenRoute) {
Vue._cachedForbiddenRoute = [];
await apis.getForbiddenRoute().then(res => {
Vue._cachedForbiddenRoute = res;
});
}
// 当当前页面的地址存在于禁止访问的列表中,则直接跳转到404页面
if (Vue._cachedForbiddenRoute.includes(to.path)) {
next({
name: 'notFound'
});
} else {
next();
}
}
}),
]
Но опять же, любые идеи реализации, данные интерфейса, полученные внешним интерфейсом, все еще можно обойти, если вы хотите подделать их, поэтому вам все равно нужно защищаться от внутреннего интерфейса.
Идеи реализации проекта
Реализация проекта не слишком сложна, но есть много моментов, о которых нужно позаботиться.
- базовая маршрутизация
- динамическая маршрутизация
- Многоуровневая вложенная маршрутизация
- Многоуровневая вложенная динамическая маршрутизация
- мета альтернатива
- Дружелюбное обращение с файлами, не соответствующими правилам
- Единое наименование
- родной в узле
fsМодули очень недружественные
Есть довольно много мелких деталей, которые следует учитывать, особенно когда маршрутизация слишком сложна.
Но узелfsСуть в том, что я не подумал об этом, особенно на кроссплатформенности, поэтому мы отказались от использования нативногоfsмодуль, сchokidarа такжеfs-extraзамененыfsчасть функции
Я учился некоторое время назадvueСинтаксическое дерево ast, поэтому я изучил следующие идеи, чтобы попытаться построить ast, но метод все еще отличается, vue строит синтаксическое дерево путем обычного разбиения元素开始标签 元素属性 元素字符 元素结束标签После ожидания и сплайсинга процесс сплайсинга очень сложен.Этот проект будет намного проще.Вы можете сгенерировать дерево, рекурсивно обходя каталог напрямую, читая файл.astохватывать
Затем используйте дерево синтаксиса для построения строкиrouter.js, процесс построения еще более хлопотный, и, наконец, записать построенную строку в файл, и все готово
Проект еще нуждается в доработке
- модульный тест
Текущий показатель покрытия юнит-тестами 100%, но я думаю есть еще и немного сложные ситуации, которые не были написаны.Позже я не только посмотрю на показатель покрытия юнит-тестами, но и дополню полноту по функционалу точки, которые необходимо проверить.
- тестовая среда
Доступ к проектуcircleci, Не вwindowsСледующий тест, обычная среда разработки тожеmac, поэтому после тестовой среды нам предстоит изучить другие инструменты ci, которые могут поддерживать windows, и протестировать разные версии узлов
На самом деле сейчасwindowsНиже также есть ошибка, но я нашелnuxtСуществует также эта ошибка, поэтому я чувствую, что это может быть не ошибка или функция, и я упомяну об этом позже.issueСпросите совета, я не знаю, проблема ли это в моем компьютере, проще говоряfs.watchКогда вы собираетесь отслеживать каталог файлов (но на самом деле здесь используетсяchokidar, но все равно) при изменении имени существующего файлового каталога его изменить нельзя,windowsСледующее подскажет вам, на какой текущий файл ссылается, и вам нужно завершить процесс, прежде чем имя файла можно будет изменить.
- более дружеская поддержка
В настоящее время проект поддерживает версию узла > 8.15.1, поддерживает толькоwebpack4, поддержит позжеwebpack3и предстоящийwebpack5
2019-04-19 15:41:31 Версия > 0.2.5
поддерживаетсяwebpack3
больше возможностей
Помимо только что упомянутого примера простого маршрута и настройки игнорирования элементов, мы также поддерживаемvue-routerдругих основных функций, в том числе动态路由 嵌套路由 全局路由守卫 meta替代品и другие функции, соответствующие функциональные пункты написаны в документах нашего склада с открытым исходным кодом.Для получения подробной информации об использовании и мерах предосторожности вы можете посетить нашрепозиторий github, Если вы считаете, что проект неплох, вы можете дать нам небольшую звезду.Конечно, если вы обнаружите что-то отличное от того, что вы ожидали, или ошибку в использовании, вы всегда можете дать нам предложениеissue