时间:2023-07-08 11:12:01 | 来源:网站运营
时间:2023-07-08 11:12:01 来源:网站运营
如何用 Vue.js 实现一个建站应用:随着互联网飞速发展,越来越多的传统服务搬到了线上,商家急需一个官网介绍自己的产品,提高知名度。因此 “建站” 成为了一种刚需。本文就如何用 Vue.js 实现一个建站应用提供了解决思路。作为前端工程师,相信大家都写过不少网站和应用,我把网站简单的分为 “表现型” 和 “操作型”。表现型可以是一个产品介绍网站,而操作型的典型代表是管理后台。不久前有机会参与一个建站项目的设计与开发,它属于操作类型网站但需要更深一层的抽象,它是一个 “创建网站的网站”。本文尝试基于 Vue.js 框架设计实现这样一个应用,用户通过拖拽模块就可以建站。希望通过本文的介绍,能够带给大家不一样的视角。
{ "id": 1, "name": "xxx公司" "type": "site", "children": [{ "type": "page", "name": "首页", "children": [{ "type": "section", "name": "公司简介", "children": [{ "type": "paragraph" }, { "type": "carousel" }] }] }]}
site.config
中增加themeColor
属性来表示。class="col-xs-12 col-sm-6 col-md-3"
表示该板块在手机下横向占 100%、平板占 50%、PC 占 25%。node
属性和themeColor
<!-- Paragraph.vue --><template> <div> <h1 :style="{color: themeColor}">{{node.content.title}}</h1> <small v-if="node.config.showSubTitle">{{node.content.subTitle}}</small> <p>{{node.content.detail}}</p> </div></template><script>export default { name: 'paragraph', props: ['node', 'themeColor']}</script>
完成所有节点代码编写之后,第二步,我们需要写一个类似于 “renderer” 的组件来递归的渲染 JSON 树。基本思路是该组件先渲染自己,然后渲染自己的后代,每个后代也重复此渲染过程,如此渲染整棵树。type
属性也就是一个 String 来获取对应的组件定义。幸运的是 Vue.js 中已经有这样的动态组件Component
,此组件的is
属性接受一个 String。由此我们的 render 组件可以这样写:<!-- render.vue --><tempplate> <component :is="node.type" :node="node" :theme="themeColor"> <render v-for="child in node.children" :key="child.id" :node="child" :theme="themeColor" /> </component></tempplate><script>// 导入JSON 树中所涉及的所有节点import Page from './Page.vue'import Section from './Section.vue'import Paragraph from './Paragraph.vue'export default { name: 'render', props: ['node', 'themeColor'], components: { Page, Section, Paragraph }}</script>
注:若 Vue.js 没有提供动态 Component 组件,我们也可以利用 Vue.js 中的createElement
方法自己实现该组件,详见此 gist(https://gist.github.com/github-libra/7ba6eb53efd5cccdd3828030708c4297)。site.config.themeColor
拖拽模块到区域中在对应的section.children
的数组中 push 一个组件节点在区域中排序模块在对应的section.children
的数组中重新设置组件节点的 index编辑模块内容和配置更新对应模块的 content 和 config 中的属性保存网站把 JSON 树存入数据库持久化// store.jsimport Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)const store = new Vuex.Store({ state: { site: {} }, mutations: { changeThemeColor () {}, addModule () {}, sortModule () {}, removeModule () {}, updateModule () {} }, actions: { getSite () {}, saveSite () {} }})
理论上有了这些方法我们已经可以从通过程序更新这棵树了,但作为编辑后台,我们还要提供一些界面上的入口让用户来编辑这棵树。edit-
。例如 Paragraph 这个组件的编辑组件可以编写如下:<!-- EditParagraph.vue --><template> <edit-wrapper> <paragraph :node="node" :themeColor="themeColor" /> </edit-wrapper></template><script>// EditWrapper提供统一的编辑入口,内部仍需要渲染一次 Paragraph 便于实时预览编辑结果import EditWrapper from './EditWrapper.vue'import Paragraph from './Paragraph.vue'import { mapMutations } from 'vuex'export default { name: 'edit-paragraph', props: ['node', 'themeColor'], methods: { ...mapMutations(['updateModule']) }}</script>
用户可以通过这个组件的界面入口编辑 Paragraph 这个模块(此处略去edit-wrapper
的实现,事实上组件的编辑可以通过弹窗加表单实现,也可以是更方便的 inline editing )。Vue.Draggable
(github.com/SortableJS/Vue.Draggable)这个库,它是基于 Sortable.js 做的一层封装。其典型的应用场景如下:<draggable v-model="myArray" :options="{group:'people'}" @start="drag=true" @end="drag=false"> <div v-for="element in myArray">{{element.name}}</div></draggable>
在我们的场景中,只需在draggable
组件上监听add
和sort
事件调用 store 中对应的方法即可。// store.jsconst autoSave = (store) => { store.watch( state => state.site, (newV, oldV) => { store.dispatch('saveSite') }, { deep: true } )}const store = new Vuex.Store({ state: { site: {} }, plugins: [autoSave]})
至此,我们已经用 Vue.js 和相关技术实现了文章开头列出的建站应用的需求。作者:唐鹤俊
简介:百姓网前端工程师。
本文仅为作者个人观点,不代表百姓网立场。
关键词:实现