在Rails 5中使用Webpacker将Vue.js应用程序从子路径提供服务

3
我想要实现的是将 Vue 3 应用程序添加到现有的 Rails 应用程序中。因此,在加载路由/spa/*之前,我的应用程序将是一个典型的Rails应用程序。在这种情况下,Rails的控制器将提供一个依赖于Webpack服务JS的布局...
首先,我在routes.rb中添加了路由/spa/,以便始终将其解析为一个控制器,该控制器提供使用javascript_pack_tag的正确布局。
然后,我已经成功地安装和设置了Webpacker在我的Rails 5.2应用程序中,并且似乎它正在正常工作,因为我已经建立了一个简单的应用程序,其中包括Vue路由和一些组件,当单击链接时正确呈现。好吧,几乎...
问题在于我将Vue应用程序提供在路径/spa/下而不是根目录/下。当我加载/spa/ URL时,显示我的标题组件(保存链接),但初始组件(Vue路由中的组件)未呈现,直到我单击Vue链接。组件被呈现,但URL从/spa/变为/q1。显然,如果我们重新加载浏览器,则该路由不受Vue而受Rails控制。
我想要实现的是告诉Webpack(er)和Vue在任何Vue路由链接之前添加/spa/
<nav id="nav">
      <router-link to="/">Question 1</router-link>
      <router-link to="/q2">Question 2</router-link>
</nav>

我知道我可以在每个链接中硬编码/spa,但那感觉很不舒服:D

我的Vue路由器:

import { createWebHistory, createRouter } from "vue-router";
import Question1 from "@/vue/views/Question1.vue";
import Question2 from "@/vue/views/Question2.vue";
// import About from "@/views/About.vue";

const routes = [
  {
    path: "q1",
    name: "Question1",
    component: Question1,
  },
  {
    path: "q3",
    name: "Question2",
    component: Question2,
  },
  { 
    path: "", 
    redirect: { name: 'Question1' }
  }
];

const router = createRouter({
  history: createWebHistory(),
  // publicPath: '/spa',
  base: '/spa/',
  routes,
});

export default router;

根据Vue 3文档,通过在路由配置中添加base参数可以很容易地解决这个问题,但是它没有起作用 :/,publicPath也是如此。
我还在某处发现,使用Webpack和Vue可以通过在vue.config.js中添加路径来解决此问题,但是使用Webpacker gem时,我不确定该怎么做。
问题是: 当调用路由/spa/时,如何使我的Vue应用程序的行为就像不存在/spa/一样?
最终编辑
跳转至@Excalibaard的答案 :)
在我的情况下,问题在于我正在使用Vue router v4,其语法与搜索路由器文档时通常看到的语法不同。
在v3路由器中,base:是传递给createRouter()函数的对象的属性。
在v4中,base是传递给createWebHistory("the-base-value")的参数。
所以,在我的情况下,解决方案将是:
const router = createRouter({
  mode:history,
  history: createWebHistory( '/spa/' ),
  routes,
});

1
你的主Vue应用程序中是否也在导出/导入VueRouter?我在你的片段中没有看到导出链接。 - Excalibaard
是的!对此感到抱歉...我已经更新了代码片段。 - luigi7up
1个回答

3

您正在使用3.0语法。

  • 在vue-router 3.0中,您可以通过new Router实例化路由器。您需要为新的Router实例提供一个base option
  • 在vue-router 4.0中,您可以通过createRouter函数完成此操作。routerOptions不再接受base键;base现在是createHistory function的可选参数。

请尝试以下操作:

const router = createRouter({
  history: createWebHistory('/spa/'),
  routes,
});

关于编辑webpack配置:

vue.config.js是用于配置Vue-CLI的文件。这与webpacker gem冲突,因为它们都有自己的方式来管理webpack和部署链。对于webpacker,您应该从导入自定义规则到您的config/webpack文件夹中并合并到默认配置来编辑webpack配置。


编辑:原始(不正确)答案

您需要删除路径开头的斜杠。在开头的斜杠告诉vue-router将其处理为绝对路径。

https://router.vuejs.org/api/#route-object-properties

https://router.vuejs.org/guide/essentials/nested-routes.html

当你扩展规模时,我建议使用:to="{ name:'Foo' }"来引用路径名,而不是直接引用路径,以防您更改路由的路径。


如果我删除斜杠并将路由保留为 { path: "q1", name: "Question1", component: Question1, } Vue应用程序根本无法编译。错误是:vue-router.esm-bundler.js:1293 Uncaught Error:路由路径应该以“/”开头:“q1”应该是“/q1”。 - luigi7up
1
无法反驳如此明确的编辑消息;)。我已经编辑了我的答案。已经有一段时间没有在同一个应用程序中使用vue和rails,而不是单独的前端和后端了。但问题似乎出现在vue-router 4.0中。 - Excalibaard
非常感谢!我注意到我的路由器初始化与基本参数没有做任何事情,但是我绝对不会注意到Vue Router ~3和v4之间的区别...我会更新我的问题并指向您的正确答案,以帮助下一个迷失的灵魂!再次感谢您! - luigi7up
我注意到新路由器位于“next”子域下...这是怎么回事?为什么只是简单的/v3和/v4分离? - luigi7up
Vue 3.0 最近才发布,通过在下一个域名下提供公共测试和审查来使其可用。许多已经建立的工具仍需要跟进。一旦 Vue 3.0 项目得到足够的外部(UI)库支持,以便新人可以舒适地使用它,我相信它将成为“默认”版本,“next”子域将在下一次重大变化之前变得无用。 - Excalibaard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接