{"id":48227,"date":"2023-01-08T21:06:50","date_gmt":"2023-10-24T03:40:33","guid":{"rendered":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8headlesscms-graphql-vue-js%e6%9d%a5%e5%88%9b%e5%bb%baspa-%e5%8d%9a%e5%ae%a2\/"},"modified":"2024-04-29T09:08:27","modified_gmt":"2024-04-29T01:08:27","slug":"%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8headlesscms-graphql-vue-js%e6%9d%a5%e5%88%9b%e5%bb%baspa-%e5%8d%9a%e5%ae%a2","status":"publish","type":"post","link":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8headlesscms-graphql-vue-js%e6%9d%a5%e5%88%9b%e5%bb%baspa-%e5%8d%9a%e5%ae%a2\/","title":{"rendered":"\u5c1d\u8bd5\u4f7f\u7528HeadLessCMS + GraphQL + Vue.js\u6765\u521b\u5efaSPA (\u535a\u5ba2)"},"content":{"rendered":"<p>\u6211\u5e0c\u671b\u5b66\u4e60\u4e00\u4e9b\u65b0\u6280\u672f\uff0c\u4e8e\u662f\u6211\u7528HeadLessCMS + GraphQL + Vue.js\u521b\u5efa\u4e86\u4e00\u4e2a\u7b80\u5355\u7684SPA\uff08\u535a\u5ba2\uff09\u3002<br \/>\n\u5728\u8fd9\u4e2a\u8fc7\u7a0b\u4e2d\uff0c\u6211\u5c06\u6240\u5b66\u7684\u5185\u5bb9\u6574\u7406\u6210\u4e86\u6559\u7a0b\u5f62\u5f0f\u3002<br \/>\n\u4e3a\u4e86\u8ba9\u521d\u5b66\u8005\u66f4\u5bb9\u6613\u7406\u89e3\uff0c\u6211\u5c3d\u91cf\u591a\u5730\u9644\u4e0a\u4e86\u5c4f\u5e55\u622a\u56fe\u3002<\/p>\n<h1>\u603b\u7ed3<\/h1>\n<p>\u4f7f\u7528Headless CMS\u3001GraphQL\u3001Vue.js\u548cApollo\u521b\u5efa\u535a\u5ba2\u3002\u7531\u4e8e\u4e3b\u8981\u662f\u6559\u7a0b\uff0c\u6240\u4ee5\u7701\u7565\u4e86GraphQL\u67e5\u8be2\u7684\u8be6\u7ec6\u8bf4\u660e\u3002\u4ee5\u4e0b\u662f\u5404\u4e2a\u7248\u672c\u3002<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">GraphCMS: 2018.7\u516c\u958b\u306e\u3082\u306e<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">Vue cli: 3.0.1<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">vue: 2.5.17<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">vue-apollo: 3.0.0-beta.11<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">vue-router&#8221;: 3.0.1<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">vuetify: 1.2.4<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">graphql: 14.0.2<\/ul>\n<h2>\u5236\u4f5c\u4e00\u4e2a\u6837\u54c1<\/h2>\n<p>\u6211\u5c06\u521b\u5efa\u4e00\u4e2a\u5177\u6709\u4e24\u79cd\u7c7b\u578b\u9875\u9762\uff08\u5e16\u5b50\u5217\u8868\u548c\u8be6\u7ec6\u9875\u9762\uff09\u7684\u535a\u5ba2\uff08Single Page Application\uff09\u3002\u5916\u89c2\u65b9\u9762\uff0c\u6211\u4f1a\u5c3d\u529b\u4f7f\u7528Vue\u7684\u7ec4\u4ef6\u5e93Vuetify\u6765\u5b9e\u73b0\u7c7b\u4f3c\u7684\u6548\u679c\u3002<\/p>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d83d2913a08637a6b454b\/6-0.gif\" alt=\"output1.gif\" \/><\/div>\n<p>\u4f60\u53ef\u4ee5\u5728\u8fd9\u91cc\u786e\u8ba4\u5df2\u7ecf\u90e8\u7f72\u5728Heroku\u4e0a\u7684\u5185\u5bb9\u3002<br \/>\n\uff08\u7531\u4e8e\u4e0d\u4f1a\u4e00\u76f4\u8fd0\u884c\uff0c\u6240\u4ee5\u521d\u6b21\u8bbf\u95ee\u53ef\u80fd\u4f1a\u6709\u4e00\u4e9b\u5ef6\u8fdf\uff09<br \/>\nhttps:\/\/graphcms-sampleblog.herokuapp.com\/<\/p>\n<p>\u8fd9\u91cc\u662f\u6e90\u4ee3\u7801\u3002<br \/>\nhttps:\/\/github.com\/kawamataryo\/vue-sample-blog<\/p>\n<h1>\u521b\u5efaAPI\u670d\u52a1\u5668<\/h1>\n<p>\u9996\u5148\uff0c\u4f7f\u7528 headressCMS \u7684 GraphCMS \u521b\u5efa API \u670d\u52a1\u5668\u3002<br \/>\n\u6b63\u5982\u5176\u540d\uff0c\u53ea\u9700\u5728\u6d4f\u89c8\u5668\u4e2d\u70b9\u70b9\u70b9\u5c31\u80fd\u521b\u5efa\u57fa\u7840\u8bbe\u65bd\u3001\u6570\u636e\u5e93\u5efa\u8bbe\u548c API \u8bbe\u8ba1\u7b49\u7b49\uff0c\u65e0\u9700\u8003\u8651\u5176\u4ed6\u95ee\u9898\uff0c<br \/>\n\u5c31\u80fd\u521b\u5efa API \u670d\u52a1\u5668\u3002\u800c\u4e14\uff0c\u54cd\u5e94\u683c\u5f0f\u662f GraphQL\u3002<\/p>\n<h2>\u521b\u5efaGraphCMS\u8d26\u6237<\/h2>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d83d2913a08637a6b454b\/12-0.png\" alt=\"\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8 2018-09-16 15.37.30.png\" \/><\/div>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d83d2913a08637a6b454b\/13-0.png\" alt=\"\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8 2018-09-16 15.37.44.png\" \/><\/div>\n<h2>\u521b\u5efa\u6a21\u5f0f<\/h2>\n<p>\u6211\u5011\u5c07\u6839\u64da\u5074\u908a\u6b04\u9078\u55ae\u7684\u65b9\u6848\u4f86\u5275\u5efa\u6a21\u578b\u3002\u9019\u5c31\u50cf\u662f\u4e00\u500b\u6578\u64da\u5eab\uff0c\u8207API\u7684\u6578\u64da\u6709\u95dc\u806f\u3002<br \/>\n\u5728\u6a21\u578b\u4e2d\uff0c\u60a8\u53ef\u4ee5\u50cfWordPress\u7684\u81ea\u5b9a\u7fa9\u6587\u7ae0\u985e\u578b\u4e00\u6a23\u5275\u5efa\u8f38\u5165\u5b57\u6bb5\u3002<\/p>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d83d2913a08637a6b454b\/16-0.png\" alt=\"\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8 2018-09-16 15.39.25.png\" \/><\/div>\n<p>\u53ef\u4ee5\u901a\u8fc7\u53f3\u4e0a\u89d2\u7684\u201cCreateModel\u201d\u8fdb\u884c\u521b\u5efa\u3002<br \/>\n\u672c\u6b21\u662f\u4ee5\u4ee5\u4e0b\u5185\u5bb9\u8fdb\u884c\u521b\u5efa\u7684\u3002<\/p>\n<pre class=\"post-pre\"><code># \u30e2\u30c7\u30eb\u306e\u69cb\u6210\r\ndisplayName\uff1a post\r\napi key\uff1a Post\r\n# \u30d5\u30a3\u30fc\u30eb\u30c9\u306e\u69cb\u6210\r\ntitle: single line text\r\ndescription: multi type text\r\ncontent: mark down\r\nthumbnail: asset picker\r\n<\/code><\/pre>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d83d2913a08637a6b454b\/19-0.png\" alt=\"\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8 2018-09-16 15.40.54.png\" \/><\/div>\n<h2>\u6dfb\u52a0\u6570\u636e<\/h2>\n<p>\u60a8\u53ef\u4ee5\u9009\u62e9\u4fa7\u8fb9\u680f\u4e2d\u7684\u201c\u5185\u5bb9\u201d&gt;\u201c\u5e16\u5b50\u201d\uff0c\u7136\u540e\u4f7f\u7528\u53f3\u4e0a\u89d2\u7684\u201c\u521b\u5efa\u5e16\u5b50\u201d\u6765\u6dfb\u52a0\u6570\u636e\u3002<br \/>\n\u8ba9\u6211\u4eec\u968f\u4fbf\u6dfb\u52a0\u4e00\u4e9b\u5185\u5bb9\u3002<br \/>\n\u540e\u9762\u5c06\u4f7f\u7528vue-apollo\u6765\u83b7\u53d6\u5e76\u89e3\u91ca\u8fd9\u4e9b\u6570\u636e\u3002<\/p>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d83d2913a08637a6b454b\/22-0.png\" alt=\"\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8 2018-09-16 20.47.14.png\" \/><\/div>\n<h2>\u5c1d\u8bd5\u4f7f\u7528GraphQL<\/h2>\n<p>\u8f93\u5165\u5185\u5bb9\u540e\uff0c\u7acb\u5373\u5c1d\u8bd5\u4f7f\u7528GraphQL\u3002\u53ef\u4ee5\u5728\u4fa7\u8fb9\u680f\u7684API Explorer\u4e2d\u5c1d\u8bd5\u53d1\u9001GraphQL\u8bf7\u6c42\u3002\u8f93\u5165\u65f6\u4e5f\u4f1a\u6709\u81ea\u52a8\u8865\u5168\u529f\u80fd\uff0c\u70b9\u51fb\u53f3\u4fa7\u7684Docs\u6309\u94ae\uff0c\u53ef\u4ee5\u67e5\u770b\u4e0e\u521b\u5efa\u7684\u6a21\u578b\u76f8\u5339\u914d\u7684GraphQL\u67e5\u8be2\u4fe1\u606f\u3002<\/p>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d83d2913a08637a6b454b\/25-0.png\" alt=\"\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8 2018-09-17 23.35.30.png\" \/><\/div>\n<h2>\u786e\u8ba4API\u4fe1\u606f<\/h2>\n<p>\u53ef\u4ee5\u4ece\u4fa7\u8fb9\u680f\u7684\u8bbe\u7f6e\u83dc\u5355\u4e2d\u786e\u8ba4\u7528\u4e8e\u6570\u636e\u83b7\u53d6\u7684\u7aef\u70b9\u3002<br \/>\n\u56e0\u4e3a\u662fGraphQL\uff0c\u6240\u4ee5\u53ea\u9700\u4e00\u884c\u4ee3\u7801\u3002<br \/>\n\u6b64\u5916\uff0c\u60a8\u8fd8\u53ef\u4ee5\u5728\u8bbe\u7f6e\u83dc\u5355\u4e2d\u8fdb\u884c\u7aef\u70b9\u7684\u516c\u5f00\u8bbe\u7f6e\u7b49\u64cd\u4f5c\u3002<br \/>\n\u521d\u59cb\u8bbe\u7f6e\u4e3a\u53ea\u8bfb\u3002\u672c\u6b21\u64cd\u4f5c\u65e0\u9700\u7279\u522b\u66f4\u6539\u3002<\/p>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d83d2913a08637a6b454b\/28-0.png\" alt=\"\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8 2018-09-16 15.41.49.png\" \/><\/div>\n<h1>\u524d\u7aef\u5f00\u53d1<\/h1>\n<p>\u63a5\u4e0b\u6765\u6211\u4eec\u5c06\u4f7f\u7528graphCMS\u521b\u5efa\u7684\u6570\u636e\u6765\u521b\u5efa\u4e00\u4e2a\u524d\u7aef\u754c\u9762\u6765\u663e\u793a\u5b83\u3002\u6211\u4eec\u5c06\u4f7f\u7528\u53ef\u4ee5\u7b80\u5355\u521b\u5efavue\u9879\u76ee\u7684vue cli\u5de5\u5177\u3002<\/p>\n<h2>\u521b\u5efa\u9879\u76ee<\/h2>\n<p>\u9996\u5148\uff0c\u5b89\u88c5Vue CLI\u3002<\/p>\n<pre class=\"post-pre\"><code>\r\n<span class=\"nv\">$ <\/span>npm <span class=\"nb\">install<\/span> <span class=\"nt\">-g<\/span> @vue\/cli-service-global\r\n<\/code><\/pre>\n<p>\u7136\u540e\u4f7f\u7528Vue CLI 3\u521b\u5efa\u9879\u76ee\u3002<\/p>\n<pre class=\"post-pre\"><code>\r\n<span class=\"nv\">$ <\/span>vue create sample-blog\r\n<\/code><\/pre>\n<p>\u5982\u679c\u9009\u62e9\u9ed8\u8ba4\u9009\u9879\uff0c\u53ef\u4ee5\u3002<br \/>\n\u901a\u8fc7\u4ee5\u4e0b\u547d\u4ee4\u542f\u52a8\uff0c\u5e76\u5728\u8bbf\u95eehttp:\/\/localhost:8088\/\u540e\u6210\u529f\u542f\u52a8\u65f6\uff0c\u9879\u76ee\u521b\u5efa\u6210\u529f\u3002<\/p>\n<pre class=\"post-pre\"><code>\r\n<span class=\"nv\">$ <\/span><span class=\"nb\">cd <\/span>sample-blog\r\n<span class=\"nv\">$ <\/span>yarn serve\r\n<\/code><\/pre>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d83d2913a08637a6b454b\/38-0.png\" alt=\"\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8 2018-09-23 7.06.43.png\" \/><\/div>\n<h2>\u6dfb\u52a0Vuetify<\/h2>\n<p>\u56e0\u4e3a\u5373\u4f7f\u662f\u6a21\u62df\u4e5f\u80fd\u63d0\u9ad8\u89c2\u611f\uff0c\u6240\u4ee5\u6211\u4eec\u9996\u5148\u6dfb\u52a0\u4e86vue.js\u7684\u7ec4\u4ef6\u5e93vuetify\u3002\u6dfb\u52a0\u4e86\u5b83\u4e4b\u540e\uff0c\u53ef\u4ee5\u4f7f\u7528\u5404\u79cd\u6750\u6599\u8bbe\u8ba1\u7684\u7ec4\u4ef6\u3002vuetify\u4e5f\u6709\u4e30\u5bcc\u7684\u624b\u518c\uff0c\u90e8\u5206\u5185\u5bb9\u5df2\u7ecf\u7ffb\u8bd1\u6210\u65e5\u8bed\u3002<\/p>\n<h3>\u5b89\u88c5<\/h3>\n<p>\u5728Vue CLI3\u4e2d\uff0c\u53ef\u4ee5\u5f88\u5bb9\u6613\u5730\u5c06Vuetify\u4f5c\u4e3a\u63d2\u4ef6\u6dfb\u52a0\u8fdb\u53bb\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nv\">$ <\/span>vue add vuetify\r\n<\/code><\/pre>\n<p>\u7136\u540e\u4f1a\u51fa\u73b0\u9009\u9879\u9009\u62e9\u3002\u8fd9\u6b21\u6211\u4eec\u8bbe\u7f6e\u5982\u4e0b\u3002<\/p>\n<pre class=\"post-pre\"><code>\r\n? Use a pre-made template? <span class=\"o\">(<\/span>will replace App.vue and HelloWorld.vue<span class=\"o\">)<\/span> Yes\r\n? Use custom theme? No\r\n? Use custom properties <span class=\"o\">(<\/span>CSS variables<span class=\"o\">)<\/span>? No\r\n? Select icon font fa4\r\n? Use fonts as a dependency <span class=\"o\">(<\/span><span class=\"k\">for <\/span>Electron or offline<span class=\"o\">)<\/span>? No\r\n? Use a-la-carte components? No\r\n? Use babel\/polyfill? Yes\r\n? Select locale en\r\n<\/code><\/pre>\n<p>\u90a3\u4e48\uff0c\u6211\u5c06\u5c1d\u8bd5\u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u6765\u542f\u52a8\u3002<\/p>\n<pre class=\"post-pre\"><code>\r\n<span class=\"nv\">$ <\/span>yarn serve\r\n<\/code><\/pre>\n<p>\u6253\u5f00 http:\/\/localhost:8080\/\uff0c\u5982\u679c\u6210\u529f\u663e\u793a\u5982\u4e0b\u754c\u9762\uff0c\u5219\u8868\u793avuetify\u5df2\u6210\u529f\u5b89\u88c5\u5b8c\u6210\u3002<\/p>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d83d2913a08637a6b454b\/49-0.png\" alt=\"\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8 2018-09-23 7.27.58.png\" \/><\/div>\n<h4>\u5982\u679c\u5728\u8fd0\u884c &#8220;yarn serve&#8221; \u65f6\u51fa\u73b0\u9519\u8bef<\/h4>\n<p>\u5728\u6211\u7684\u73af\u5883\u4e2d\uff0c\u51fa\u73b0\u4e86\u4ee5\u4e0b\u9519\u8bef\u3002<\/p>\n<pre class=\"post-pre\"><code>\r\n ERROR  Failed to compile with 1 errors                                                                                                                                           07:22:42\r\n\r\n error  <span class=\"k\">in<\/span> .\/src\/main.js\r\n\r\nModule build failed <span class=\"o\">(<\/span>from .\/node_modules\/babel-loader\/lib\/index.js<span class=\"o\">)<\/span>:\r\nBrowserslistError: <span class=\"o\">[<\/span>BABEL] \/Users\/kawamataryou\/vue_training\/sample-blog\/src\/main.js: \/Users\/kawamataryou\/vue_training\/sample-blog contains both .browserslistrc and package.json with brow\r\nsers <span class=\"o\">(<\/span>While processing: <span class=\"s2\">\"\/Users\/kawamataryou\/vue_training\/sample-blog\/node_modules\/@vue\/babel-preset-app\/index.js<\/span><span class=\"nv\">$0<\/span><span class=\"s2\">\"<\/span><span class=\"o\">)<\/span>\r\n<\/code><\/pre>\n<p>\u5305\u542b\u4e86.browserslistrc\u548cpackage.json\uff0c\u8fd9\u4e24\u4e2a\u6587\u4ef6\u90fd\u5b58\u5728\u53ef\u80fd\u662f\u95ee\u9898\u7684\u539f\u56e0\uff0c\u6240\u4ee5\u6211\u5220\u9664\u4e86.browserslistrc\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code>$ rm .browserslistrc\r\n<\/code><\/pre>\n<p>\u5982\u679c\u91cd\u65b0\u542f\u52a8\uff0c\u95ee\u9898\u5c31\u89e3\u51b3\u4e86\u3002<\/p>\n<h3>\u521b\u5efa\u4e00\u4e2a\u6837\u672c\u7ec4\u4ef6<\/h3>\n<p>\u4f7f\u7528Vuetify\u7acb\u5373\u521b\u5efa\u7528\u4e8e\u663e\u793a\u6587\u7ae0\u5217\u8868\u7684Card\u7ec4\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nv\">$ <\/span><span class=\"nb\">touch <\/span>src\/components\/PostCard.vue   \r\n<\/code><\/pre>\n<p>\u5c06\u4ee5\u4e0b\u5185\u5bb9\u6dfb\u52a0\u5230 src\/components\/PostCard.vue \u4e2d\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nt\">&lt;<\/span><span class=\"k\">template<\/span><span class=\"nt\">&gt;<\/span>\r\n  <span class=\"nt\">&lt;v-flex<\/span> <span class=\"na\">xs12<\/span> <span class=\"na\">sm6<\/span> <span class=\"na\">md4<\/span><span class=\"nt\">&gt;<\/span>\r\n    <span class=\"nt\">&lt;article&gt;<\/span>\r\n      <span class=\"nt\">&lt;v-hover&gt;<\/span>\r\n        <span class=\"nt\">&lt;v-card<\/span>\r\n            <span class=\"na\">slot-scope=<\/span><span class=\"s\">\"<\/span>{ hover }\"\r\n            :class=\"`elevation-${hover ? 12 : 2}`\"\r\n        &gt;\r\n          <span class=\"nt\">&lt;a<\/span> <span class=\"na\">href=<\/span><span class=\"s\">\"\"<\/span><span class=\"nt\">&gt;<\/span>\r\n            <span class=\"nt\">&lt;v-img<\/span>\r\n                <span class=\"na\">class=<\/span><span class=\"s\">\"white--text\"<\/span>\r\n                <span class=\"na\">height=<\/span><span class=\"s\">\"170px\"<\/span>\r\n                <span class=\"na\">:src=<\/span><span class=\"s\">post.thumbnail.url<\/span>\r\n            <span class=\"nt\">&gt;<\/span>\r\n            <span class=\"nt\">&lt;\/v-img&gt;<\/span>\r\n          <span class=\"nt\">&lt;\/a&gt;<\/span>\r\n          <span class=\"nt\">&lt;v-card-title&gt;<\/span>\r\n            <span class=\"nt\">&lt;div&gt;<\/span>\r\n              <span class=\"nt\">&lt;h2&gt;<\/span><span class=\"si\">{{<\/span> <span class=\"nx\">post<\/span><span class=\"p\">.<\/span><span class=\"nx\">title<\/span> <span class=\"si\">}}<\/span><span class=\"nt\">&lt;\/h2&gt;<\/span>\r\n              <span class=\"nt\">&lt;span<\/span> <span class=\"na\">class=<\/span><span class=\"s\">\"grey--text\"<\/span><span class=\"nt\">&gt;<\/span><span class=\"si\">{{<\/span> <span class=\"nx\">post<\/span><span class=\"p\">.<\/span><span class=\"nx\">createdAt<\/span><span class=\"si\">}}<\/span><span class=\"nt\">&lt;\/span&gt;&lt;br&gt;<\/span>\r\n              <span class=\"nt\">&lt;span&gt;<\/span><span class=\"si\">{{<\/span> <span class=\"nx\">post<\/span><span class=\"p\">.<\/span><span class=\"nx\">description<\/span> <span class=\"si\">}}<\/span><span class=\"nt\">&lt;\/span&gt;<\/span>\r\n            <span class=\"nt\">&lt;\/div&gt;<\/span>\r\n          <span class=\"nt\">&lt;\/v-card-title&gt;<\/span>\r\n          <span class=\"nt\">&lt;v-card-actions&gt;<\/span>\r\n            <span class=\"nt\">&lt;v-btn<\/span> <span class=\"na\">icon<\/span> <span class=\"na\">class=<\/span><span class=\"s\">\"red--text\"<\/span><span class=\"nt\">&gt;<\/span>\r\n              <span class=\"nt\">&lt;v-icon<\/span> <span class=\"na\">medium<\/span><span class=\"nt\">&gt;<\/span>fa-reddit<span class=\"nt\">&lt;\/v-icon&gt;<\/span>\r\n            <span class=\"nt\">&lt;\/v-btn&gt;<\/span>\r\n            <span class=\"nt\">&lt;v-btn<\/span> <span class=\"na\">icon<\/span> <span class=\"na\">class=<\/span><span class=\"s\">\"light-blue--text\"<\/span><span class=\"nt\">&gt;<\/span>\r\n              <span class=\"nt\">&lt;v-icon<\/span> <span class=\"na\">medium<\/span><span class=\"nt\">&gt;<\/span>fa-twitter<span class=\"nt\">&lt;\/v-icon&gt;<\/span>\r\n            <span class=\"nt\">&lt;\/v-btn&gt;<\/span>\r\n            <span class=\"nt\">&lt;v-btn<\/span> <span class=\"na\">icon<\/span> <span class=\"na\">class=<\/span><span class=\"s\">\"blue--text text--darken-4\"<\/span><span class=\"nt\">&gt;<\/span>\r\n              <span class=\"nt\">&lt;v-icon<\/span> <span class=\"na\">medium<\/span><span class=\"nt\">&gt;<\/span>fa-facebook<span class=\"nt\">&lt;\/v-icon&gt;<\/span>\r\n            <span class=\"nt\">&lt;\/v-btn&gt;<\/span>\r\n            <span class=\"nt\">&lt;v-spacer&gt;&lt;\/v-spacer&gt;<\/span>\r\n            <span class=\"nt\">&lt;v-btn<\/span> <span class=\"na\">flat<\/span> <span class=\"na\">color=<\/span><span class=\"s\">\"blue\"<\/span> <span class=\"na\">href=<\/span><span class=\"s\">\"\"<\/span><span class=\"nt\">&gt;<\/span>Read more<span class=\"nt\">&lt;\/v-btn&gt;<\/span>\r\n          <span class=\"nt\">&lt;\/v-card-actions&gt;<\/span>\r\n        <span class=\"nt\">&lt;\/v-card&gt;<\/span>\r\n      <span class=\"nt\">&lt;\/v-hover&gt;<\/span>\r\n    <span class=\"nt\">&lt;\/article&gt;<\/span>\r\n  <span class=\"nt\">&lt;\/v-flex&gt;<\/span>\r\n<span class=\"nt\">&lt;\/<\/span><span class=\"k\">template<\/span><span class=\"nt\">&gt;<\/span>\r\n\r\n<span class=\"nt\">&lt;<\/span><span class=\"k\">script<\/span><span class=\"nt\">&gt;<\/span>\r\n\r\n  <span class=\"k\">export<\/span> <span class=\"k\">default<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"na\">name<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">PostCard<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"na\">props<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">post<\/span><span class=\"dl\">\"<\/span><span class=\"p\">]<\/span>\r\n  <span class=\"p\">}<\/span>\r\n<span class=\"nt\">&lt;\/<\/span><span class=\"k\">script<\/span><span class=\"nt\">&gt;<\/span>\r\n\r\n<\/code><\/pre>\n<p>\u7136\u540e\uff0c\u6211\u4eec\u9700\u8981\u4fee\u6539App.vue\u6587\u4ef6\uff0c\u4ee5\u4fbf\u52a0\u8f7d\u8fd9\u4e2a\u7ec4\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nt\">&lt;<\/span><span class=\"k\">template<\/span><span class=\"nt\">&gt;<\/span>\r\n  <span class=\"nt\">&lt;v-app&gt;<\/span>\r\n    <span class=\"nt\">&lt;v-container<\/span> <span class=\"na\">grid-list-xl<\/span><span class=\"nt\">&gt;<\/span>\r\n      <span class=\"nt\">&lt;v-layout<\/span> <span class=\"na\">row<\/span> <span class=\"na\">wrap<\/span><span class=\"nt\">&gt;<\/span>\r\n        <span class=\"nt\">&lt;PostCard<\/span>\r\n            <span class=\"na\">v-for=<\/span><span class=\"s\">\"post in posts\"<\/span>\r\n            <span class=\"na\">v-bind:key=<\/span><span class=\"s\">\"post.id\"<\/span>\r\n            <span class=\"na\">:post=<\/span><span class=\"s\">post<\/span>\r\n        <span class=\"nt\">&gt;&lt;\/PostCard&gt;<\/span>\r\n      <span class=\"nt\">&lt;\/v-layout&gt;<\/span>\r\n    <span class=\"nt\">&lt;\/v-container&gt;<\/span>\r\n  <span class=\"nt\">&lt;\/v-app&gt;<\/span>\r\n<span class=\"nt\">&lt;\/<\/span><span class=\"k\">template<\/span><span class=\"nt\">&gt;<\/span>\r\n\r\n<span class=\"nt\">&lt;<\/span><span class=\"k\">script<\/span><span class=\"nt\">&gt;<\/span>\r\n  <span class=\"k\">import<\/span> <span class=\"nx\">PostCard<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">.\/components\/PostCard<\/span><span class=\"dl\">'<\/span>\r\n\r\n  <span class=\"k\">export<\/span> <span class=\"k\">default<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"na\">name<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">App<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"na\">components<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n      <span class=\"nx\">PostCard<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"p\">},<\/span>\r\n    <span class=\"na\">data<\/span><span class=\"p\">:<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">({<\/span>\r\n      <span class=\"na\">posts<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span>\r\n        <span class=\"p\">{<\/span>\r\n          <span class=\"na\">id<\/span><span class=\"p\">:<\/span> <span class=\"mi\">1<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"na\">createdAt<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">2018\/09\/23<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"na\">title<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">sample post<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"na\">description<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">sample post description<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"na\">contents<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">sample post contents<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"na\">thumbnail<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n            <span class=\"na\">url<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">https:\/\/picsum.photos\/800\/400?image=80<\/span><span class=\"dl\">\"<\/span>\r\n          <span class=\"p\">}<\/span>\r\n        <span class=\"p\">},<\/span>\r\n        <span class=\"p\">{<\/span>\r\n          <span class=\"na\">id<\/span><span class=\"p\">:<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"na\">createdAt<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">2018\/09\/24<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"na\">title<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">sample post2<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"na\">description<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">sample post description2<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"na\">contents<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">sample post contents2<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"na\">thumbnail<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n            <span class=\"na\">url<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">https:\/\/picsum.photos\/800\/400?image=90<\/span><span class=\"dl\">\"<\/span>\r\n          <span class=\"p\">}<\/span>\r\n        <span class=\"p\">},<\/span>\r\n        <span class=\"p\">{<\/span>\r\n          <span class=\"na\">id<\/span><span class=\"p\">:<\/span> <span class=\"mi\">3<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"na\">createdAt<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">2018\/09\/24<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"na\">title<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">sample post3<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"na\">description<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">sample post description3<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"na\">contents<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">sample post contents3<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"na\">thumbnail<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n            <span class=\"na\">url<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">https:\/\/picsum.photos\/800\/400?image=100<\/span><span class=\"dl\">\"<\/span>\r\n          <span class=\"p\">}<\/span>\r\n        <span class=\"p\">},<\/span>\r\n      <span class=\"p\">]<\/span>\r\n    <span class=\"p\">})<\/span>\r\n  <span class=\"p\">}<\/span>\r\n<span class=\"nt\">&lt;\/<\/span><span class=\"k\">script<\/span><span class=\"nt\">&gt;<\/span>\r\n\r\n<\/code><\/pre>\n<p>\u5982\u679c\u60a8\u5728\u8fd9\u4e2a\u9636\u6bb5\u6267\u884c&#8221;yarn serve&#8221;\u7684\u547d\u4ee4\u5e76\u4e14\u663e\u793a\u5982\u4e0b\u5185\u5bb9\uff0c\u90a3\u5c31\u53ef\u4ee5\u4e86\u3002<br \/>\n\u4e4b\u540e\uff0c\u6211\u4eec\u5c06\u6839\u636e\u8fd9\u4e2a\u7ec4\u4ef6\u8fdb\u884c\u6570\u636e\u7684\u6dfb\u52a0\u7b49\u64cd\u4f5c\u3002<\/p>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d83d2913a08637a6b454b\/64-0.png\" alt=\"\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8 2018-09-23 8.05.12.png\" \/><\/div>\n<h2>\u5728\u4e2d\u56fd\uff0c\u6dfb\u52a0API\u5ba2\u6237\u7aefApollo<\/h2>\n<p>Apollo\u662f\u4e00\u4e2aGraphQL\u5ba2\u6237\u7aef\u5e93\u3002<br \/>\n\u6211\u4eec\u5c06\u4f7f\u7528Apollo\u4eceHeadlessCMS\u83b7\u53d6\u6570\u636e\u6765\u5c1d\u8bd5\u4e00\u4e0b\u3002<\/p>\n<h3>\u5b89\u88c5\u548c\u914d\u7f6evue-apollo\u3002<\/h3>\n<p>\u5b89\u88c5\u4f7f\u7528Vue CLI\u3002<br \/>\n\u5176\u4ed6\u5b89\u88c5\u65b9\u6cd5\u8bf7\u53c2\u8003\u8fd9\u91cc\u7684\u8bf4\u660e\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nv\">$ <\/span> vue add apollo       \r\n<\/code><\/pre>\n<p>\u6240\u6709\u9009\u9879\u90fd\u53ef\u4ee5\u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u3002<br \/>\nvue-apollo.js\u914d\u7f6e\u6587\u4ef6\u4f1a\u81ea\u52a8\u521b\u5efa\u5728src\/\u4e0b\uff0c<br \/>\n\u5e76\u4e14\u4f1a\u5728main.js\u4e2d\u6dfb\u52a0\u52a0\u8f7d\u914d\u7f6e\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">import<\/span> <span class=\"nx\">Vue<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">vue<\/span><span class=\"dl\">'<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nx\">VueApollo<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">vue-apollo<\/span><span class=\"dl\">'<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">createApolloClient<\/span><span class=\"p\">,<\/span> <span class=\"nx\">restartWebsockets<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">vue-cli-plugin-apollo\/graphql-client<\/span><span class=\"dl\">'<\/span>\r\n\r\n<span class=\"c1\">\/\/ Install the vue plugin<\/span>\r\n<span class=\"nx\">Vue<\/span><span class=\"p\">.<\/span><span class=\"nx\">use<\/span><span class=\"p\">(<\/span><span class=\"nx\">VueApollo<\/span><span class=\"p\">)<\/span>\r\n\r\n<span class=\"c1\">\/\/ Name of the localStorage item<\/span>\r\n<span class=\"kd\">const<\/span> <span class=\"nx\">AUTH_TOKEN<\/span> <span class=\"o\">=<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">apollo-token<\/span><span class=\"dl\">'<\/span>\r\n\r\n<span class=\"c1\">\/\/ Http endpoint<\/span>\r\n<span class=\"kd\">const<\/span> <span class=\"nx\">httpEndpoint<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">process<\/span><span class=\"p\">.<\/span><span class=\"nx\">env<\/span><span class=\"p\">.<\/span><span class=\"nx\">VUE_APP_GRAPHQL_HTTP<\/span> <span class=\"o\">||<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">http:\/\/localhost:4000\/graphql<\/span><span class=\"dl\">'<\/span>\r\n\r\n<span class=\"c1\">\/\/ Config<\/span>\r\n<span class=\"kd\">const<\/span> <span class=\"nx\">defaultOptions<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"c1\">\/\/ You can use `https` for secure connection (recommended in production)<\/span>\r\n  <span class=\"nx\">httpEndpoint<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"c1\">\/\/ You can use `wss` for secure connection (recommended in production)<\/span>\r\n  <span class=\"c1\">\/\/ Use `null` to disable subscriptions<\/span>\r\n  <span class=\"na\">wsEndpoint<\/span><span class=\"p\">:<\/span> <span class=\"nx\">process<\/span><span class=\"p\">.<\/span><span class=\"nx\">env<\/span><span class=\"p\">.<\/span><span class=\"nx\">VUE_APP_GRAPHQL_WS<\/span> <span class=\"o\">||<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">ws:\/\/localhost:4000\/graphql<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"c1\">\/\/ LocalStorage token<\/span>\r\n  <span class=\"na\">tokenName<\/span><span class=\"p\">:<\/span> <span class=\"nx\">AUTH_TOKEN<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"c1\">\/\/ Enable Automatic Query persisting with Apollo Engine<\/span>\r\n  <span class=\"na\">persisting<\/span><span class=\"p\">:<\/span> <span class=\"kc\">false<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"c1\">\/\/ Use websockets for everything (no HTTP)<\/span>\r\n  <span class=\"c1\">\/\/ You need to pass a `wsEndpoint` for this to work<\/span>\r\n  <span class=\"na\">websocketsOnly<\/span><span class=\"p\">:<\/span> <span class=\"kc\">false<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"c1\">\/\/ Is being rendered on the server?<\/span>\r\n  <span class=\"na\">ssr<\/span><span class=\"p\">:<\/span> <span class=\"kc\">false<\/span><span class=\"p\">,<\/span>\r\n<span class=\"p\">.<\/span>\r\n<span class=\"p\">.<\/span>\r\n<span class=\"p\">.<\/span>\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code><span class=\"p\">import '@babel\/polyfill'\r\nimport Vue from 'vue'\r\nimport '.\/plugins\/vuetify'\r\nimport App from '.\/App.vue'\r\n<\/span><span class=\"gi\">+ import { createProvider } from '.\/vue-apollo'\r\n<\/span>\r\nVue.config.productionTip = false\r\n\r\nnew Vue({\r\n<span class=\"gi\">+  apolloProvider: createProvider(),\r\n<\/span>  render: h =&gt; h(App)\r\n<span class=\"err\">}).$mount('#app')<\/span>\r\n<\/code><\/pre>\n<p>\u6dfb\u52a0\u8bbe\u7f6e\u7aef\u70b9\u3002<br \/>\n\u5982\u679c\u67e5\u770bsrc\/vue-apollo.js\u6587\u4ef6\u7684\u7aef\u70b9\u8bbe\u7f6e\u680f\uff0c<\/p>\n<pre class=\"post-pre\"><code><span class=\"c1\">\/\/ Http endpoint<\/span>\r\n<span class=\"kd\">const<\/span> <span class=\"nx\">httpEndpoint<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">process<\/span><span class=\"p\">.<\/span><span class=\"nx\">env<\/span><span class=\"p\">.<\/span><span class=\"nx\">VUE_APP_GRAPHQL_HTTP<\/span> <span class=\"o\">||<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">http:\/\/localhost:4000\/graphql<\/span><span class=\"dl\">'<\/span>\r\n<\/code><\/pre>\n<p>\u8fd9\u662f\u901a\u8fc7\u53c2\u8003\u73af\u5883\u53d8\u91cfVUE_APP_GRAPHQL_HTTP\u4f5c\u4e3a\u7aef\u70b9\u8fdb\u884c\u914d\u7f6e\u7684\u610f\u601d\uff0c\u5982\u679c\u6ca1\u6709\u8bbe\u7f6e\uff0c\u5219\u5c06\u5176\u8bbe\u7f6e\u4e3a&#8217;http:\/\/localhost:4000\/graphql&#8217;\u3002\u56e0\u6b64\uff0c\u8bf7\u5728vue cli\u7684\u73af\u5883\u53d8\u91cf\u4e2d\u6dfb\u52a0VUE_APP_GRAPHQL_HTTP\uff0c\u5e76\u5728\u90a3\u91cc\u8bbe\u7f6eGraphCMS\u7684\u7aef\u70b9URL\u3002\u53e6\u5916\uff0c\u7531\u4e8e\u4e0d\u4f7f\u7528wsEndpoint\uff0c\u5c06\u5176\u8bbe\u7f6e\u4e3anull\u3002\u6709\u5173\u73af\u5883\u53d8\u91cf\u7684\u914d\u7f6e\uff0c\u8bf7\u53c2\u9605vue cli 3\u6587\u6863\u4e2d\u7684\u6b64\u5904\u3002<\/p>\n<p>\u521b\u5efa.env\u6587\u4ef6<\/p>\n<pre class=\"post-pre\"><code><span class=\"c\"># \u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u30eb\u30fc\u30c8\u3067\u3001\u3001<\/span>\r\n<span class=\"nv\">$ <\/span>vi .env\r\n<\/code><\/pre>\n<p>\u8bf7\u5411.env\u6587\u4ef6\u4e2d\u6dfb\u52a0\u4ee5\u4e0b\u5185\u5bb9\u3002graphCMS\u7684\u7ec8\u7aef\u70b9\u8bf7\u4f7f\u7528\u4e4b\u524d\u63d0\u53ca\u7684\u8bbe\u7f6e\u4e2d\u7684\u5185\u5bb9\u8fdb\u884c\u590d\u5236\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"n\">VUE_APP_GRAPHQL_HTTP<\/span>=<span class=\"n\">https<\/span>:\/\/<span class=\"n\">api<\/span>-<span class=\"n\">apeast<\/span>.<span class=\"n\">graphcms<\/span>.<span class=\"n\">com<\/span>\/<span class=\"n\">xxxxxxxxx<\/span>\/<span class=\"n\">master<\/span>\r\n<\/code><\/pre>\n<p>\u5e76\u4e14\u7531\u4e8e\u672c\u6b21\u4e0d\u4f7f\u7528wss\uff0c\u6240\u4ee5\u4e0b\u9762\u7684\u9009\u9879\u8bf7\u5220\u9664apollo.js\u6240\u5177\u6709\u7684\u4ee5\u4e0b\u9009\u9879\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"err\">.<\/span>\r\n.\r\n<span class=\"p\">const defaultOptions = {\r\n<\/span>  \/\/ You can use `https` for secure connection (recommended in production)\r\n  httpEndpoint,\r\n<span class=\"gd\">-  \/\/ You can use `wss` for secure connection (recommended in production)\r\n-  \/\/ Use `null` to disable subscriptions\r\n-  wsEndpoint: process.env.VUE_APP_GRAPHQL_WS || 'ws:\/\/localhost:4000\/graphql',\r\n<\/span>  \/\/ LocalStorage token\r\n  tokenName: AUTH_TOKEN,\r\n<span class=\"err\">.<\/span>\r\n.\r\n<\/code><\/pre>\n<p>\u8fd9\u6837Apollo\u7684\u8bbe\u7f6e\u5c31\u5b8c\u6210\u4e86\u3002<\/p>\n<h3>\u6dfb\u52a0GraphQL<\/h3>\n<p>\u7ec8\u4e8e\u8f6e\u5230GraphQL\u51fa\u573a\u4e86\u3002\u4ece\u8fd9\u91cc\u5f00\u59cb\uff0c\u6211\u4eec\u5c06\u7f16\u5199GraphQL\u67e5\u8be2\u3002<br \/>\n\u9996\u5148\uff0c\u662f\u6dfb\u52a0graphql.js\u6587\u4ef6\u6765\u63cf\u8ff0\u67e5\u8be2\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nv\">$ <\/span><span class=\"nb\">mkdir <\/span>src\/constants\r\n<span class=\"nv\">$ <\/span><span class=\"nb\">touch <\/span>src\/constants\/graphql.js\r\n\r\n<\/code><\/pre>\n<p>\u6211\u4f1a\u4f7f\u7528 graphql.js \u6765\u7f16\u5199\u67e5\u8be2\u3002<br \/>\n\u6700\u5f00\u59cb\u662f\u83b7\u53d6\u6240\u6709\u5e16\u5b50\u7684\u64cd\u4f5c\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">import<\/span> <span class=\"nx\">gql<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">graphql-tag<\/span><span class=\"dl\">'<\/span>\r\n\r\n<span class=\"c1\">\/\/ \u3059\u3079\u3066\u306e\u6295\u7a3f\u3092\u53d6\u5f97<\/span>\r\n<span class=\"k\">export<\/span> <span class=\"kd\">const<\/span> <span class=\"nx\">ALL_POSTS<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">gql<\/span><span class=\"s2\">`\r\n    query allPosts {\r\n        posts {\r\n            id\r\n            title\r\n            content\r\n            description\r\n            createdAt\r\n            thumbnail {\r\n                url\r\n            }\r\n        }\r\n    }\r\n`<\/span>\r\n\r\n<\/code><\/pre>\n<p>\u5728App.vue\u4e2d\u52a0\u8f7d\u521b\u5efa\u7684\u67e5\u8be2\u3002<br \/>\n\u7136\u540e\uff0c\u5c06\u5728data\u4e2d\u76f4\u63a5\u5199\u5165\u7684\u90e8\u5206\u66ff\u6362\u4e3aApollo\u7684\u83b7\u53d6\u7ed3\u679c\u3002<br \/>\n\u53ea\u9700\u5728Apollo\u4e2d\u6dfb\u52a0\u5148\u524d\u58f0\u660e\u7684\u67e5\u8be2\u5373\u53ef\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"err\">.<\/span>\r\n.\r\n<span class=\"err\">.<\/span>\r\n\r\n<span class=\"gd\">&lt;script&gt;\r\n<\/span>  import PostCard from '.\/components\/PostCard'\r\n<span class=\"gi\">+ import {ALL_POSTS} from \".\/constants\/graphql\";\r\n<\/span>\r\n  export default {\r\n    name: 'App',\r\n    components: {\r\n      PostCard,\r\n    },\r\n<span class=\"gi\">+    apollo: {\r\n+      posts: ALL_POSTS\r\n+    }\r\n<\/span><span class=\"gd\">-    data: () =&gt; ({\r\n-      posts: [\r\n-        {\r\n-          id: 1,\r\n-          createdAt: \"2018\/09\/23\",\r\n-          title: \"sample post\",\r\n-          description: \"sample post description\",\r\n-          contents: \"sample post contents\",\r\n-          thumbnail: {\r\n-            url: \"https:\/\/picsum.photos\/800\/400?image=80\"\r\n-          }\r\n-        },\r\n-        {\r\n-          id: 2,\r\n-          createdAt: \"2018\/09\/24\",\r\n-          title: \"sample post2\",\r\n-          description: \"sample post description2\",\r\n-          contents: \"sample post contents2\",\r\n-          thumbnail: {\r\n-            url: \"https:\/\/picsum.photos\/800\/400?image=90\"\r\n-          }\r\n-        },\r\n-        {\r\n-          id: 3,\r\n-          createdAt: \"2018\/09\/24\",\r\n-          title: \"sample post3\",\r\n-          description: \"sample post description3\",\r\n-          contents: \"sample post contents3\",\r\n-          thumbnail: {\r\n-            url: \"https:\/\/picsum.photos\/800\/400?image=100\"\r\n-          }\r\n-        },\r\n-      ]\r\n-    })\r\n<\/span>  }\r\n<span class=\"gd\">&lt;\/script&gt;\r\n<\/span>\r\n<\/code><\/pre>\n<p>\u53ea\u8981\u4f7f\u7528 &#8220;yarn serve&#8221; \u547d\u4ee4\u542f\u52a8\uff0c\u5e94\u8be5\u80fd\u591f\u663e\u793a\u5728 GraphCMS \u4e2d\u6dfb\u52a0\u7684\u5e16\u5b50\u6570\u636e\u3002<\/p>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d83d2913a08637a6b454b\/91-0.gif\" alt=\"eoutput2.gif\" \/><\/div>\n<h2>\u6dfb\u52a0\u8def\u7531 vue-router<\/h2>\n<p>\u56e0\u4e3aSPA\uff08\u5355\u9875\u5e94\u7528\uff09\u7684\u9700\u8981\uff0c\u6211\u4eec\u5c06\u5728\u4e00\u89c8\u9875\u9762\u4e0a\u6dfb\u52a0\u5230\u8be6\u7ec6\u9875\u9762\u7684\u8def\u7531\u3002<br \/>\n\u6211\u4eec\u5c06\u4f7f\u7528vue-router\u6765\u5b9e\u73b0\u8def\u7531\u529f\u80fd\u3002<\/p>\n<h3>\u5b89\u88c5\u548c\u8bbe\u7f6e<\/h3>\n<p>\u4e3a\u4e86\u907f\u514d\u4f7f\u7528vue cli\u7684add\u547d\u4ee4\u65f6\u9ed8\u8ba4\u6dfb\u52a0\u6587\u4ef6\u4ee5\u53ca\u81ea\u52a8\u66f4\u6539App.vue\u6587\u4ef6\u5bfc\u81f4\u7684\u9ebb\u70e6\uff0c\u5efa\u8bae\u4f7f\u7528yarn\u6765\u5b89\u88c5vue-router\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nv\">$ <\/span>yarn add vue-router\r\n<\/code><\/pre>\n<p>\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u5c06\u6dfb\u52a0\u8bbe\u7f6e\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nv\">$ <\/span><span class=\"nb\">touch <\/span>src\/router.js\r\n<\/code><\/pre>\n<p>\u5c06\u8def\u7531\u4fe1\u606f\u5728router.js\u6587\u4ef6\u4e2d\u8fdb\u884c\u7f16\u5199\u3002<br \/>\n\u7a0d\u540e\u4f1a\u6dfb\u52a0\u5728\u8fd9\u91cc\u58f0\u660e\u7684PostList.vue\u548cPostDetail.vue\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">import<\/span> <span class=\"nx\">Vue<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">vue<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nx\">VueRouter<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">vue-router<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\r\n\r\n<span class=\"nx\">Vue<\/span><span class=\"p\">.<\/span><span class=\"nx\">use<\/span><span class=\"p\">(<\/span><span class=\"nx\">VueRouter<\/span><span class=\"p\">);<\/span>\r\n\r\n<span class=\"c1\">\/\/ \u30eb\u30fc\u30c6\u30a3\u30f3\u30b0<\/span>\r\n<span class=\"kd\">const<\/span> <span class=\"nx\">routes<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span>\r\n  <span class=\"p\">{<\/span>\r\n    <span class=\"c1\">\/\/ \u8a18\u4e8b\u4e00\u89a7\u30da\u30fc\u30b8<\/span>\r\n    <span class=\"na\">path<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">\/<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"na\">name<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">postList<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"na\">component<\/span><span class=\"p\">:<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"k\">import<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">.\/views\/PostList.vue<\/span><span class=\"dl\">'<\/span><span class=\"p\">)<\/span>\r\n  <span class=\"p\">},<\/span>\r\n  <span class=\"p\">{<\/span>\r\n   <span class=\"c1\">\/\/ \u8a18\u4e8b\u8a73\u7d30\u30da\u30fc\u30b8<\/span>\r\n    <span class=\"na\">path<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">\/post\/:id<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"na\">name<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">postDetail<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"na\">component<\/span><span class=\"p\">:<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"k\">import<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">.\/views\/PostDetail.vue<\/span><span class=\"dl\">'<\/span><span class=\"p\">)<\/span>\r\n  <span class=\"p\">},<\/span>\r\n<span class=\"p\">]<\/span>\r\n\r\n<span class=\"kd\">const<\/span> <span class=\"nx\">router<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nx\">VueRouter<\/span><span class=\"p\">({<\/span>\r\n  <span class=\"na\">routes<\/span><span class=\"p\">:<\/span> <span class=\"nx\">routes<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"na\">base<\/span><span class=\"p\">:<\/span> <span class=\"nx\">process<\/span><span class=\"p\">.<\/span><span class=\"nx\">env<\/span><span class=\"p\">.<\/span><span class=\"nx\">BASE_URL<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"na\">mode<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">history<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"c1\">\/\/ \u30da\u30fc\u30b8\u9077\u79fb\u306e\u969b\u306e\u4f4d\u7f6e\u6307\u5b9a \u6307\u5b9a\u304c\u306a\u3044\u5834\u5408 \u30da\u30fc\u30b8\u30c8\u30c3\u30d7\u3078<\/span>\r\n  <span class=\"nx\">scrollBehavior<\/span><span class=\"p\">(<\/span><span class=\"nx\">to<\/span><span class=\"p\">,<\/span> <span class=\"k\">from<\/span><span class=\"p\">,<\/span> <span class=\"nx\">savedPosition<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">savedPosition<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n      <span class=\"k\">return<\/span> <span class=\"nx\">savedPosition<\/span>\r\n    <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\r\n      <span class=\"k\">return<\/span> <span class=\"p\">{<\/span><span class=\"na\">x<\/span><span class=\"p\">:<\/span> <span class=\"mi\">0<\/span><span class=\"p\">,<\/span> <span class=\"na\">y<\/span><span class=\"p\">:<\/span> <span class=\"mi\">0<\/span><span class=\"p\">}<\/span>\r\n    <span class=\"p\">}<\/span>\r\n  <span class=\"p\">}<\/span>\r\n<span class=\"p\">});<\/span>\r\n\r\n<span class=\"k\">export<\/span> <span class=\"k\">default<\/span> <span class=\"nx\">router<\/span><span class=\"p\">;<\/span>\r\n<\/code><\/pre>\n<p>\u7136\u540e\uff0c\u5728main.js\u4e2d\u6dfb\u52a0\u8bbe\u7f6e\u4ee5\u52a0\u8f7d\u5b83\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"p\">import '@babel\/polyfill'\r\nimport Vue from 'vue'\r\nimport '.\/plugins\/vuetify'\r\nimport App from '.\/App.vue'\r\nimport { createProvider } from '.\/vue-apollo'\r\n<\/span><span class=\"gi\">+ import router from \".\/router\"\r\n<\/span>\r\nVue.config.productionTip = false\r\n\r\nnew Vue({\r\n  apolloProvider: createProvider(),\r\n<span class=\"gi\">+  router,\r\n<\/span>  render: h =&gt; h(App)\r\n<span class=\"err\">}).$mount('#app')<\/span>\r\n\r\n<\/code><\/pre>\n<p>\u6700\u540e\uff0c\u5728App.vue\u7684\u5217\u8868\u9875\u9762\u7ec4\u4ef6\u4e2d\u6dfb\u52a0\u7684\u90e8\u5206\u5c06\u88ab\u66f4\u6539\u4e3avue-router\u7684\u8f6c\u79fb\u6807\u7b7e\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nt\">&lt;<\/span><span class=\"k\">template<\/span><span class=\"nt\">&gt;<\/span>\r\n  <span class=\"nt\">&lt;v-app&gt;<\/span>\r\n    <span class=\"nt\">&lt;transition<\/span> <span class=\"na\">name=<\/span><span class=\"s\">\"fade\"<\/span><span class=\"nt\">&gt;<\/span>\r\n      <span class=\"nt\">&lt;router-view\/&gt;<\/span>\r\n    <span class=\"nt\">&lt;\/transition&gt;<\/span>\r\n  <span class=\"nt\">&lt;\/v-app&gt;<\/span>\r\n<span class=\"nt\">&lt;\/<\/span><span class=\"k\">template<\/span><span class=\"nt\">&gt;<\/span>\r\n\r\n<span class=\"nt\">&lt;<\/span><span class=\"k\">script<\/span><span class=\"nt\">&gt;<\/span>\r\n  <span class=\"k\">export<\/span> <span class=\"k\">default<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"na\">name<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">App<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"p\">}<\/span>\r\n<span class=\"nt\">&lt;\/<\/span><span class=\"k\">script<\/span><span class=\"nt\">&gt;<\/span>\r\n\r\n<\/code><\/pre>\n<p>\u5230\u76ee\u524d\u4e3a\u6b62\uff0c\u8def\u7531\u5668\u7684\u8bbe\u7f6e\u5df2\u7ecf\u5b8c\u6210\u3002<\/p>\n<h3>\u589e\u52a0Vue\u7ec4\u4ef6<\/h3>\n<p>\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u5c06\u8bbe\u7f6e\u9875\u9762\u8df3\u8f6c\u5230vue\u7ec4\u4ef6\u3002<br \/>\n\u6211\u4eec\u5c06\u521b\u5efa\u4e00\u4e2a\u5217\u8868\u9875\u9762\u548c\u4e00\u4e2a\u8be6\u60c5\u9875\u9762\u7684\u7ec4\u4ef6\u3002<\/p>\n<p>\u5c06\u5217\u8868\u9875\u9762\u4eceApp.vue\u79fb\u52a8\u5e76\u521b\u5efa\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nt\">&lt;<\/span><span class=\"k\">template<\/span><span class=\"nt\">&gt;<\/span>\r\n  <span class=\"nt\">&lt;v-container<\/span> <span class=\"na\">grid-list-xl<\/span><span class=\"nt\">&gt;<\/span>\r\n    <span class=\"nt\">&lt;v-layout<\/span> <span class=\"na\">row<\/span> <span class=\"na\">wrap<\/span><span class=\"nt\">&gt;<\/span>\r\n      <span class=\"nt\">&lt;PostCard<\/span>\r\n          <span class=\"na\">v-for=<\/span><span class=\"s\">\"post in posts\"<\/span>\r\n          <span class=\"na\">v-bind:key=<\/span><span class=\"s\">\"post.id\"<\/span>\r\n          <span class=\"na\">:post=<\/span><span class=\"s\">post<\/span>\r\n      <span class=\"nt\">&gt;&lt;\/PostCard&gt;<\/span>\r\n    <span class=\"nt\">&lt;\/v-layout&gt;<\/span>\r\n  <span class=\"nt\">&lt;\/v-container&gt;<\/span>\r\n<span class=\"nt\">&lt;\/<\/span><span class=\"k\">template<\/span><span class=\"nt\">&gt;<\/span>\r\n\r\n<span class=\"nt\">&lt;<\/span><span class=\"k\">script<\/span><span class=\"nt\">&gt;<\/span>\r\n  <span class=\"k\">import<\/span> <span class=\"nx\">PostCard<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">..\/components\/PostCard<\/span><span class=\"dl\">'<\/span>\r\n  <span class=\"k\">import<\/span> <span class=\"p\">{<\/span><span class=\"nx\">ALL_POSTS<\/span><span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">..\/constants\/graphql<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\r\n\r\n  <span class=\"k\">export<\/span> <span class=\"k\">default<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"na\">name<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">PostList<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"na\">components<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n      <span class=\"nx\">PostCard<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"p\">},<\/span>\r\n    <span class=\"na\">data<\/span><span class=\"p\">:<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">({<\/span>\r\n      <span class=\"na\">posts<\/span><span class=\"p\">:<\/span> <span class=\"p\">[],<\/span>\r\n    <span class=\"p\">}),<\/span>\r\n    <span class=\"na\">apollo<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n      <span class=\"na\">posts<\/span><span class=\"p\">:<\/span> <span class=\"nx\">ALL_POSTS<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n  <span class=\"p\">}<\/span>\r\n<span class=\"nt\">&lt;\/<\/span><span class=\"k\">script<\/span><span class=\"nt\">&gt;<\/span>\r\n<\/code><\/pre>\n<p>\u8a73\u7d30\u9801\u9762\u5c07\u6309\u7167\u4ee5\u4e0b\u7d50\u69cb\u9032\u884c\u8a2d\u7f6e\u3002<br \/>\n\u76ee\u524d\uff0cpost\u4ecd\u4ee5\u76f4\u63a5\u7de8\u5bebdata\u7684\u65b9\u5f0f\u9032\u884c\uff0c\u4f46\u7a0d\u5f8c\u5c07\u8f49\u63db\u70ba\u4f7f\u7528apollo\u9032\u884c\u6aa2\u7d22\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nt\">&lt;<\/span><span class=\"k\">template<\/span><span class=\"nt\">&gt;<\/span>\r\n  <span class=\"nt\">&lt;div&gt;<\/span>\r\n    <span class=\"nt\">&lt;section&gt;<\/span>\r\n      <span class=\"nt\">&lt;v-parallax<\/span> <span class=\"na\">:src=<\/span><span class=\"s\">\"post.thumbnail.url\"<\/span> <span class=\"na\">height=<\/span><span class=\"s\">\"600\"<\/span><span class=\"nt\">&gt;<\/span>\r\n        <span class=\"nt\">&lt;v-layout<\/span>\r\n            <span class=\"na\">column<\/span>\r\n            <span class=\"na\">align-center<\/span>\r\n            <span class=\"na\">justify-center<\/span>\r\n            <span class=\"na\">class=<\/span><span class=\"s\">\"white--text\"<\/span>\r\n        <span class=\"nt\">&gt;<\/span>\r\n          <span class=\"nt\">&lt;h1<\/span> <span class=\"na\">class=<\/span><span class=\"s\">\"white--text mb-2 display-2 text-xs-center\"<\/span><span class=\"nt\">&gt;<\/span><span class=\"si\">{{<\/span><span class=\"nx\">post<\/span><span class=\"p\">.<\/span><span class=\"nx\">title<\/span><span class=\"si\">}}<\/span><span class=\"nt\">&lt;\/h1&gt;<\/span>\r\n          <span class=\"nt\">&lt;p<\/span> <span class=\"na\">class=<\/span><span class=\"s\">\"white-text text-xs-center subheading\"<\/span><span class=\"nt\">&gt;<\/span><span class=\"si\">{{<\/span> <span class=\"nx\">post<\/span><span class=\"p\">.<\/span><span class=\"nx\">description<\/span> <span class=\"si\">}}<\/span><span class=\"nt\">&lt;\/p&gt;<\/span>\r\n        <span class=\"nt\">&lt;\/v-layout&gt;<\/span>\r\n      <span class=\"nt\">&lt;\/v-parallax&gt;<\/span>\r\n    <span class=\"nt\">&lt;\/section&gt;<\/span>\r\n    <span class=\"nt\">&lt;v-content&gt;<\/span>\r\n      <span class=\"nt\">&lt;v-container&gt;<\/span>\r\n        <span class=\"nt\">&lt;v-layout<\/span> <span class=\"na\">row<\/span> <span class=\"na\">wrap<\/span> <span class=\"na\">justify-center<\/span><span class=\"nt\">&gt;<\/span>\r\n          <span class=\"nt\">&lt;v-flex<\/span> <span class=\"na\">xs12<\/span> <span class=\"na\">md8<\/span><span class=\"nt\">&gt;<\/span>\r\n            <span class=\"nt\">&lt;p&gt;<\/span><span class=\"si\">{{<\/span> <span class=\"nx\">post<\/span><span class=\"p\">.<\/span><span class=\"nx\">content<\/span> <span class=\"si\">}}<\/span><span class=\"nt\">&lt;\/p&gt;<\/span>\r\n          <span class=\"nt\">&lt;\/v-flex&gt;<\/span>\r\n        <span class=\"nt\">&lt;\/v-layout&gt;<\/span>\r\n      <span class=\"nt\">&lt;\/v-container&gt;<\/span>\r\n    <span class=\"nt\">&lt;\/v-content&gt;<\/span>\r\n  <span class=\"nt\">&lt;\/div&gt;<\/span>\r\n<span class=\"nt\">&lt;\/<\/span><span class=\"k\">template<\/span><span class=\"nt\">&gt;<\/span>\r\n\r\n<span class=\"nt\">&lt;<\/span><span class=\"k\">script<\/span><span class=\"nt\">&gt;<\/span>\r\n\r\n  <span class=\"k\">export<\/span> <span class=\"k\">default<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"na\">name<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">PostDetail<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"na\">data<\/span><span class=\"p\">:<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">({<\/span>\r\n      <span class=\"na\">post<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"na\">title<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">sample title<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n        <span class=\"na\">description<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">sample description<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n        <span class=\"na\">content<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">amet, consectetur adipisicing elit. Culpa debitis dolores eius facilis officiis quo unde velit. Ab accusantium aperiam commodi cupiditate dignissimos eius eum sequi sunt tempore, vero voluptas.Consequuntur deleniti doloremque eius incidunt modi non repellendus sapiente ut vel. Autem neque, ullam. Atque aut eveniet, exercitationem illo illum inventore molestias numquam, optio quas recusandae, repellendus suscipit tenetur vero?Blanditiis consequuntur deserunt dolor ducimus modi necessitatibus, odit placeat quaerat quia saepe sequi unde ut voluptate? Aspernatur consectetur, dignissimos eaque fuga in laborum odit, quibusdam rem rerum sed sit soluta?Aliquam atque deleniti dolorem laborum maxime voluptates? A architecto, corporis earum explicabo fugiat labore porro velit! Adipisci at consequatur, error eveniet, laboriosam minus nemo nihil numquam quisquam rerum sequi temporibus.Deleniti, fuga, quibusdam! Aspernatur commodi cum doloremque esse est eum illo inventore ipsum itaque laborum molestias mollitia nostrum, odio officiis omnis perspiciatis possimus quia quidem recusandae tempore vero voluptate voluptates.<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n        <span class=\"na\">thumbnail<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n          <span class=\"na\">url<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">https:\/\/picsum.photos\/1200\/600?image=90<\/span><span class=\"dl\">\"<\/span>\r\n        <span class=\"p\">}<\/span>\r\n      <span class=\"p\">}<\/span>\r\n    <span class=\"p\">})<\/span>\r\n  <span class=\"p\">}<\/span>\r\n<span class=\"nt\">&lt;\/<\/span><span class=\"k\">script<\/span><span class=\"nt\">&gt;<\/span>\r\n\r\n<span class=\"nt\">&lt;<\/span><span class=\"k\">style<\/span><span class=\"nt\">&gt;<\/span>\r\n  <span class=\"nc\">.v-parallax__image<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"nl\">opacity<\/span><span class=\"p\">:<\/span> <span class=\"m\">1<\/span><span class=\"cp\">!important<\/span><span class=\"p\">;<\/span>\r\n  <span class=\"p\">}<\/span>\r\n<span class=\"nt\">&lt;\/<\/span><span class=\"k\">style<\/span><span class=\"nt\">&gt;<\/span>\r\n\r\n<\/code><\/pre>\n<p>\u8bf7\u663e\u793a\u4e4b\u524d\u7684\u6240\u6709\u9875\u9762\uff0c\u7f51\u5740\u662fhttp:\/\/localhost:8080\/\u3002<br \/>\n\u5982\u679c\u5728\u7f51\u5740http:\/\/localhost:8080\/post\/1\u4e0a\u663e\u793a\u4ee5\u4e0b\u8be6\u7ec6\u4fe1\u606f\uff0c\u90a3\u5c31\u53ef\u4ee5\u4e86\u3002<\/p>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d83d2913a08637a6b454b\/113-0.png\" alt=\"\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8 2018-09-24 0.13.09.png\" \/><\/div>\n<h3>\u4f7f\u7528Apollo\u4ece\u8be6\u7ec6\u9875\u9762\u83b7\u53d6\u6570\u636e\u3002<\/h3>\n<p>\u6211\u5011\u5c07\u4e4b\u524d\u76f4\u63a5\u5beb\u5728\u7d44\u4ef6\u4e2d\u7684post\u6539\u70ba\u4f7f\u7528Apollo\u9032\u884c\u7372\u53d6\u3002<\/p>\n<p>\u9996\u5148\uff0c\u5728graphql.js\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u67e5\u8be2\u51fd\u6570\uff0c\u7528\u4e8e\u901a\u8fc7ID\u83b7\u53d6\u4e00\u7bc7\u6587\u7ae0\u7684\u6570\u636e\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"p\">.<\/span>\r\n<span class=\"p\">.<\/span>\r\n<span class=\"c1\">\/\/ ID\u30671\u4ef6\u53d6\u5f97<\/span>\r\n<span class=\"k\">export<\/span> <span class=\"kd\">const<\/span> <span class=\"nx\">FEACH_POST_BY_ID<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">gql<\/span><span class=\"s2\">`\r\n    query feachPostById($id: ID!) {\r\n        post(where: { id: $id }) {\r\n            title\r\n            content\r\n            description\r\n            createdAt\r\n            thumbnail {\r\n                url\r\n            }\r\n        }\r\n    }\r\n`<\/span>\r\n<\/code><\/pre>\n<p>\u4e0b\u4e00\u6b65\u662f\u5728PostDetail\u4e2d\u52a0\u8f7d\u5b83\u3002<br \/>\n\u5bf9\u4e0b\u8ff0\u5185\u5bb9\u8fdb\u884c\u4fee\u6b63\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nt\">&lt;<\/span><span class=\"k\">script<\/span><span class=\"nt\">&gt;<\/span>\r\n  <span class=\"k\">import<\/span> <span class=\"p\">{<\/span><span class=\"nx\">FEACH_POST_BY_ID<\/span><span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">..\/components\/graphql<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\r\n\r\n  <span class=\"k\">export<\/span> <span class=\"k\">default<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"na\">name<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">PostDetail<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"na\">data<\/span><span class=\"p\">:<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">({<\/span>\r\n      <span class=\"na\">post<\/span><span class=\"p\">:<\/span> <span class=\"p\">[]<\/span> \r\n    <span class=\"p\">}),<\/span>\r\n    <span class=\"na\">apollo<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n      <span class=\"na\">post<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"na\">query<\/span><span class=\"p\">:<\/span> <span class=\"nx\">FEACH_POST_BY_ID<\/span><span class=\"p\">,<\/span>\r\n        <span class=\"nx\">variables<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n          <span class=\"k\">return<\/span> <span class=\"p\">{<\/span>\r\n            <span class=\"na\">id<\/span><span class=\"p\">:<\/span> <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">$route<\/span><span class=\"p\">.<\/span><span class=\"nx\">params<\/span><span class=\"p\">.<\/span><span class=\"nx\">id<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"p\">}<\/span>\r\n        <span class=\"p\">},<\/span>\r\n      <span class=\"p\">}<\/span>\r\n    <span class=\"p\">}<\/span>\r\n  <span class=\"p\">}<\/span>\r\n<span class=\"nt\">&lt;\/<\/span><span class=\"k\">script<\/span><span class=\"nt\">&gt;<\/span>\r\n\r\n<\/code><\/pre>\n<p>\u60a8\u53ef\u4ee5\u4f7f\u7528 apollo.post.variables() \u6765\u8bbe\u7f6e\u8981\u4f20\u9012\u7ed9\u67e5\u8be2\u7684\u53c2\u6570\u3002\u672c\u4f8b\u4e2d\uff0c\u6211\u4eec\u4f7f\u7528 this.$route.params.id \u5c06 Vue Router \u7684 URL \u53c2\u6570\u8bbe\u7f6e\u4e3a id\u3002\u60a8\u53ef\u4ee5\u83b7\u53d6\u5230 localhost:8080\/post\/xxx \u4e2d\u7684 xxx\u3002<\/p>\n<h3>\u5728\u5217\u8868\u4e2d\u6dfb\u52a0\u5230\u8be6\u7ec6\u4fe1\u606f\u7684\u94fe\u63a5\u3002<\/h3>\n<p>\u6211\u4eec\u5c06\u5728\u5217\u8868\u7684\u6700\u540e\u6dfb\u52a0\u4e00\u4e2a\u94fe\u63a5\u5230\u8be6\u7ec6\u4fe1\u606f\u3002\u5728vuetify\u7ec4\u4ef6\u4e2d\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528:to\u6765\u8bbe\u7f6evue-router\u94fe\u63a5\u3002<br \/>\n\u6211\u4eec\u5c06\u5728\u5e16\u5b50\u5361\u7247\u7ec4\u4ef6\u4e2d\u7684\u5217\u8868\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u94fe\u63a5\u3002<\/p>\n<pre class=\"post-pre\"><code>  &lt;v-flex xs12 sm6 md4&gt;\r\n    &lt;article&gt;\r\n      &lt;v-hover&gt;\r\n        &lt;v-card\r\n            slot-scope=\"{ hover }\"\r\n            :class=\"`elevation-${hover ? 12 : 2}`\"\r\n        &gt;\r\n<span class=\"gi\">+          &lt;a v-bind:href=\"'\/post\/' + post.id\"&gt;\r\n<\/span>            &lt;v-img\r\n                class=\"white--text\"\r\n                height=\"170px\"\r\n                :src=post.thumbnail.url\r\n            &gt;\r\n            &lt;\/v-img&gt;\r\n<span class=\"gi\">+          &lt;\/a&gt;\r\n<\/span>          &lt;v-card-title&gt;\r\n            &lt;div&gt;\r\n              &lt;h2&gt;{{ post.title }}&lt;\/h2&gt;\r\n              &lt;span class=\"grey--text\"&gt;{{ post.createdAt | moment }}&lt;\/span&gt;&lt;br&gt;\r\n              &lt;span&gt;{{ post.description }}&lt;\/span&gt;\r\n            &lt;\/div&gt;\r\n          &lt;\/v-card-title&gt;\r\n          &lt;v-card-actions&gt;\r\n            &lt;v-btn icon class=\"red--text\"&gt;\r\n              &lt;v-icon medium&gt;fa-reddit&lt;\/v-icon&gt;\r\n            &lt;\/v-btn&gt;\r\n            &lt;v-btn icon class=\"light-blue--text\"&gt;\r\n              &lt;v-icon medium&gt;fa-twitter&lt;\/v-icon&gt;\r\n            &lt;\/v-btn&gt;\r\n            &lt;v-btn icon class=\"blue--text text--darken-4\"&gt;\r\n              &lt;v-icon medium&gt;fa-facebook&lt;\/v-icon&gt;\r\n            &lt;\/v-btn&gt;\r\n            &lt;v-spacer&gt;&lt;\/v-spacer&gt;\r\n<span class=\"gd\">-            &lt;v-btn flat color=\"blue\"&gt;Read more&lt;\/v-btn&gt;\r\n<\/span><span class=\"gi\">+            &lt;v-btn flat color=\"blue\" :to=\"'\/post\/' + post.id\"&gt;Read more&lt;\/v-btn&gt;\r\n<\/span>          &lt;\/v-card-actions&gt;\r\n        &lt;\/v-card&gt;\r\n      &lt;\/v-hover&gt;\r\n    &lt;\/article&gt;\r\n  &lt;\/v-flex&gt;\r\n<span class=\"gd\">&lt;\/template&gt;\r\n<\/span><\/code><\/pre>\n<p>\u4ee5\u4e0a\u662f\u8def\u7531\u5b8c\u6210\u7684\u90e8\u5206\u3002<br \/>\n\u63a5\u4e0b\u6765\u5e94\u8be5\u80fd\u591f\u6309\u7167\u4ee5\u4e0b\u7684\u65b9\u5f0f\u8fdb\u884c\u5c4f\u5e55\u8df3\u8f6c\u3002<\/p>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d83d2913a08637a6b454b\/125-0.gif\" alt=\"output3.gif\" \/><\/div>\n<p>\u76ee\u524d\u4e3a\u6b62\u524d\u7aef\u90e8\u5206\u5df2\u7ecf\u5b8c\u6210\u3002<br \/>\n\u867d\u7136\u6211\u672c\u6765\u8fd8\u60f3\u5b9e\u73b0\u5206\u9875\u7b49\u529f\u80fd\uff0c\u4f46\u662f\u56e0\u4e3a\u5df2\u7ecf\u53d8\u5f97\u592a\u957f\u4e86\uff0c\u6240\u4ee5\u6211\u60f3\u53e6\u5916\u627e\u4e2a\u673a\u4f1a\u6574\u7406\u4e00\u4e0b\u3002<\/p>\n<h1>\u90e8\u7f72<\/h1>\n<p>\u6700\u540e\uff0c\u65e2\u7136\u5df2\u7ecf\u505a\u597d\u4e86\u8fd9\u4e2a\u9879\u76ee\uff0c\u6211\u4eec\u5c31\u8bd5\u7740\u8fdb\u884c\u5916\u90e8\u516c\u5f00\u5427\u3002<br \/>\n\u901a\u8fc7\u4f7f\u7528Heroku\uff0c\u4f60\u53ef\u4ee5\u8f7b\u677e\u5730\u90e8\u7f72Vue\u9879\u76ee\u3002<\/p>\n<h2>\u8868\u8fbe\u7684\u6dfb\u52a0\u548c\u8bbe\u7f6e<\/h2>\n<p>\u6dfb\u52a0Node.js\u670d\u52a1\u5668\u7aefJavaScript\u7684\u6267\u884c\u73af\u5883expless\u3002<\/p>\n<pre class=\"post-pre\"><code>$ yarn add express\r\n<\/code><\/pre>\n<p>\u7136\u540e\uff0c\u6211\u4eec\u5c06\u670d\u52a1\u5668\u7684\u8bbe\u7f6e\u914d\u7f6e\u6587\u4ef6server.js\u6dfb\u52a0\u5230\u9879\u76ee\u6839\u76ee\u5f55\u4e2d\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nv\">$ <\/span>vi server.js\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">express<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">require<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">express<\/span><span class=\"dl\">'<\/span><span class=\"p\">);<\/span>\r\n<span class=\"kd\">const<\/span> <span class=\"nx\">port<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">process<\/span><span class=\"p\">.<\/span><span class=\"nx\">env<\/span><span class=\"p\">.<\/span><span class=\"nx\">PORT<\/span> <span class=\"o\">||<\/span> <span class=\"mi\">5000<\/span><span class=\"p\">;<\/span>\r\n<span class=\"kd\">const<\/span> <span class=\"nx\">app<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">express<\/span><span class=\"p\">();<\/span>\r\n<span class=\"nx\">app<\/span><span class=\"p\">.<\/span><span class=\"nx\">use<\/span><span class=\"p\">(<\/span><span class=\"nx\">express<\/span><span class=\"p\">.<\/span><span class=\"kd\">static<\/span><span class=\"p\">(<\/span><span class=\"nx\">__dirname<\/span> <span class=\"o\">+<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">\/dist\/<\/span><span class=\"dl\">\"<\/span><span class=\"p\">));<\/span>\r\n\r\n<span class=\"nx\">app<\/span><span class=\"p\">.<\/span><span class=\"kd\">get<\/span><span class=\"p\">(<\/span><span class=\"sr\">\/.*\/<\/span><span class=\"p\">,<\/span> <span class=\"kd\">function<\/span><span class=\"p\">(<\/span><span class=\"nx\">req<\/span><span class=\"p\">,<\/span> <span class=\"nx\">res<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"nx\">res<\/span><span class=\"p\">.<\/span><span class=\"nx\">sendfile<\/span><span class=\"p\">(<\/span><span class=\"nx\">__dirname<\/span> <span class=\"o\">+<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">\/dist\/index.html<\/span><span class=\"dl\">\"<\/span><span class=\"p\">);<\/span>\r\n<span class=\"p\">});<\/span>\r\n\r\n<span class=\"nx\">app<\/span><span class=\"p\">.<\/span><span class=\"nx\">listen<\/span><span class=\"p\">(<\/span><span class=\"nx\">port<\/span><span class=\"p\">);<\/span>\r\n\r\n<\/code><\/pre>\n<p>\u5173\u4e8eserver.js\u7684\u7f16\u5199\u65b9\u5f0f\uff0c\u6211\u53c2\u8003\u4e86\u4ee5\u4e0b\u5185\u5bb9\u3002\u5c06Vue Cli 3\u9879\u76ee\u90e8\u7f72\u5230Heroku\u4e0a\u3002<\/p>\n<p>\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u9700\u8981\u5728package.json\u4e2d\u6dfb\u52a0\u670d\u52a1\u5668\u542f\u52a8\u547d\u4ee4\u7b49\u3002<\/p>\n<pre class=\"post-pre\"><code>  \"name\": \"sample-blog\",\r\n  \"version\": \"0.1.0\",\r\n  \"private\": true,\r\n  \"scripts\": {\r\n    \"serve\": \"vue-cli-service serve\",\r\n    \"build\": \"vue-cli-service build\",\r\n    \"lint\": \"vue-cli-service lint\",\r\n<span class=\"gi\">+    \"postinstall\": \"yarn build\",\r\n+    \"start\": \"node server.js\"\r\n<\/span>  },\r\n<span class=\"err\">.<\/span>\r\n.\r\n<span class=\"err\">.<\/span>\r\n<\/code><\/pre>\n<p>\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c<\/p>\n<pre class=\"post-pre\"><code><span class=\"nv\">$ <\/span>yarn start\r\n<\/code><\/pre>\n<p>\u5982\u679c\u6ca1\u6709\u9519\u8bef\uff0c\u5219\u670d\u52a1\u5668\u4f1a\u542f\u52a8\uff0c\u5e76\u901a\u8fc7\u8bbf\u95ee http:\/\/localhost:5000\/ \u6765\u663e\u793a\u5217\u8868\u9875\u9762\uff0c\u8fd9\u6837\u670d\u52a1\u5668\u7684\u8bbe\u7f6e\u5c31\u5b8c\u6210\u4e86\u3002<\/p>\n<h2>\u5c06heloku\u90e8\u7f72<\/h2>\n<p>\u5047\u8bbe\u5df2\u7ecf\u5b8c\u6210\u4e86Heloku\u547d\u4ee4\u884c\u5de5\u5177\u7684\u8bbe\u7f6e\uff0c\u7ee7\u7eed\u8fdb\u884c\u3002<\/p>\n<p>Heroku\u4f7f\u7528Git\u6765\u8fdb\u884c\u90e8\u7f72\u3002<br \/>\n\u9996\u5148\uff0c\u6211\u4eec\u9700\u8981\u7f16\u8f91.gitignore\u6587\u4ef6\uff0c\u4ee5\u4fbf\u5c06dist\/\u76ee\u5f55\u4e0b\u7684\u53ef\u6267\u884c\u6587\u4ef6\u7eb3\u5165\u7248\u672c\u63a7\u5236\u3002<\/p>\n<pre class=\"post-pre\"><code>$ vi .gitignore\r\n<\/code><\/pre>\n<p>\u8ba9\u6211\u4eec\u6ce8\u91ca\u6216\u5220\u9664\/dist\u7684\u90e8\u5206\u3002<\/p>\n<pre class=\"post-pre\"><code># \/dist\r\n<\/code><\/pre>\n<p>\u63a5\u4e0b\u6765\u8fdb\u884cgit\u7684\u521d\u59cb\u5316\u3001\u6682\u5b58\u548c\u63d0\u4ea4commit\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nv\">$ <\/span>git init\r\n<span class=\"nv\">$ <\/span>git add <span class=\"nb\">.<\/span>\r\n<span class=\"nv\">$ <\/span>git commit <span class=\"nt\">-m<\/span> <span class=\"s2\">\"init for heroku\"<\/span>\r\n<\/code><\/pre>\n<p>\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u5c06\u521b\u5efa\u4e00\u4e2aHeroku\u9879\u76ee\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nv\">$ <\/span>heroku create graphcms-sampleblog   \r\n<span class=\"c\"># graphcms-sampleblog\u306e\u90e8\u5206\u304curl\u306e\u4e00\u90e8\u3068\u306a\u308a\u307e\u3059\u3002\u65e2\u5b58\u3068\u88ab\u308b\u3068\u4f7f\u3048\u306a\u3044\u306e\u3067\u6ce8\u610f<\/span>\r\n<\/code><\/pre>\n<p>\u5e76\u4e14\uff0c\u5c06\u5176\u90e8\u7f72\u5230Heroku\u4e0a\u3002<br \/>\n\u53ea\u9700\u4e00\u6761\u547d\u4ee4\uff0c\u5373\u53ef\u5b8c\u6210\u90e8\u7f72\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nv\">$ <\/span>git push heroku master\r\n<\/code><\/pre>\n<p>\u8ba9\u6211\u4eec\u7acb\u523b\u53bb\u6d4f\u89c8\u7f51\u7ad9\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nv\">$ <\/span>heroku open\r\n<\/code><\/pre>\n<p>\u5982\u679c\u5728 https:\/\/\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u540d.herokuapp.com\/ \u4e0a\u80fd\u591f\u6b63\u5e38\u5728\u6d4f\u89c8\u5668\u4e2d\u663e\u793a\uff0c\u90a3\u5c31\u8868\u793a\u90e8\u7f72\u5b8c\u6210\u4e86\u3002<br \/>\n\u53e6\u5916\uff0c\u5982\u679c\u60f3\u5728\u793a\u4f8b\u4e2d\u6dfb\u52a0vuetify\u7684\u5bfc\u822a\u680f\u548c\u9875\u811a\u7b49\uff0c\u5c31\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u6f14\u793a\u7f51\u7ad9\u3002<\/p>\n<h1>\u5370\u8c61<\/h1>\n<p>\u54ce\u5440\uff0cVue.js\u771f\u597d\u73a9\u3002\u901f\u5ea6\u611f\u5b8c\u5168\u4e0d\u540c\u3002GraphQL\u592a\u5389\u5bb3\u4e86\u3002\u67e5\u8be2\u975e\u5e38\u6613\u61c2\u3002<br \/>\n\u6211\u771f\u7684\u89c9\u5f97\u7f16\u7801\u3001\u8bbe\u8ba1\u3001\u90e8\u7f72\u3001\u53d1\u5e03\u7684\u5faa\u73af\u771f\u7684\u5f88\u5feb\u3002<br \/>\n\u771f\u7684\u975e\u5e38\u611f\u8c22\u90a3\u4e9b\u521b\u9020\u4e86\u8fd9\u4e48\u68d2\u7684\u5f00\u6e90\u8f6f\u4ef6\u7684\u524d\u8f88\u4eec\u3002<\/p>\n<p>\u5e0c\u671b\u5728\u63a5\u4e0b\u6765\u7684\u6587\u7ae0\u4e2d\u5c06\u65e0\u6cd5\u89e3\u91ca\u7684\u5206\u9875\u548cCRUD\uff08\u6dfb\u52a0\u3001\u7f16\u8f91\u3001\u5220\u9664\u6587\u7ae0\uff09\u5185\u5bb9\u516c\u5f00\u3002\u5982\u679c\u53d1\u73b0\u62fc\u5199\u9519\u8bef\u6216\u8005\u4e0d\u63a8\u8350\u7684\u5199\u6cd5\uff0c\u8bf7\u901a\u8fc7\u7f16\u8f91\u8bf7\u6c42\u6216\u8bc4\u8bba\u544a\u77e5\uff0c\u4e0d\u80dc\u611f\u6fc0\u3002<\/p>\n<h1>\u8ffd\u52a0\u8bb0\u5f55<\/h1>\n<p>\u6211\u6dfb\u52a0\u4e86\u6709\u5173\u5b9e\u73b0\u5206\u9875\u7684\u6587\u7ae0\u3002<br \/>\n\u5c1d\u8bd5\u4f7f\u7528vue-apollo + vuetify\u5b9e\u73b0\u5206\u9875\uff08\u5b58\u5728\u95ee\u9898\uff09\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u6211\u5e0c\u671b\u5b66\u4e60\u4e00\u4e9b\u65b0\u6280\u672f\uff0c\u4e8e\u662f\u6211\u7528HeadLessCMS + GraphQL + Vue.js\u521b\u5efa\u4e86\u4e00\u4e2a\u7b80\u5355\u7684SP [&hellip;]<\/p>\n","protected":false},"author":7,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-48227","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v21.5 (Yoast SEO v21.5) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>\u5c1d\u8bd5\u4f7f\u7528HeadLessCMS + GraphQL + Vue.js\u6765\u521b\u5efaSPA (\u535a\u5ba2) - Blog - Silicon Cloud<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.silicloud.com\/zh\/blog\/\u5c1d\u8bd5\u4f7f\u7528headlesscms-graphql-vue-js\u6765\u521b\u5efaspa-\u535a\u5ba2\/\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u5c1d\u8bd5\u4f7f\u7528HeadLessCMS + GraphQL + Vue.js\u6765\u521b\u5efaSPA (\u535a\u5ba2)\" \/>\n<meta property=\"og:description\" content=\"\u6211\u5e0c\u671b\u5b66\u4e60\u4e00\u4e9b\u65b0\u6280\u672f\uff0c\u4e8e\u662f\u6211\u7528HeadLessCMS + GraphQL + Vue.js\u521b\u5efa\u4e86\u4e00\u4e2a\u7b80\u5355\u7684SP [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.silicloud.com\/zh\/blog\/\u5c1d\u8bd5\u4f7f\u7528headlesscms-graphql-vue-js\u6765\u521b\u5efaspa-\u535a\u5ba2\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog - Silicon Cloud\" \/>\n<meta property=\"article:published_time\" content=\"2023-10-24T03:40:33+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-04-29T01:08:27+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d83d2913a08637a6b454b\/6-0.gif\" \/>\n<meta name=\"author\" content=\"\u79d1, \u9896\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"\u79d1, \u9896\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8headlesscms-graphql-vue-js%e6%9d%a5%e5%88%9b%e5%bb%baspa-%e5%8d%9a%e5%ae%a2\/\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8headlesscms-graphql-vue-js%e6%9d%a5%e5%88%9b%e5%bb%baspa-%e5%8d%9a%e5%ae%a2\/\",\"name\":\"\u5c1d\u8bd5\u4f7f\u7528HeadLessCMS + GraphQL + Vue.js\u6765\u521b\u5efaSPA (\u535a\u5ba2) - Blog - Silicon Cloud\",\"isPartOf\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\"},\"datePublished\":\"2023-10-24T03:40:33+00:00\",\"dateModified\":\"2024-04-29T01:08:27+00:00\",\"author\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/8ca01ba7f7362ad4edb7da206a12f29e\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8headlesscms-graphql-vue-js%e6%9d%a5%e5%88%9b%e5%bb%baspa-%e5%8d%9a%e5%ae%a2\/#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8headlesscms-graphql-vue-js%e6%9d%a5%e5%88%9b%e5%bb%baspa-%e5%8d%9a%e5%ae%a2\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8headlesscms-graphql-vue-js%e6%9d%a5%e5%88%9b%e5%bb%baspa-%e5%8d%9a%e5%ae%a2\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.silicloud.com\/zh\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u5c1d\u8bd5\u4f7f\u7528HeadLessCMS + GraphQL + Vue.js\u6765\u521b\u5efaSPA (\u535a\u5ba2)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/\",\"name\":\"Blog - Silicon Cloud\",\"description\":\"\",\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/8ca01ba7f7362ad4edb7da206a12f29e\",\"name\":\"\u79d1, \u9896\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/8a6fb3cc7ba2f69d2189ba532aec4633ea7ed75ac0af162ec367cb3abc0fb2af?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/8a6fb3cc7ba2f69d2189ba532aec4633ea7ed75ac0af162ec367cb3abc0fb2af?s=96&d=mm&r=g\",\"caption\":\"\u79d1, \u9896\"},\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/author\/keying\/\"},{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8headlesscms-graphql-vue-js%e6%9d%a5%e5%88%9b%e5%bb%baspa-%e5%8d%9a%e5%ae%a2\/#local-main-organization-logo\",\"url\":\"\",\"contentUrl\":\"\",\"caption\":\"Blog - Silicon Cloud\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"\u5c1d\u8bd5\u4f7f\u7528HeadLessCMS + GraphQL + Vue.js\u6765\u521b\u5efaSPA (\u535a\u5ba2) - Blog - Silicon Cloud","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.silicloud.com\/zh\/blog\/\u5c1d\u8bd5\u4f7f\u7528headlesscms-graphql-vue-js\u6765\u521b\u5efaspa-\u535a\u5ba2\/","og_locale":"zh_CN","og_type":"article","og_title":"\u5c1d\u8bd5\u4f7f\u7528HeadLessCMS + GraphQL + Vue.js\u6765\u521b\u5efaSPA (\u535a\u5ba2)","og_description":"\u6211\u5e0c\u671b\u5b66\u4e60\u4e00\u4e9b\u65b0\u6280\u672f\uff0c\u4e8e\u662f\u6211\u7528HeadLessCMS + GraphQL + Vue.js\u521b\u5efa\u4e86\u4e00\u4e2a\u7b80\u5355\u7684SP [&hellip;]","og_url":"https:\/\/www.silicloud.com\/zh\/blog\/\u5c1d\u8bd5\u4f7f\u7528headlesscms-graphql-vue-js\u6765\u521b\u5efaspa-\u535a\u5ba2\/","og_site_name":"Blog - Silicon Cloud","article_published_time":"2023-10-24T03:40:33+00:00","article_modified_time":"2024-04-29T01:08:27+00:00","og_image":[{"url":"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d83d2913a08637a6b454b\/6-0.gif"}],"author":"\u79d1, \u9896","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"\u79d1, \u9896","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"10 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8headlesscms-graphql-vue-js%e6%9d%a5%e5%88%9b%e5%bb%baspa-%e5%8d%9a%e5%ae%a2\/","url":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8headlesscms-graphql-vue-js%e6%9d%a5%e5%88%9b%e5%bb%baspa-%e5%8d%9a%e5%ae%a2\/","name":"\u5c1d\u8bd5\u4f7f\u7528HeadLessCMS + GraphQL + Vue.js\u6765\u521b\u5efaSPA (\u535a\u5ba2) - Blog - Silicon Cloud","isPartOf":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website"},"datePublished":"2023-10-24T03:40:33+00:00","dateModified":"2024-04-29T01:08:27+00:00","author":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/8ca01ba7f7362ad4edb7da206a12f29e"},"breadcrumb":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8headlesscms-graphql-vue-js%e6%9d%a5%e5%88%9b%e5%bb%baspa-%e5%8d%9a%e5%ae%a2\/#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8headlesscms-graphql-vue-js%e6%9d%a5%e5%88%9b%e5%bb%baspa-%e5%8d%9a%e5%ae%a2\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8headlesscms-graphql-vue-js%e6%9d%a5%e5%88%9b%e5%bb%baspa-%e5%8d%9a%e5%ae%a2\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.silicloud.com\/zh\/blog\/"},{"@type":"ListItem","position":2,"name":"\u5c1d\u8bd5\u4f7f\u7528HeadLessCMS + GraphQL + Vue.js\u6765\u521b\u5efaSPA (\u535a\u5ba2)"}]},{"@type":"WebSite","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website","url":"https:\/\/www.silicloud.com\/zh\/blog\/","name":"Blog - Silicon Cloud","description":"","inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/8ca01ba7f7362ad4edb7da206a12f29e","name":"\u79d1, \u9896","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/8a6fb3cc7ba2f69d2189ba532aec4633ea7ed75ac0af162ec367cb3abc0fb2af?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/8a6fb3cc7ba2f69d2189ba532aec4633ea7ed75ac0af162ec367cb3abc0fb2af?s=96&d=mm&r=g","caption":"\u79d1, \u9896"},"url":"https:\/\/www.silicloud.com\/zh\/blog\/author\/keying\/"},{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8headlesscms-graphql-vue-js%e6%9d%a5%e5%88%9b%e5%bb%baspa-%e5%8d%9a%e5%ae%a2\/#local-main-organization-logo","url":"","contentUrl":"","caption":"Blog - Silicon Cloud"}]}},"_links":{"self":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/48227","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/comments?post=48227"}],"version-history":[{"count":2,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/48227\/revisions"}],"predecessor-version":[{"id":84347,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/48227\/revisions\/84347"}],"wp:attachment":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/media?parent=48227"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/categories?post=48227"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/tags?post=48227"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}