You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3集成Payload CMS实时预览方案及Vue友好开源无头CMS推荐

问题1:Vue3集成Payload CMS实时预览功能

1. 完善Payload Pages集合配置

先更新Payload的Pages集合,配置动态预览URL和预览权限:

const Pages = {
  admin: {
    useAsTitle: 'title',
    livePreview: {
      // 生成带预览路径的URL,编辑时自动打开预览窗口
      url: ({ data }) => `http://localhost:1234/preview/${data.slug}`,
      width: 1200,
      height: 800
    },
  },
  // 配置预览权限,允许携带预览标识的请求获取草稿数据
  access: {
    preview: ({ req }) => {
      return req.headers['payload-preview'] || req.query['payload-preview'];
    },
  },
}
export default Pages

2. 新增Vue预览路由

修改router/index.js,添加专门的预览路由:

import { createRouter, createWebHistory } from 'vue-router'
import Page from '../views/Page.vue'
import PreviewPage from '../views/PreviewPage.vue'

const routes = [
  {
    path: '/:slug', 
    name: 'Page',
    component: Page,
    props: true
  },
  {
    path: '/preview/:slug',
    name: 'PreviewPage',
    component: PreviewPage,
    props: true
  }
]

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes
})

export default router

3. 实现PreviewPage组件(实时预览核心)

Payload通过WebSocket推送编辑中的草稿数据,组件需要先拉取初始草稿,再监听WebSocket更新:

<template>
  <div v-if="pageData">
    <div v-for="block in pageData.layout" :key="block.id">
      <hero-block v-if="block.blockType === 'hero'" 
        :title="block.title" 
        :subtitle="block.content[0]?.children[0]?.text" 
        :imageURL="block.media?.url" 
        :imageAlt="block.media?.['alt text']">
      </hero-block>
    </div>
  </div>
  <div v-else>
    <p>Loading preview...</p>
  </div>
</template>

<script>
import HeroBlock from '../blocks/HeroBlock.vue'

export default {
  name: 'PreviewPage',
  components: { HeroBlock },
  props: { slug: { type: String, required: true } },
  data() {
    return {
      pageData: null,
      socket: null
    }
  },
  async mounted() {
    await this.fetchPreviewData()
    this.connectWebSocket()
  },
  beforeUnmount() {
    this.socket?.close()
  },
  methods: {
    async fetchPreviewData() {
      try {
        const apiUrl = import.meta.env.VITE_API_URL
        const response = await fetch(`${apiUrl}/pages?where[slug][equals]=${this.slug}&preview=true`, {
          headers: { 'Payload-Preview': 'true' }
        })
        if (!response.ok) throw new Error('Failed to fetch preview data')
        const data = await response.json()
        this.pageData = data.docs[0]
      } catch (err) {
        console.error('Preview data fetch error:', err)
      }
    },
    connectWebSocket() {
      const wsUrl = import.meta.env.VITE_API_URL.replace('http', 'ws') + '/ws'
      this.socket = new WebSocket(wsUrl)

      this.socket.onopen = () => {
        this.socket.send(JSON.stringify({
          type: 'subscribe',
          collection: 'pages',
          id: this.pageData.id
        }))
      }

      this.socket.onmessage = (event) => {
        const message = JSON.parse(event.data)
        if (message.type === 'update' && message.collection === 'pages' && message.id === this.pageData.id) {
          this.pageData = message.doc
        }
      }
    }
  }
}
</script>

可选:合并预览与正常页面逻辑

如果不想单独写PreviewPage组件,可在原Page组件中通过路由判断预览模式,合并拉取数据和WebSocket逻辑。


问题2:是否更换CMS?适配Vue的开源无头CMS推荐

不需要因为Payload偏向React就立刻更换,Payload的核心API是框架无关的,仅官方预览组件为React实现,我们完全可以自己写Vue版预览逻辑(如上),如果已经投入配置成本,继续使用是可行的。

如果想换更适配Vue生态的开源无头CMS,推荐:

  • Directus:官方用Vue3开发Admin UI,对Vue前端天然友好,支持无代码内容建模、原生实时预览,API自动生成,全开源无商业限制。
  • Strapi:最流行的开源无头CMS之一,社区资源丰富,官方提供Vue集成示例,支持REST/GraphQL,自定义能力强,适合大多数Vue项目。
  • TinaCMS:轻量级Git-based CMS,适合Nuxt等静态站点,内容直接存储在Git仓库,无需数据库,Vue集成简单。
  • KeystoneJS:基于Node.js的高度自定义CMS,支持GraphQL,Vue对接无压力,适合需要复杂后端逻辑的场景。

其中Directus和Strapi是Vue项目的首选,前者对Vue生态适配更自然,后者社区资源更充足。


内容的提问来源于stack exchange,提问作者eligolf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 16:25:05