没有节点的Vue SSR

时间:2019-10-10 09:00:55

标签: javascript vue.js vuejs2

我正在重构一个大量使用vue组件的Web应用。

当前,使用树枝模板语言在服务器端渲染vue组件。组件以静态html的形式呈现到页面上...不使用webpack或vue cli。数据是动态的...(产品目录)。

您可以将每个页面视为呈现为静态html的“单页应用”。模板是树枝和豆瓣汤。

长期的目的是将后端移动到Phoenix,所以我正在尝试使组件尽可能轻便,以使它们不会与树枝紧密耦合。

我想在重构中使用vue cli,vuex,webpack等。我想在服务器端渲染组件...但是,我无法使用vue SSR,因为我们无法在服务器上运行节点。

我是否可以构建组件(使用webpack等),将其上传到服务器-并在服务器端将其预先填充数据?

我曾经(但无法上班)的一个想法是尝试将vuex存储放置在我编译的vue应用程序之外...作为美化的字符串。然后,我可以(使用树枝)将数据写入其中,并将应用程序嵌入向下发送的html中。

它仍然会使用树枝-但仅用于填充vuex状态对象...其余的将作为html字符串发送下来...从理论上讲,我认为这不应该杀死搜索引擎,页面?

2 个答案:

答案 0 :(得分:1)

Vue docs提到了一些您可以签出的选项。

一个看起来很有前途的特殊项目是prerender-spa-plugin

答案 1 :(得分:0)

好吧...。这就是我设法做到的:

像往常一样使用vue cli和所有很酷的工具来构建vue SPA

使用https://github.com/SolarLiner/vue-cli-plugin-prerender-spa通过vue cli轻松配置prerender-spa-plugin。

在store.js内部-设置状态...。这需要类似于数据的形状。

例如:

const state = {
  isLoading: false,
  products: [
    {
      name: 'Product 10',
      sku: '12345',
      price: 300,
      stock: 100
    }
  ],
  cart: {

  }
}

此“应用”具有动态数据。因此,我们需要使用正确的数据更新状态客户端。通过mounted内部的Ajax调用来完成此操作非常麻烦,因为我们将从服务器发送此消息,并且可以访问服务器上的初始数据...

在main.js文件中,添加一个已挂接的钩子:

new Vue({
  store,
  render: h => h(App),
  mounted () {
    const configElement = document.getElementById('config')
    const config = JSON.parse(configElement && configElement.innerHTML)
    const initialState = (config && config.initialState)
    if (initialState) {
      // Set our initial state here - this will overwrite the state
      // in our store with the data we want
      this.$store.commit('INIT_STATE', initialState)
    }

    // You'll need this for renderAfterDocumentEvent.
    document.dispatchEvent(new Event('render-event'))
  }
}).$mount('#app')

并在store.mutations内部-添加'INIT_STATE'突变。例如:

  INIT_STATE (state, initialState) {
    state.products = initialState
  },

您可能想在已安装的设备中使用action-但由于该操作不是异步的,因此我决定直接进行更改。

在构建项目时-您将得到一个index.html文件。在index.html内,在app.js上方添加一个JSON脚本标签(我们这样做是因为我们不希望浏览器认为它是JavaScript)。

使用服务器端模板在初始状态下“拖放”作为JSON对象。例如

<script id="config" type="application/json">
  {{get_my_initial_data_as_JSON()}}
</script>
<script src="/js/app.67487567.js"></script>

成为:

<script id="config" type="application/json">
    {"initialState":[{"name":"Product 1","sku":"123","price":300,"stock":10},{"name":"Product 2","sku":"234","price":300,"stock":10},{"name":"Product 3","sku":"456","price":300,"stock":10},{"name":"Product 4","sku":"678","price":300,"stock":10}]}
</script>
<script src="/js/app.67487567.js"></script>

如果您查看index.html的源代码,您将看到html包含Build({name: product10}等)中的商店中的初始数据

但是,商店会使用正确的数据自动更新到安装的挂钩中。

我已经测试过,并且google看到并抓取了已装载的数据。

好处:

以这种方式更新初始状态意味着不需要Ajax调用即可获取初始数据...因此,交互时间和页面加载都更快。

此方法将硬连接vue模板的服务器端信息删除到服务器端模板中。您不必使用两种模板语言(例如,vue和细枝,或细枝的混合来输出vue)来复制模板。它将您的vue应用从后端解开。

最大的好处是能够使用Vue Cli的工具和Webpack-由于服务器端的原因,以前几乎无法使用。

**编辑**

考虑一下-您只需进入/public/index.html并在行上方插入JSON脚本标签

如果您要在此处添加打算用于编写JSON的服务器端方法-例如:

 <script id="config" type="application/json">
   {{get_my_initial_data_as_JSON()}}
  </script> 

您没有任何客户端文件可以编辑:)您只需要从服务器上获取该文件,并准备好get_my_initial_data_as_JSON()即可填充文件。