实时演示
如果您时间紧迫,请查看我们在 Stackblitz 上的官方 实时演示。
🚀 使用
注意 此模块适用于 Nuxt 3。 查看
@storyblok/nuxt-2
以获取 Nuxt 2.
重要 如果您是 Storyblok 的首次用户,请阅读 入门 指南,以便在不到 5 分钟的时间内准备好项目。
安装
安装 @storyblok/nuxt
npx nuxi@latest module add storyblok
将以下代码添加到 nuxt.config.js
的 modules 部分,并将 accessToken 替换为 Storyblok 空间的 API 令牌。
import { defineNuxtConfig } from "nuxt";
export default defineNuxtConfig({
modules: [
["@storyblok/nuxt", { accessToken: "<your-access-token>" }]
// ...
]
});
您也可以使用 storyblok
配置,如果您更喜欢。
import { defineNuxtConfig } from "nuxt";
export default defineNuxtConfig({
modules: ["@storyblok/nuxt"],
storyblok: {
accessToken: "<your-access-token>"
}
});
警告 此 SDK 在后台使用 Fetch API。如果您的环境不支持它,您需要安装一个 polyfill,例如 isomorphic-fetch。有关更多信息,请参阅 storyblok-js-client 文档。
选项
初始化模块时,您可以传递所有 @storyblok/vue 选项,以及一个 bridge
选项,该选项在我们的 JS SDK Storyblok 桥接部分 中解释,以及一个 enableSudoMode
选项来定义您自己的插件(见下文)。
注意 如果您想在
nuxt-devtools
中使用 Storyblok,您可以使用选项devtools
,如果启用,请确保已安装 @nuxt/devtools 模块并在您的 nuxt 配置中启用它。
// Defaults
["@storyblok/nuxt", {
{
accessToken: "<your-access-token>",
bridge: true,
devtools: true,
apiOptions: {}, // storyblok-js-client options
}
}]
定义您自己的插件
虽然推荐的方法涵盖了大多数情况,但有些情况下您可能需要使用 enableSudoMode
选项并禁用我们的插件,以便您可以合并您自己的插件。
// nuxt.config.ts
modules: [
[
"@storyblok/nuxt",
{
accessToken: "<your-access-token>",
enableSudoMode: true
}
]
];
要在 SDK 的 apiOptions
中包含其他功能,例如自定义缓存方法,您可以在 plugins 文件夹(自动导入)中实现以下解决方案。
// plugins/storyblok.js
import { StoryblokVue, apiPlugin } from "@storyblok/vue";
export default defineNuxtPlugin(({ vueApp }) => {
vueApp.use(StoryblokVue, {
accessToken: "<your-access-token>",
apiOptions: {
cache: {
type: "custom",
custom: {
flush() {
console.log("all right");
}
}
}
},
use: [apiPlugin]
});
});
区域参数
可能的值
eu
(默认):用于在欧盟创建的空间us
:用于在美国创建的空间ap
:用于在澳大利亚创建的空间ca
:用于在加拿大创建的空间cn
:用于在中国创建的空间
在美国创建的空间的完整示例
["@storyblok/nuxt", {
{
accessToken: "<your-access-token>",
apiOptions: {
region: "us"
}
}
}]
重要 对于在美国或中国创建的空间,
region
参数 **必须** 指定。
入门
1. 创建并链接您的组件到 Storyblok 可视化编辑器
将您的 Vue 组件链接到 Storyblok 空间中的等效组件
- 首先,您需要将它们全局加载,并将它们添加到
~/storyblok
目录中。在您的代码中使用帕斯卡命名法命名它们很重要ExampleComponent.vue
,并在您的 Storyblok 空间中使用连字符命名它们example-component
,这样它们将被自动导入。
如果您想为 Storyblok 相关的组件定义自己的目录,您可以在nuxt.config.js
中使用选项componentsDir
// nuxt.config.ts modules: [ [ "@storyblok/nuxt", { accessToken: "<your-access-token>", componentsDir: false, } ] ], components: { dirs: [ { path: '~/components/storyblok', global: true, } ] },
否则,您可以设置另一个目录并手动加载它们(例如,通过 使用 Nuxt 插件)。警告 请注意,如果您在
storyblok
文件夹中命名的组件与components
文件夹中的另一个组件相同,它将无法正常工作。提示:在您的 Nuxt 项目中使用不同的名称来保留组件。 - 对于每个组件,在其根元素上使用
v-editable
指令,传递它们接收的blok
属性
<div v-editable="blok" / >
- 最后,使用
<StoryblokComponent>
,它在 Nuxt 应用程序中全局可用
<StoryblokComponent :blok="blok" />
该
blok
是来自 Storblok 的内容交付 API 的实际块数据。
2. 获取 Storyblok 故事并监听可视化编辑器事件
组合 API
最简单的方法是使用 useAsyncStoryblok
一行可组合(它被自动导入)。您需要将 slug
作为第一个参数传递,而第二个和第三个参数 apiOptions
和 bridgeOptions
分别是可选的。
查看我们 API 文档中可用的 apiOptions 和传递给 Storyblok Bridge 的 bridgeOptions。
注意 如果你想了解更多关于版本控制的信息
{ version: "draft" /* 或 "publish" */ }
,请访问 预览和/或生产环境的使用 部分。
<script setup>
const story = await useAsyncStoryblok(
"vue",
{ version: "draft", resolve_relations: "Article.author" }, // API Options
{ resolveRelations: ["Article.author"], resolveLinks: "url" } // Bridge Options
);
if (story.value.status) {
throw createError({
statusCode: story.value.status,
statusMessage: story.value.response
});
}
</script>
<template>
<StoryblokComponent v-if="story" :blok="story.content" />
</template>
这是在 useState
和 useStoryblokBridge
函数中分别使用 useStoryblokApi
的简写等效方法。
<script setup>
const story = useState();
const storyblokApi = useStoryblokApi();
const { data } = await storyblokApiInstance.get(
`cdn/stories/vue`,
{
version: "draft"
}
);
story.value = data.story;
onMounted(() => {
useStoryblokBridge(
story.value.id,
(evStory) => (story.value = evStory),
{ resolveRelations: ["Article.author"], resolveLinks: "url" } // Bridge Options
);
});
</script>
<template>
<StoryblokComponent v-if="story" :blok="story.content" />
</template>
useState
是一个 SSR 友好的ref
替代方案。它的值将在服务器端渲染后(在客户端水合期间)保留。
渲染富文本
你可以使用 @storyblok/nuxt
附带的 renderRichText
函数和 Vue 计算属性轻松渲染富文本。
<template>
<div v-html="articleContent"></div>
</template>
<script setup>
const props = defineProps({ blok: Object });
const articleContent = computed(() =>
renderRichText(props.blok.articleContent)
);
</script>
你还可以通过将选项作为 renderRichText
函数的第二个参数传递来设置自定义模式和组件解析器。
<script setup>
import cloneDeep from "clone-deep";
const mySchema = cloneDeep(RichTextSchema); // you can make a copy of the default RichTextSchema
// ... and edit the nodes and marks, or add your own.
// Check the base RichTextSchema source here https://github.com/storyblok/storyblok-js-client/blob/v4/source/schema.js
const props = defineProps({ blok: Object });
const articleContent = computed(() =>
renderRichText(props.blok.articleContent, {
schema: mySchema,
resolver: (component, blok) => {
switch (component) {
case "my-custom-component":
return `<div class="my-component-class">${blok.text}</div>`;
default:
return "Resolver not defined";
}
}
})
);
</script>
3. 使用预览和/或生产环境
请记住,桥接器只使用 version: 'draft'
和 预览访问令牌 工作。
对于生产站点,不作为内容编辑器的预览使用,应该使用 version: 'published'
和 公共访问令牌。
注意 如果你将生产环境用作营销人员和你的公共网站的预览,你需要一个插件来处理不同的 .env 变量,或者使用 预览访问令牌 的版本,检查你是否在 Storyblok 中。例如,类似于
if (window.location.search.includes(_storyblok_tk[token]=<YOUR_TOKEN>)
。
查看官方文档,了解如何 访问不同的内容版本。
API
useAsyncStoryblok(slug, apiOptions, bridgeOptions)
(推荐选项)在幕后使用 useState
来帮助实现 SSR 兼容性。
查看可用的 apiOptions(传递给 storyblok-js-client
)和 bridgeOptions(传递给 Storyblok Bridge)。
useStoryblok(slug, apiOptions, bridgeOptions)
当我们需要进行完整的客户端请求时,例如获取已登录用户的个性化数据,使用 useStoryblok
而不是 useAsyncStoryblok
可能会有所帮助。
查看可用的 apiOptions(传递给 storyblok-js-client
)和 bridgeOptions(传递给 Storyblok Bridge)。
useStoryblokApi()
返回 storyblok-js-client
的实例。
useStoryblokBridge(storyId, callback, bridgeOptions)
使用此单行函数来涵盖最常见的用例:在 Storyblok 可视化编辑器上发生任何更改时更新故事。
Storyblok JavaScript SDK 生态系统
🔗 相关链接
- Stackblitz 上的实时演示
- Nuxt.js 集线器: 了解如何开发使用 Storyblok API 来检索和管理内容的 Nuxt.js 应用程序;
- Storyblok & Nuxt.js 在 GitHub 上: 查看我们所有 Nuxt.js 开源仓库;
- Storyblok CLI: 用于构建 Storyblok 项目和字段类型的简单 CLI。
ℹ️ 更多资源
支持
- 错误或功能请求?提交问题;
- 您是否对 Storyblok 有疑问或需要帮助?加入我们的 Discord 社区.
贡献
请查看我们的 贡献指南 和我们的 行为准则。此项目使用 semantic-release 通过使用提交消息来生成新版本,我们使用 Angular 约定来命名提交。查看 此问题 关于 semantic-release 常见问题解答中的内容。