返回顶部
首页 > 资讯 > 精选 >javascript怎么实现页面生成器
  • 293
分享到

javascript怎么实现页面生成器

2023-06-27 10:06:35 293人浏览 独家记忆
摘要

这篇文章主要介绍“javascript怎么实现页面生成器”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“javascript怎么实现页面生成器”文章能帮助大家解决问题。目标我们的目标是实现一个页面制作

这篇文章主要介绍“javascript怎么实现页面生成器”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“javascript怎么实现页面生成器”文章能帮助大家解决问题。

目标

我们的目标是实现一个页面制作后台,在后台中我们可以对页面进行 组件选择 --> 布局样式调整 --> 发布上线 --> 编辑修改这样的流程操作。

架构设计

首先是要能提供组件给用户进行选择,那么我们需要一个组件库,然后需要对选择的组件进行布局样式调整,所以我们需要一个页面编辑后台接着我们需要将编辑产出的数据渲染成真实的页面,所以我们需要一个node服务和用于填充的template 模板。发布上线,这个直接对接各个公司内部的发布系统就好了,这里我们不做过多阐述。最后的编辑修改功能也就是针对配置的修改,所以我们需要一个数据库,这里我选择的是用了mysql 。当然你也可以顺便做做权限管理,页面管理....等等之类的活。啰嗦了这么长,我们来画个图,了解下大概的流程:

javascript怎么实现页面生成器

开撸

组件的实现

首先我们来实现组件这一部分,因为组件关联着后台编辑的预览和最后发布的使用。组件设计我们应该尽量保持组件的对外一致性,这样在进行渲染的时候,我们可以提供一个统一的对外数据接口。这里我们的技术选型是基于 Vue  的,所以下面的代码部分也主要是基于 Vue 的,但是万变不离其宗,其他语言也类似。

根据上图,我们的组件是会被一个个拆分单独发布到 npm仓库的,为什么这么设计呢?其实之前也考虑过设计成一个组件库,所有组件都包含在一个组件库内,这样只需要发布一个组件库包,用的时候按需加载就好了。后来在实践的过程中发现这样并不合适协同开发,其他前端如果想贡献组件,接入的改造成本也很大。举个例子:小明在业务中写了个Button组件,这个组件经常会被其他项目复用,他想把这个组件贡献到我们的系统中,被模板使用,如果是一个组件库的话,他首先得拉取我们组件库的代码,然后按照组件库的规范格式进行提交。这样一来,偷懒的小明可能就不太愿意这么干,最爽的方法当然是在本地构建一个npm库,开发选用的是用typescript还是其他的我们不关心,选用的 CSS 预处理器我们也不关心,甚至编码规范的ESLint我们也不关心。最后只需通过编译后的文件即可。这样就避免了一个组件库的约束。依托于NPM完善的发布/拉取,以及版本控制机制,可以让我们少做一些额外的工作,也可以快速的把平台搭建起来。

说了这么多,代码呢?,我们以一个Button为例,我们对外提供这样的形式组件:

<template>  <div :style="data.style.container" class="w_button_container">    <button :style="data.style.btn"> {{data.context}}</button>  </div></template><script>export default {  name: 'WButton',  props: {    data: {      type: Object,      default: () => {}    }  }}</script>

可以看到我们只对外暴露了一个props,这样做法的好处是可以统一组件对外暴露的数据,组件内部爱怎么玩怎么玩。注意,这里我们也可以引入一些第三方组件库,比如mint-ui之类的。

后台编辑的实现

在写代码前,我们先考虑一下需要实现哪些功能:

  1. 一个属性编辑区,提供给使用者编辑组件内部props的功能

  2. 一个组件选择区,提供使用者选择需要的组件

  3. 一个组件预览区,提供使用者拖拽排序页面预览的功能

编辑区的实现

按照顺序,我们先来实现组件的属性编辑功能。我们要考虑,一个组件暴露出哪些可配置的信息。这些可配置的信息如何同步到后台编辑区,让使用者进行编辑,一个按钮的可配置信息可能是这样:

javascript怎么实现页面生成器

如果把这些配置全部写在后台库里面,根据当前选择的组件加载不同的配置,维护起来会相当麻烦,而且随着组件数量的增加,也会变得臃肿,所以我们可以将这些配置存储在服务端,后台只需要根据存储的规则进行解析便可,举个例子,我们其实可以存储这样的编辑配置:

[  {    "blockName": "按钮布局设置",     "settings": {      "src": {        "type": "input",          "require": true,        "label": "按钮文案"      }    }  }]

