1.2.6 • Published 6 months ago

microi-pageengine v1.2.6

Weekly downloads
-
License
ISC
Repository
-
Last release
6 months ago

一、前言

🎉🎉插件陆续更新中,后续文档会更新至CSDN
https://lisaisai.blog.csdn.net/

二、npm集成

2.1 持久化

不管哪种方式集成,如果要持久化,那必须准备一张数据表,格式如下

{
  Id: '', //页面ID
  Title: '',//页面标题
  Number: '',//页面编号
  Desc: '',//页面描述
  JsonObj: {}|'' //对象或者字符串
}

2.2 npm包集成方案

只需一个Vue3页面搞定,实在掏不出页面连路由都没有用App页面也行, 通过组件方式集成到项目内,不会污染项目,而且升级扩展都是独立的,主打一个互不干扰,距离产生美。

npm包依赖项 参考 https://www.npmjs.com/package/microi-pageengine ,目前version 1.2.4 ,陆续会升级

npm i microi-pageengine@latest

2.3 安装 element-plus 图标库

Vue3组件集成最低要求 element-plus ,请自行安装最新版本。

npm install @element-plus/icons-vue

2.4 注册所有图标

// main.ts
// 如果您正在使用CDN引入,请删除下面一行。
import * as ElementPlusIconsVue from '@element-plus/icons-vue'

const app = createApp(App)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
  app.component(key, component)
}

2.5 引用封装的extendedWidget.js

/**
 * @description: 自定义扩展组件
 * @author: mrcroi_lisaisai
 * @createTime: 2024/11/26 9:09
 **/

import { defineAsyncComponent } from 'vue'

export const newWidgets = [
  {
    type: 'test',
    label: '测试',
    category: 0, //0 内置组件,1 自定义组件
    show: 1, //是否展示 0隐藏,1展示
    icon: '', // elementplus
    img: 'https://www.nbweixin.cn/autopage/logoarr1/%E9%97%AE%E5%8D%B7%E8%B0%83%E6%9F%A5.png', //图片图标
    widgetOption: {
      height: 280, //高度
    },
    widgetParams: [
      {
        sort: 0,
        label: '数据来源', //属性名称
        type: 'textarea', //表单组件类型(input,textarea,number,color,select,switch,slider)
        value: '', //表单组件内容
        typeOptions: {
          rows: 3, //表单组件设置,多行文本框默认3行
          dataJson: {
            icon: 'https://www.nbweixin.cn/autopage/photo.png',
            title: '早安,Ah jung,开始您一天的工作吧!',
            subTitle: '今日阴转大雨,15℃ - 25℃,出门记得带伞哦。',
          },
        },
      },
      {
        sort: 1,
        label: '测试属性',
        type: 'input',
        value: '',
        typeOptions: {},
      },
    ],
  },
]

export const newComponents = [
  {
    'test-widget': defineAsyncComponent(() =>
      import('@/components/test-widget.vue')
    ),
  },
]

2.6 配置主题

main.ts 引用暗黑模式样式

import 'element-plus/theme-chalk/dark/css-vars.css'

2.7 Vue3 npm集成demo

<template>
  <!-- 页面设计器 -->
  <formDesigner :remoteObj="remoteObj"  :components="newComponents" :widgets="newWidgets"/>
  <!-- 页面渲染器 -->
  <!-- <formRenderer :remoteObj="remoteObj" /> -->
</template>
<script setup>
  
//引入组件
import { formDesigner, EventBus, usePageEngineStore } from 'microi-pageengine' 
//引入样式
import 'microi-pageengine/style.css' 

//把这两个方法封装在utils文件夹里方便管理,
import { newComponents, newWidgets } from '@/utils/extendedWidget'

//本地组件
import { useRouter } from 'vue-router'
import { createPinia } from 'pinia'
import { onMounted, onBeforeUnmount, ref } from 'vue'

//用自己的路由处理组件内部跳转,通过EventBus监听处理内部事件,主打一个自由自在,随心所欲.
const router = useRouter()

//状态机传参,npm包没包把pinia打包进去,正所谓巧妇难为无米之炊,给她传一个完事
const pinia = createPinia()
const pageEngineStore = usePageEngineStore(pinia)

//传入数据,这个数据不知道什么格式,可以在设计器拖拽几个组件查看下页面JSON ,和渲染JSON一毛一样的
const remoteObj = ref({
  Id: '', //自定义页面ID
  Title: '',//自定义页面标题
  Number: '',//自定义页面编号
  Desc: '',//自定义页面描述
  JsonObj: {}|'' //对象或者字符串
})


