这是我在工作中所做的应用程序关键部分的修改版本。
# config/routes.rb
# frozen_string_literal: true
Rails.application.routes.draw do
root('application#index')
# I use a scope because in the real app I also have other routes such as
# browserconfig.xml and site.webmanifest which are both procedurally
# generated.
scope('/', format: false) do
# Catch all for HTML 5 history routing. This must be the last route.
get('*path', to: 'application#index')
end
# equivalent, if scope is unnecessary
# get('/*path', to: 'application#index', format: false)
end
# app/controllers/application_controller.rb
# frozen_string_literal: true
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
def index
# Avoid having an empty view file.
render(inline: '', layout: 'application')
end
end
/ app/views/layouts/application.html.slim
doctype html
html
head
/ ...
body
main
/ Webpacker 4.3.0
= javascript_packs_with_chunks_tag('main', defer: true)
在我的 JS 代码中,我在 main 元素上挂载了一个 Vue 实例。所有客户端/Vue 路由都通过我的 Vue 路由器处理。我有一个JS目录树结构如下:
project_root/
|-- src/
|-- api/ <- external REST API handling code
|-- channels/ <- Action Cable stuff
|-- components/ <- Vue SFC's and functional components
|-- images/ <- image files
|-- lib/ <- various local library code
|-- mixins/ <- Vue component mixins
|-- packs/ <- all files in here are picked up by Webpacker; these are the entry-points
|-- main.mjs <- imports pages/main.mjs (my app has multiple packs and pages, and there's "some" logic behind this structure)
|-- pages/
|-- main.mjs <- does the heavy lifting of building the Vue instance
|-- plugins/ <- Vue plugins
|-- scss/ <- SCSS files
|-- store/ <- Vuex stuff
|-- vendor/ <- third-party vendor stuff, like poly-fills
|-- main.mjs
// src/pages/main.mjs
import '@/scss/main.scss';
// this should be first to ensure `vendors` loads first
import build from '@/main';
import VuexRouterSync from 'vuex-router-sync';
import App from '@/components/app.vue';
import router from '@/lib/router';
import store from '@/store';
build(
App,
{
router,
store,
},
(Vue) => {
Vue.use(BootstrapVueUtils);
VuexRouterSync.sync(store, router);
},
);
// src/main.mjs
import '@/vendor';
import isFunction from 'lodash-es/isFunction';
import Vue from 'vue';
export default function build(appComponent, config = {}, preInit = null) {
// call Vue.use here for any plugins that are common to all packs/pages
// Vue.use(Vuelidate);
if (preInit == null && isFunction(config)) {
preInit = config;
config = {};
}
if (isFunction(preInit)) {
preInit(Vue);
}
function init() {
new Vue({
beforeCreate() {
Vue.$rootVm = this;
},
render(h) {
return h(appComponent);
},
...config,
}).$mount('main');
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
}
// src/lib/router.mjs
import Vue from 'vue';
import VueRouter from 'vue-router';
import Folder from '@/components/folders/show.vue';
import Folders from '@/components/folders'; // index.vue
import Home from '@/components/home.vue';
import LogIn from '@/components/log-in.vue';
import NotFound from '@/components/not-found.vue';
import Settings from '@/components/settings'; // index.vue
Vue.use(VueRouter);
const router = new VueRouter({
mode: 'history',
saveScrollPosition: true,
routes: [
{
path: '/',
redirect: '/folders',
component: Home,
children: [
{
name: 'folders',
path: 'folders',
component: Folders,
},
{
name: 'folder',
path: 'folders/:id',
component: Folder,
},
{
name: 'settings',
path: 'settings',
component: Settings,
},
],
},
{
name: 'log-in',
path: '/log-in',
component: LogIn,
},
// This isn't necessary, and I question it now. Has no effect on the functioning of the router.
{
name: 'not-found',
path: '*',
component: NotFound,
}
],
});
// There's some additional code after this to setup event handling on the
// `router`, specifically `router.beforeEach` to check the logged-in status
// and if not logged in redirect to the log-in route.
这是很多代码,但我想尝试涵盖从 Rails 路由器到 Vue 路由器的所有内容,还包括一些可能有帮助的额外内容。
我确实注意到您在 'home' Vue 路由的子数组中包含了前导 /。这是不必要的,因为它是基于父级隐含的。
来自Vue Router docs:
请注意,以 / 开头的嵌套路径将被视为根路径。这允许您利用组件嵌套,而无需使用嵌套 URL。
因此,虽然没有必要,但我认为这不是您问题的原因。
我唯一能想到的就是绝对确定 Rails 包罗万象的路线是最后一条路线。 Rails 路由从上到下按照config/routes.rb 文件中指定路由的顺序进行匹配。