[{"data":1,"prerenderedAt":701},["ShallowReactive",2],{"docs-guides\u002Ffrontend-vue-zh":3},{"id":4,"title":5,"body":6,"description":694,"extension":695,"meta":696,"navigation":218,"path":697,"seo":698,"stem":699,"__hash__":700},"docs\u002Fzh\u002Fguides\u002Ffrontend-vue.md","Vue 前端接入指南",{"type":7,"value":8,"toc":685},"minimark",[9,13,22,26,42,45,48,76,79,113,117,120,359,546,550,557,615,627,630,662,668,671,681],[10,11,5],"h1",{"id":12},"vue-前端接入指南",[14,15,16,17,21],"p",{},"本指南说明如何在 Vue 应用中接入 ",[18,19,20],"code",{},"braid\u002Fruntime\u002Fvue","。",[23,24,25],"h2",{"id":25},"前置条件",[27,28,29,33,39],"ul",{},[30,31,32],"li",{},"已有 Vue 3 应用",[30,34,35,36],{},"组件库提供 ",[18,37,38],{},"braid.manifest.json",[30,40,41],{},"你能拿到 manifest 中每个组件名对应的 Vue 组件实现",[23,43,44],{"id":44},"安装",[14,46,47],{},"前端接入必须使用官方 npm 运行时，不要自行实现 Braid runtime：",[49,50,55],"pre",{"className":51,"code":52,"language":53,"meta":54,"style":54},"language-bash shiki shiki-themes one-dark-pro","npm install @qingjin\u002Fbraid vue\n","bash","",[18,56,57],{"__ignoreMap":54},[58,59,62,66,70,73],"span",{"class":60,"line":61},"line",1,[58,63,65],{"class":64},"sVbv2","npm",[58,67,69],{"class":68},"subq3"," install",[58,71,72],{"class":68}," @qingjin\u002Fbraid",[58,74,75],{"class":68}," vue\n",[23,77,78],{"id":78},"接入步骤",[80,81,82,89,95,106],"ol",{},[30,83,84,85,88],{},"使用 Vue 标准 ",[18,86,87],{},"app.component()"," 全局注册组件库。",[30,90,91,92,21],{},"安装 Braid 插件 ",[18,93,94],{},"createBraidPlugin",[30,96,97,98,101,102,105],{},"在 setup 中通过 ",[18,99,100],{},"useBraidAdapter()"," 获取 ",[18,103,104],{},"createAdapter"," 工厂。",[30,107,108,109,112],{},"调用 ",[18,110,111],{},"createAdapter()"," 创建适配器并消费命令流。",[23,114,116],{"id":115},"推荐方式插件模式","推荐方式：插件模式",[14,118,119],{},"组件通过 Vue 全局注册，Braid 插件自动发现，无需手动维护组件映射。",[49,121,125],{"className":122,"code":123,"language":124,"meta":54,"style":54},"language-ts shiki shiki-themes one-dark-pro","\u002F\u002F main.ts\nimport { createApp } from 'vue'\nimport { createBraidPlugin } from '@qingjin\u002Fbraid\u002Fruntime\u002Fvue'\nimport manifest from '.\u002Fbraid.manifest.json'\nimport ArticleList from '.\u002FArticleList.vue'\nimport PersonalProfileCard from '.\u002FPersonalProfileCard.vue'\n\nconst app = createApp(App)\n\n\u002F\u002F 1. 按 Vue 标准方式全局注册组件库\napp.component('PersonalProfileCard', PersonalProfileCard)\napp.component('ArticleList', ArticleList)\n\n\u002F\u002F 2. 安装 Braid 插件（自动从全局注册表发现 manifest 声明的组件）\napp.use(createBraidPlugin({ manifest }))\n\napp.mount('#app')\n","ts",[18,126,127,133,157,173,187,200,213,220,246,251,257,282,303,308,314,337,342],{"__ignoreMap":54},[58,128,129],{"class":60,"line":61},[58,130,132],{"class":131},"sV9Aq","\u002F\u002F main.ts\n",[58,134,136,140,144,148,151,154],{"class":60,"line":135},2,[58,137,139],{"class":138},"seHd6","import",[58,141,143],{"class":142},"sn6KH"," { ",[58,145,147],{"class":146},"sVyAn","createApp",[58,149,150],{"class":142}," } ",[58,152,153],{"class":138},"from",[58,155,156],{"class":68}," 'vue'\n",[58,158,160,162,164,166,168,170],{"class":60,"line":159},3,[58,161,139],{"class":138},[58,163,143],{"class":142},[58,165,94],{"class":146},[58,167,150],{"class":142},[58,169,153],{"class":138},[58,171,172],{"class":68}," '@qingjin\u002Fbraid\u002Fruntime\u002Fvue'\n",[58,174,176,178,181,184],{"class":60,"line":175},4,[58,177,139],{"class":138},[58,179,180],{"class":146}," manifest",[58,182,183],{"class":138}," from",[58,185,186],{"class":68}," '.\u002Fbraid.manifest.json'\n",[58,188,190,192,195,197],{"class":60,"line":189},5,[58,191,139],{"class":138},[58,193,194],{"class":146}," ArticleList",[58,196,183],{"class":138},[58,198,199],{"class":68}," '.\u002FArticleList.vue'\n",[58,201,203,205,208,210],{"class":60,"line":202},6,[58,204,139],{"class":138},[58,206,207],{"class":146}," PersonalProfileCard",[58,209,183],{"class":138},[58,211,212],{"class":68}," '.\u002FPersonalProfileCard.vue'\n",[58,214,216],{"class":60,"line":215},7,[58,217,219],{"emptyLinePlaceholder":218},true,"\n",[58,221,223,226,230,234,237,240,243],{"class":60,"line":222},8,[58,224,225],{"class":138},"const",[58,227,229],{"class":228},"sU0A5"," app",[58,231,233],{"class":232},"sjrmR"," =",[58,235,236],{"class":64}," createApp",[58,238,239],{"class":142},"(",[58,241,242],{"class":146},"App",[58,244,245],{"class":142},")\n",[58,247,249],{"class":60,"line":248},9,[58,250,219],{"emptyLinePlaceholder":218},[58,252,254],{"class":60,"line":253},10,[58,255,256],{"class":131},"\u002F\u002F 1. 按 Vue 标准方式全局注册组件库\n",[58,258,260,263,266,269,271,274,277,280],{"class":60,"line":259},11,[58,261,262],{"class":228},"app",[58,264,265],{"class":142},".",[58,267,268],{"class":64},"component",[58,270,239],{"class":142},[58,272,273],{"class":68},"'PersonalProfileCard'",[58,275,276],{"class":142},", ",[58,278,279],{"class":146},"PersonalProfileCard",[58,281,245],{"class":142},[58,283,285,287,289,291,293,296,298,301],{"class":60,"line":284},12,[58,286,262],{"class":228},[58,288,265],{"class":142},[58,290,268],{"class":64},[58,292,239],{"class":142},[58,294,295],{"class":68},"'ArticleList'",[58,297,276],{"class":142},[58,299,300],{"class":146},"ArticleList",[58,302,245],{"class":142},[58,304,306],{"class":60,"line":305},13,[58,307,219],{"emptyLinePlaceholder":218},[58,309,311],{"class":60,"line":310},14,[58,312,313],{"class":131},"\u002F\u002F 2. 安装 Braid 插件（自动从全局注册表发现 manifest 声明的组件）\n",[58,315,317,319,321,324,326,328,331,334],{"class":60,"line":316},15,[58,318,262],{"class":228},[58,320,265],{"class":142},[58,322,323],{"class":64},"use",[58,325,239],{"class":142},[58,327,94],{"class":64},[58,329,330],{"class":142},"({ ",[58,332,333],{"class":146},"manifest",[58,335,336],{"class":142}," }))\n",[58,338,340],{"class":60,"line":339},16,[58,341,219],{"emptyLinePlaceholder":218},[58,343,345,347,349,352,354,357],{"class":60,"line":344},17,[58,346,262],{"class":228},[58,348,265],{"class":142},[58,350,351],{"class":64},"mount",[58,353,239],{"class":142},[58,355,356],{"class":68},"'#app'",[58,358,245],{"class":142},[49,360,362],{"className":122,"code":361,"language":124,"meta":54,"style":54},"\u002F\u002F 组件内使用\nimport { useBraidAdapter } from '@qingjin\u002Fbraid\u002Fruntime\u002Fvue'\n\nconst { createAdapter } = useBraidAdapter()\n\nconst adapter = createAdapter({\n  mountTarget: '#widget-stage',\n  onEvent(event) { console.log(event) },\n  onError(error, context) { console.error(context.source, error.message) },\n})\n\nawait consumeBraidStream(response.body, adapter)\n",[18,363,364,369,384,388,407,411,426,440,469,512,517,521],{"__ignoreMap":54},[58,365,366],{"class":60,"line":61},[58,367,368],{"class":131},"\u002F\u002F 组件内使用\n",[58,370,371,373,375,378,380,382],{"class":60,"line":135},[58,372,139],{"class":138},[58,374,143],{"class":142},[58,376,377],{"class":146},"useBraidAdapter",[58,379,150],{"class":142},[58,381,153],{"class":138},[58,383,172],{"class":68},[58,385,386],{"class":60,"line":159},[58,387,219],{"emptyLinePlaceholder":218},[58,389,390,392,394,396,398,401,404],{"class":60,"line":175},[58,391,225],{"class":138},[58,393,143],{"class":142},[58,395,104],{"class":228},[58,397,150],{"class":142},[58,399,400],{"class":232},"=",[58,402,403],{"class":64}," useBraidAdapter",[58,405,406],{"class":142},"()\n",[58,408,409],{"class":60,"line":189},[58,410,219],{"emptyLinePlaceholder":218},[58,412,413,415,418,420,423],{"class":60,"line":202},[58,414,225],{"class":138},[58,416,417],{"class":228}," adapter",[58,419,233],{"class":232},[58,421,422],{"class":64}," createAdapter",[58,424,425],{"class":142},"({\n",[58,427,428,431,434,437],{"class":60,"line":215},[58,429,430],{"class":146},"  mountTarget",[58,432,433],{"class":142},": ",[58,435,436],{"class":68},"'#widget-stage'",[58,438,439],{"class":142},",\n",[58,441,442,445,447,451,454,457,459,462,464,466],{"class":60,"line":222},[58,443,444],{"class":64},"  onEvent",[58,446,239],{"class":142},[58,448,450],{"class":449},"s_ZVi","event",[58,452,453],{"class":142},") { ",[58,455,456],{"class":228},"console",[58,458,265],{"class":142},[58,460,461],{"class":64},"log",[58,463,239],{"class":142},[58,465,450],{"class":146},[58,467,468],{"class":142},") },\n",[58,470,471,474,476,479,481,484,486,488,490,492,494,496,498,501,503,505,507,510],{"class":60,"line":248},[58,472,473],{"class":64},"  onError",[58,475,239],{"class":142},[58,477,478],{"class":449},"error",[58,480,276],{"class":142},[58,482,483],{"class":449},"context",[58,485,453],{"class":142},[58,487,456],{"class":228},[58,489,265],{"class":142},[58,491,478],{"class":64},[58,493,239],{"class":142},[58,495,483],{"class":228},[58,497,265],{"class":142},[58,499,500],{"class":146},"source",[58,502,276],{"class":142},[58,504,478],{"class":228},[58,506,265],{"class":142},[58,508,509],{"class":146},"message",[58,511,468],{"class":142},[58,513,514],{"class":60,"line":253},[58,515,516],{"class":142},"})\n",[58,518,519],{"class":60,"line":259},[58,520,219],{"emptyLinePlaceholder":218},[58,522,523,526,529,531,534,536,539,541,544],{"class":60,"line":284},[58,524,525],{"class":138},"await",[58,527,528],{"class":64}," consumeBraidStream",[58,530,239],{"class":142},[58,532,533],{"class":228},"response",[58,535,265],{"class":142},[58,537,538],{"class":146},"body",[58,540,276],{"class":142},[58,542,543],{"class":146},"adapter",[58,545,245],{"class":142},[23,547,549],{"id":548},"显式组件映射可选","显式组件映射（可选）",[14,551,552,553,556],{},"如果不想用全局注册，也可以在插件选项中显式传入 ",[18,554,555],{},"components","：",[49,558,560],{"className":122,"code":559,"language":124,"meta":54,"style":54},"app.use(createBraidPlugin({\n  manifest,\n  components: {\n    PersonalProfileCard,\n    ArticleList,\n  },\n}))\n",[18,561,562,576,583,591,598,605,610],{"__ignoreMap":54},[58,563,564,566,568,570,572,574],{"class":60,"line":61},[58,565,262],{"class":228},[58,567,265],{"class":142},[58,569,323],{"class":64},[58,571,239],{"class":142},[58,573,94],{"class":64},[58,575,425],{"class":142},[58,577,578,581],{"class":60,"line":135},[58,579,580],{"class":146},"  manifest",[58,582,439],{"class":142},[58,584,585,588],{"class":60,"line":159},[58,586,587],{"class":146},"  components",[58,589,590],{"class":142},": {\n",[58,592,593,596],{"class":60,"line":175},[58,594,595],{"class":146},"    PersonalProfileCard",[58,597,439],{"class":142},[58,599,600,603],{"class":60,"line":189},[58,601,602],{"class":146},"    ArticleList",[58,604,439],{"class":142},[58,606,607],{"class":60,"line":202},[58,608,609],{"class":142},"  },\n",[58,611,612],{"class":60,"line":215},[58,613,614],{"class":142},"}))\n",[14,616,617,556,621,623,624,626],{},[618,619,620],"strong",{},"解析优先级",[18,622,555],{}," 显式映射 > ",[18,625,87],{}," 全局注册。",[23,628,629],{"id":629},"运行时行为",[27,631,632,641,647,653],{},[30,633,634,637,638],{},[18,635,636],{},"render","：创建新 widget，生成 ",[18,639,640],{},"widgetId",[30,642,643,646],{},[18,644,645],{},"update","：按浅合并更新 props",[30,648,649,652],{},[18,650,651],{},"destroy","：卸载组件并释放 DOM",[30,654,655,656,658,659],{},"组件事件：runtime 自动补齐 ",[18,657,640],{}," 和 ",[18,660,661],{},"timestamp",[14,663,664,665,667],{},"这些行为由 ",[18,666,20],{}," 提供，集成时不应在业务项目中重新实现。",[23,669,670],{"id":670},"线上示例",[14,672,673,674,21],{},"Braid 架构的完整实践示例见 ",[675,676,680],"a",{"href":677,"rel":678},"https:\u002F\u002Fmengqinghe.com",[679],"nofollow","mengqinghe.com",[682,683,684],"style",{},"html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .subq3, html code.shiki .subq3{--shiki-default:#98C379}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sV9Aq, html code.shiki .sV9Aq{--shiki-default:#7F848E;--shiki-default-font-style:italic}html pre.shiki code .seHd6, html code.shiki .seHd6{--shiki-default:#C678DD}html pre.shiki code .sn6KH, html code.shiki .sn6KH{--shiki-default:#ABB2BF}html pre.shiki code .sVyAn, html code.shiki .sVyAn{--shiki-default:#E06C75}html pre.shiki code .sU0A5, html code.shiki .sU0A5{--shiki-default:#E5C07B}html pre.shiki code .sjrmR, html code.shiki .sjrmR{--shiki-default:#56B6C2}html pre.shiki code .s_ZVi, html code.shiki .s_ZVi{--shiki-default:#E06C75;--shiki-default-font-style:italic}",{"title":54,"searchDepth":135,"depth":135,"links":686},[687,688,689,690,691,692,693],{"id":25,"depth":135,"text":25},{"id":44,"depth":135,"text":44},{"id":78,"depth":135,"text":78},{"id":115,"depth":135,"text":116},{"id":548,"depth":135,"text":549},{"id":629,"depth":135,"text":629},{"id":670,"depth":135,"text":670},"本指南说明如何在 Vue 应用中接入 braid\u002Fruntime\u002Fvue。","md",{},"\u002Fzh\u002Fguides\u002Ffrontend-vue",{"title":5,"description":694},"zh\u002Fguides\u002Ffrontend-vue","AlO0zs08RqGbYcn-5o2_Y1-1eBkBTutoSZcJ9zXxjgw",1786595235853]