//模拟加载远程数据
const loadFormData = () => {}

onMounted(() => {
  
  //如果需要token,设置token,该token一经接收即刻存入pinia状态机,每次调用接口通过拦截器自动处理token头,无需每次手动写,持久化用的localStorage ,可以F12查看
  pageEngineStore.setToken('')
  
  //下面这一大串监听,其实也可以写到一个事件里,通过key value 键值对来区分,暂时先这么着吧
  
  //监听保存页面JSON事件
  EventBus.on('saveFormJson', (saveFormJson) => {
    console.log('监听saveFormJson', saveFormJson)
  })

  //监听日历选择日期事件
  EventBus.on('calendarSelDate', (data) => {
    console.log('监听calendarSelDate', data)
  })

  //卡片更多跳转
  EventBus.on('cartMoreLink', (linkurl, linktype) => {
    console.log('监听cartMoreLink', linkurl, linktype)
    if (linktype == 'router') {
      router.push(linkurl)
    }
  })

  //链接组件跳转
  EventBus.on('linkWidget', (linkurl, linktype) => {
    console.log('监听linkWidget', linkurl, linktype)
    if (linktype == 'router') {
      router.push(linkurl)
    }
  })

  //鱼骨图跳转
  EventBus.on('fishWidget', (linkurl) => {
    console.log('监听fishWidget', linkurl)
    router.push(linkurl)
  })

  //步骤跳转
  EventBus.on('stepsWidget', (id, linkurl) => {
    console.log('监听stepsWidget', id, linkurl)
    router.push(linkurl)
  })

  //地图marker点击事件
  EventBus.on('mapMarkerClick', (item) => {
    console.log('监听mapMarkerClick',item)
  })

})

//销毁
onBeforeUnmount(() => {
  EventBus.off('saveFormJson')
  EventBus.off('calendarSelDate')
  EventBus.off('cartMoreLink')
  EventBus.off('linkWidget')
  EventBus.off('fishWidget')
  EventBus.off('stepsWidget')
  EventBus.off('mapMarkerClick')
})
</scrip>

<style>
.dark {
  background: #252525;
  color: white;
}
.light {
  background-color: white;
  color: black;
}
</style>

三、Iframe外挂形式集成方案

这种模式说白了就是百搭,把低代码设计器当成一个在线工具,它是无状态的,不依赖任何前端和后端,高内聚低耦合,可集成任意平台.假以时日自定义扩展组件有上百个时,完全可以独当一面成为一方霸主,独立产品。

平台集成使用Iframe,把页面设计器嵌入到自己页面中,通过postMessage方式与父页面进行通信,父页面可以获取到设计器生成的页面JSON,也可以把token传给设计器

3.1 数据通信使用 postMessage 方式

父页面(对接平台)通过 postMessage 向子页面发送数据,这里主要传token ,子页面(页面设计引擎组件) 使用 window.addEventListener 监听并接收数据

3.2 Vue3组合式 集成demo

<template>
  <div v-loading="loading" class="iframe-container">
    <iframe
      ref="myIframe"
      id="iframe"
      :src="src"
      frameborder="0"
      width="100%"
      height="730px"
      @load="onIframeLoad"
    ></iframe>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
const loading = ref(true)
const src = ref('https://www.nbweixin.cn/autopage/')

const myIframe = ref(null)

//模拟数据库数据
const demoObj = {
  Id: 31908,
  Title: '测试标题',
  Number: 'page_31908',
  Desc: '这是一个空的页面模板',
  JsonObj: {} //对象或者字符串
}

// 监听 iframe 是否加载完成
const onIframeLoad = () => {
  console.log('Iframe 已加载完成')
  loading.value = false
  sendMessageToIframe()
}

const sendMessageToIframe = () => {
  // 要发送的数据
  const dataToSend = {
    iframeToken: 'token_test', //自定义token
    iframeFormData: JSON.stringify(demoObj), //页面JSON,新增的话JsonObj留空就行
  }
  // 使用 postMessage 发送数据给 iframe
  myIframe.value.contentWindow.postMessage(dataToSend, '*')
}