我们在编辑后台,通过接口请求到这些配置,便可以进行规则渲染:

        createEditorElement (vm: VNode) {      let dom = null      switch (vm.config.type) {        case 'align':          dom = this.createAlignElement(vm)          break;        case 'select':          dom = this.createSelectElement(vm)          break;        case 'actions':          dom = this.createActionElement(vm)          break;        case 'vue-editor':          dom = this.createVueEditor(vm)          break;        default:          dom = this.createBasicElement(vm)      }      return dom    }
组件选择功能

首先我们需要考虑的是,组件怎么进行注册?因为组件被用户选用的时候,我们是需要渲染该组件的,所以我们可以提供一段 node 脚本来遍历所需组件,进行组件的安装注册:

// 定义渲染模板和路径var OUTPUT_PATH = path.join(__dirname, '../packages/index.js');console.log(chalk.yellow('正在生成包引用文件...'))var INSTALL_COMPONENT_TEMPLATE = '    {{name}}';var IMPORT_TEMPLATE = 'import {{componentName}} from \\\\'{{name}}\\\\'';var MAIN_TEMPLATE = `{{include}}const components = [{{install}}]const install = function(Vue) {    components.map((component) => {        Vue.component(component.name, component)    })}if (typeof window !== 'undefined' && window.Vue) {    install(window.Vue)}export {    install,{{list}}}`;// 渲染引用文件var template = render(MAIN_TEMPLATE, {  include: includeComponentTemplate.join(endOfLine),  install: installTemplate.join(`,${endOfLine}`),  version: process.env.VERSION || require('../package.JSON').version,  list: listTemplate.join(`,${endOfLine}`)});// 写入引用fs.writeFileSync(OUTPUT_PATH, template);

最后渲染出来的文件大概是这样:

import WButton from 'w-button'const components = [    WButton]const install = function(Vue) {    components.map((component) => {        Vue.component(component.name, component)    })}if (typeof window !== 'undefined' && window.Vue) {    install(window.Vue)}export {    install,    WButton}

这个也是组件库的通用写法,所以这里的思想就是把发布到npm上的组件,进行聚合,聚合成一个组件包引用,我们在后台编辑的时候,是需要全量引入的:

import * as W_UI from '../../packages'Vue.use(W_UI)

这样,我们组件便注册完了,组件选择区,主要是提供组件的可选项,我们可以遍历组件,提供一个个 List 让用户选择,当然如果我们每个组件如果只提供一个组件名,用户可能并不知道组件长什么样,所以我们最好可以提供一下组件长什么样的缩略图。这里我们可以在组件发布的时候,也通过 node 脚本进行。这里要实现的代码比较多,我就大致说一下过程,因为也不是核心逻辑,可有可无,只能说有了体验上会好一点:

  1. 用户启用 dev-server 进行代码编写测试

  2. server 脚本使用 Chrome 工具 puppeteer,调整页面到手机端模式, 进行当前 dev-server 截图。

  3. 生成截图文件,上传到node服务,关联组件

这样,就可以在加载组件选择区的时候,为组件附上缩略图。

组件预览区

当用户在选择区选择了组件,我们需要展示在预览区域,那么我们怎么知道用户选择了哪些组件呢?总不能提前全部把组件写入渲染区域,通过 v-if来判断选择吧?当然没有这么蠢,Vue 已经提供了动态组件的功能了:

<div    :class="[index===currentEditor ? 'active' : '']"    :is="select.name"    :data="select.data"></div>

为什么我们不用缩略图代替真实组件?一方面生成的缩略图尺寸存在问题,另一方面,我们需要编辑的联动性,就是编辑区的编辑需要及时的反馈给用户。

额外的问题

说了这么多,貌似一切都很顺利,但是这样在实践的时候,发现了存在一个明显的问题就是:我们中间的预览区域其实就是为了尽可能模拟移动端页面效果。但是如果我们加入了一些包含类似 position: fixed 样式的组件,会发现样式上就出现了明显的问题。典型的比如Dialog Loading 等。所以我们参考了 m-ui组件库的设计,将中间预览操作容器展示为一个iframe。将iframe大小调整为375 * 667,模拟 iPhone 6 的手机端。这样就不会存在样式问题了。可是这样又出现了另一个难点,那就是左侧的编辑数据如何及时的反应到iframe中?没错,就是postMessgae,大致思路如下:

javascript怎么实现页面生成器

利用 vuex 做数据存储池,所有的变化,通过 postMessgae进行同步,这样我们只用确保数据池中的数据变化,便可以映射到渲染层的变化。比如,我们在预览区进行了组件选择和拖拽排序,那么我们只需通过vuex出发同步信息便可:

// action.tsconst action = {  setCurrentPage ({commit, state}, page: number) {      // 更新当前store      commit('setCurrentPage',page)      // 对应postMessage      helper.postMsgToChild({type: 'syncState', value: state})    },  // ...}

Template 模板的实现

模板的设计实现,我参考了 Vue-cli 2.x 版本的思想,把这里的模板,存在了对应的 git 仓库中。当用户需要进行页面构建的时候,直接从 git 仓库中拉取对应的模板即可。当然拉取完,也会缓存一份在本地,以后渲染,直接从本地缓存中读取即可。我们现在把中心放在模板的格式和规范上。模板我们采用什么样的语法无所谓,这里我才用了和 Vue-cli一样的Handlerbars引擎。这里直接上我们模板的设计:

<template>  <div class="pg-index" :style="{backgroundColor: '{{bGColor}}'}">      <div class="main-container" :style="{        backgroundColor: '{{bgColor}}',        backgroundImage: '{{bgImage}}' ? 'url({{bgImage}})' : null,        backgroundSize: '{{bgSize}}',        backgroundRepeat: 'no-repeat'      }">        {{#components}}          <div class="cp-module-editor {{className}} {{data.className}}">            <{{name}} class="temp-component" :data="{{tostring data}}" data-type="{{upcasefirst name}}"></{{name}}>          </div>        {{/components}}      </div>  </div></template><script>    {{#noRepeatcpsName}}  import {{upcasefirst this}} from '{{this}}'    {{/noRepeatCpsName}}export default {  name: '{{upcasefirst repoName}}',  components: {    {{#noRepeatCpsName}}      {{upcasefirst this}},    {{/noRepeatCpsName}}  }}</script>

为了简化逻辑,我们把模板都设计成流式布局,所有组件一个个堆叠往下顺序排列。这个文件便是我们vue-webpack-simple的模板中的App.vue。我们对其进行了改写。这样在数据填充万,便可以渲染出一个 Vue 单文件。这里我只举着一个例子,我们还可以实现多页模板等等复杂的模板,根据需求拉取不同的模板即可。

Node 渲染服务

当后台提交渲染请求的时候,我们的 node 服务所做的工作主要是:

  1. 拉取对应模板

  2. 渲染数据

  3. 编译

拉取也就是去指定仓库中通过download-git-repo插件进行拉取模板。编译其实也就是通过metalsmith静态模板生成器把模板作为输入,数据作为填充,按照handlebars的语法进行规则渲染。最后产出build构建好的目录。在这一步,我们之前所需的组件,会被渲染进package.json文件。我们来看一下核心代码:

// 这里就像一个管道,以数据入口为生成源,通过renderTemplateFiles编译产出到目标目录function build(data, temp_dest, source, dest, cb) {  let metalsmith = Metalsmith(temp_dest)    .use(renderTemplateFiles(data))    .source(source)    .destination(dest)    .clean(false)  return metalsmith.build((error, files) => {    if (error) console.log(error);    let f = Object.keys(files)      .filter(o => fs.existsSync(path.join(dest, o)))      .map(o => path.join(dest, o))    cb(error, f)  })}function renderTemplateFiles(data) {  return function (files) {    Object.keys(files).forEach((fileName) => {      let file = files[fileName]      // 渲染方法      file.contents = Handlebars.compile(file.contents.toString())(data)    })  }}

最后我们得到的是一个 Vue 项目,此时还不能直接跑在浏览器端,这里就涉及到当前发布系统所支持的形式了。怎么说?如果你的公司发布系统需要在线编译,那么你可以把源文件直接上传到 git 仓库,触发仓库的 WEBHook 让发布系统替你发掉这个项目即可。如果你们的发布系统是需要你编译后提交编译文件进行发布的,那么你可以通过 node 命令,进行本地构建,产出 html ,CSS ,JS 。直接提交给发布系统即可。 

关于“javascript怎么实现页面生成器”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网精选频道,小编每天都会为大家更新不同的知识点。

--结束END--

本文标题: javascript怎么实现页面生成器

本文链接: https://lsjlt.com/news/309524.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • javascript怎么实现页面生成器
    这篇文章主要介绍“javascript怎么实现页面生成器”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“javascript怎么实现页面生成器”文章能帮助大家解决问题。目标我们的目标是实现一个页面制作...
    99+
    2023-06-27
  • phpstorm快速生成html页面怎么实现
    phpstorm中快速生成html页面的方法:1、打开phpstorm工具;2、新建一个文件;3、最后输入一个“!”号和按下键盘【Tab】建快速生成html页面代码架构即可。具体操作步骤:打开已安装的phpstorm工具。在左侧项目列表中新...
    99+
    2024-04-02
  • php怎么生成页面及url
    要生成页面及URL,你可以使用PHP的URL重写功能和页面模板。以下是一个简单的示例:1. 配置URL重写:在你的Web服务器中配置...
    99+
    2023-09-05
    php
  • Javascript动态生成的页面信息爬
      最近,笔者在使用Requests模拟浏览器发送Post请求时,发现程序返回的html与浏览器F12观察到的略有不同,经过观察返回的response.text,cookies确认有效,因为我们可以看到返回的登陆信息。然而部分字段的值依然...
    99+
    2023-01-30
    页面 动态 信息
  • JavaScript中怎么实现一个密码生成器
    这期内容当中小编将会给大家带来有关JavaScript中怎么实现一个密码生成器,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。我为大家准备了一个密码生成工具,有0-9和a-...
    99+
    2024-04-02
  • javascript怎么实现跳转到页面
    这篇文章给大家分享的是有关javascript怎么实现跳转到页面的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。JavaScript可以做什么1.可以使网页具有交互性,例如响应用户点击,给用户提供更好的体验。2.可...
    99+
    2023-06-14
  • JavaScript中怎么实现SPA单页面
    这篇“JavaScript中怎么实现SPA单页面”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“JavaScript中怎么实现...
    99+
    2023-07-05
  • 怎么在Html5页面中生成图片
    本篇文章为大家展示了怎么在Html5页面中生成图片,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。LiveDemo    function DPR()...
    99+
    2023-06-09
  • ASP.NET中怎么生成HTML静态页面
    ASP.NET中怎么生成HTML静态页面,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。ASP.NET模版生成HTML静态页面方案1:/// <&...
    99+
    2023-06-17
  • javascript怎么实现定时跳转页面
    本篇内容介绍了“javascript怎么实现定时跳转页面”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! ...
    99+
    2024-04-02
  • JavaScript中怎么实现页面自适应
    JavaScript中怎么实现页面自适应,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。 实现原理:获取IE显示屏幕的宽高.确定哪些对...
    99+
    2024-04-02
  • JavaScript怎么实现注册登录页面
    本篇内容介绍了“JavaScript怎么实现注册登录页面”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! ...
    99+
    2024-04-02
  • 怎么在javascript中实现页面跳转
    本篇文章给大家分享的是有关怎么在javascript中实现页面跳转,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。javascript实现页面跳转的方法:1、通过修改窗体对象wi...
    99+
    2023-06-14
  • 小程序如何实现页面生成二维码
    首先,登录微信公众号平台,进入小程序管理后台,点击“生成小程序码”;在对话框中填写小程序的名称,并在开启入口中输入管理小程序的微信号;在手机中打开小程序,点击右上角,选择“复制本页路径”;最后,将路径复制到公众号平台上,点击生成,保存二维码...
    99+
    2024-04-02
  • Java使用Freemarker页面静态化生成的实现
    目录前言:1、 Freemarker介绍2、创建模板文件3、生成文件4、 Freemarker指令4.1、assign指令4.2、include指令4.3、if指令4.4、list指...
    99+
    2024-04-02
  • HTML、CSS、JavaScript是怎么变成页面的
    这篇文章主要讲解了“HTML、CSS、JavaScript是怎么变成页面的”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“HTML、CSS、JavaScrip...
    99+
    2024-04-02
  • 原生JavaScript实现网页版计算器
    本文实例为大家分享了JavaScript实现网页版计算器的具体代码,供大家参考,具体内容如下 由于无聊看电脑上的系统软件翻到了计算器这个功能,就简单写一下这个计算器的功能吧,这个网页...
    99+
    2024-04-02
  • javascript怎么实现简单页面倒计时
    小编给大家分享一下javascript怎么实现简单页面倒计时,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!具体如下:<!DOCTYPE html><html><head>&nb...
    99+
    2023-06-06
  • JavaScript怎么实现页面动态验证码
    小编给大家分享一下JavaScript怎么实现页面动态验证码,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!效果图: 实现思路:把数字和字母放到一个数组中...
    99+
    2023-06-14
  • 怎么实现javascript跳转到指定页面
    JavaScript是一种广泛用于Web页面交互和动态效果的编程语言。在Web开发中,跳转到指定页面是一项常见的任务,通常在用户点击一个链接或按下一个按钮时触发。本文将介绍不同方式的JavaScript跳转到指定页面的方法。window.l...
    99+
    2023-05-14
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作