//监听iframe 内部透传事件
let pageengineEvent = null
pageengineEvent = function (event) {
  if (event.data) {
    switch (event.data.key) {
      //保存页面json
      case 'saveFormJson':
        console.log('已接到到来自iframe消息,saveFormJson', event.data.value)
        let obj = JSON.parse(event.data.value)
        console.log(obj)
        break
      //监听日历选择日期事件
      case 'calendarSelDate':
        console.log('已接到到来自iframe消息,calendarSelDate', event.data.value)
        break
      //监听日历选择日期事件
      case 'calendarSelDate':
        console.log('已接到到来自iframe消息,calendarSelDate', event.data.value)
        break
      //卡片更多跳转
      case 'cartMoreLink':
        console.log(
          '已接到到来自iframe消息,cartMoreLink 监听',
          event.data.value
        )
        break
      //链接组件跳转
      case 'linkWidget':
        console.log('已接到到来自iframe消息,linkWidget', event.data.value)
        break
      //鱼骨图跳转
      case 'fishWidget':
        console.log('已接到到来自iframe消息,fishWidget', event.data.value)
        break
      //步骤跳转
      case 'stepsWidget':
        console.log('已接到到来自iframe消息,stepsWidget', event.data.value)
        break
      //地图maker点击事件
      case 'mapWidget':
        console.log('已接到到来自iframe消息,mapWidget', event.data.value)
        break
      default:
        break
    }
  }
}
window.addEventListener('message', pageengineEvent)
onMounted(() => {})

onBeforeUnmount(() => {
  window.removeEventListener('message', pageengineEvent)
})
</script>

<style lang="scss" scoped></style>

四、在线office文档编辑器

4.1 Vue3 npm包集成

使用方法,注册引用 webOffice 组件,必填参数 url ,其它参数非必填。

<template>
  <webOffice :url="url"></webOffice>
</template>
<script setup name="weboffice">
 
import { webOffice } from 'microi-pageengine' 

let url =
  'https://www.nbweixin.cn/autopage/%E9%99%84%E5%BD%95A-4%20%E7%AB%8B%E9%A1%B9%E8%AF%84%E5%AE%A1%E6%8A%A5%E5%91%8A.doc'
let title = '附录A-4 立项评审报告.doc' //选填
let key = '附录A-4 立项评审报告.doc' //选填
let server = 'http://192.168.93.128:9000' //选填
</script>

<style lang="scss" scoped></style>

4.2 Iframe 调用office

使用方法,在自己的页面引入 iframe ,通过 postMessage 消息传递,必填参数 url ,其它参数非必填。

参数解读:

const demoObj = {
  url: ' ', //文件地址,支持word、excel、ppt (必填)
  title: '', //文件标题,可留空
  key: '',//唯一值,可留空
  server: '', //服务地址,可留空
}

demo示例:

<template>
  <div v-loading="loading" class="iframe-container">
    <iframe
      ref="myIframe"
      id="iframe"
      :src="src"
      frameborder="0"
      width="100%"
      height="730px"
      @load="onIframeLoad"
    ></iframe>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
const loading = ref(true)

const src = ref('https://www.nbweixin.cn/autopage/weboffice')

const myIframe = ref(null)

//模拟数据库数据
const demoObj = {
  url: 'https://www.nbweixin.cn/autopage/%E9%99%84%E5%BD%95A-4%20%E7%AB%8B%E9%A1%B9%E8%AF%84%E5%AE%A1%E6%8A%A5%E5%91%8A.doc',
  title: '',
  key: '',
  server: '',
}

// 监听 iframe 是否加载完成
const onIframeLoad = () => {
  console.log('Iframe 已加载完成')
  loading.value = false
  sendMessageToIframe()
}

const sendMessageToIframe = () => {
  // 要发送的数据
  const dataToSend = {
    officeData: JSON.stringify(demoObj),
  }
  // 使用 postMessage 发送数据给 iframe
  myIframe.value.contentWindow.postMessage(dataToSend, '*')
}

onMounted(() => {})

onBeforeUnmount(() => {})
</script>

<style lang="scss" scoped></style>
1.2.6

6 months ago

1.2.5

9 months ago

1.2.4

9 months ago

1.2.2

9 months ago

1.2.1

9 months ago

1.2.0

9 months ago

1.1.9

9 months ago

1.1.8

9 months ago

1.1.7

9 months ago

1.1.6

9 months ago

1.1.5

10 months ago

1.1.4

10 months ago

1.1.3

10 months ago

1.1.2

10 months ago

1.1.1

10 months ago

1.1.0

10 months ago

1.0.8

10 months ago

1.0.7

10 months ago

1.0.6

10 months ago

1.0.5

10 months ago

1.0.4

10 months ago

1.0.3

10 months ago

1.0.2

10 months ago

1.0.1

10 months ago

1.0.0

10 months ago