微页面设计开发指南
发布于 2021-01-13 09:02
一、目标实现
左侧:为可用的组件列表,可拖动任一组件到中间的预览区域
中间:为页面预览效果页面,选中任一组件,可在右侧进行参数配置
右侧:为组件的参数配置(选中中间的组件时出现),页面配置(选中页面管理tab按钮时出现),组件管理(选中组件管理tab时出现),更改配置,中间的预览区域立即更新视图
二、开发设计规范
后台部分
管理后台文件目录结构
1. 可将以上的页面进行模块拆分:
components目录放一些常用的组件,leftComponentsPage.vue和rightConfigPage.vue分别为左侧和右侧的集成组件
configComponents目录是右侧显示的对应组件和页面的配置相关的组件,每个组件对应一个配置,封装成对应的组件
viewComponents目录放置组件对应的样式结构代码,每个组件封装成一个样式组件,名称和配置组件一一对应
details.vue为整合页面,分别调用左侧的leftComponentsPage.vue组件和右侧的rightConfigPage.vue组件,以及中间预览遍历组件按需加载样式组件
2. 数据流方向
3. 组件数据格式
以图片组件为例:
{
"image":{
"showMethod":"YHYG", // 显示的排列方式,一行一个
"borderWidth":0,
"pageMargin":0,
"maxImageNum":10,
"cornerType":"ZJ",
"imageType":"normal",
"showNum":6,
"indicator":"style1",
"items":[
{
"title":"",
"imageUrl":"",
"imageWidth":345,
"imageHeight":241,
"action":"webview",
"maAppid":"",
"maPagePath":"",
"extLink":"",
"actionArea":"hotArea",
"hotAreas":{
"width":100,
"height":100,
"xAxis":128,
"yAxis":63
}
}
]
}
}
image下面为组件的属性,由云端接口直接返回,items下面的每一项对应单个图片属性,右侧配置区域可对每个属性进行配置,每上传一张图片,往items里增加一项
4. 视图组件结构和对应样式
<template>
<!-- 组件1:图片组件 -->
<div class="component-wrapper image-component" :style="wrapperStyle">
<div class="image-list">
<div :style="imgItemStyle" class="image-item" v-for="(img, imgIndex) in imgObject.items" :key="imgIndex">
<img class="image" :src="img.imageUrl ? img.imageUrl : defaultImg">
<div :class="['hotarea', debugMode ? 'debug' : '' ]" :style="img.hotAreaStyle"
@click="redirectPageTo(img.action, img.extLink, img.maAppid, img.maPagePath)" v-if="img.action !== 'nothing'">
</div>
</div>
</div>
</div>
</template>
类名为component-wrapper的图层为最外层,宽度为屏幕宽度100%(后台预览页面宽度定为375px),为这个图层设置左右padding值为组件传过来的pageMargin的大小
computed: {
wrapperStyle() {
return {
padding-left: this.comData.image.pageMargin + 'px',
padding-right: this.comData.image.pageMargin + 'px'
}
}
}
computed: {
imgObject() {
this.comData.image.items.map((item) => {
if (item.action !== 'nothing') {
item.hotAreaStyle = {
width: (item.actionArea === 'hotArea' ? item.hotAreas.width : item.imageWidth) + 'px',
height: (item.actionArea === 'hotArea' ? item.hotAreas.height : item.imageHeight) + 'px',
left: item.actionArea === 'hotArea' ? item.hotAreas.xAxis + 'px' : 0 ,
top: item.actionArea === 'hotArea' ? item.hotAreas.yAxis + 'px' : 0
}
}
})
return this.comData.image
}
}
主页面放在subpackage下面的microPage下
<view class="page-com" wx:for="{{ comData }}" wx:for-item="item" wx:key="index" wx:if="{{ pageStatus === 'ON' && pageDelete === 'NORMAL' }}">
<!-- 图片组件渲染 -->
<image-view comData="{{ item.components }}" wx:if="{{ item.comType === 'image' }}" />
<!-- 按钮组件渲染 -->
<button-view comData="{{ item.components }}" wx:if="{{ item.comType === 'btn' }}" />
<!-- 悬浮组件渲染 -->
<absolute-view comData="{{ item.components }}" showCom="{{ showCom }}" wx:if="{{ item.comType === 'absolute' }}" />
</view>
循环遍历传过来的页面组件数据,渲染不同的组件拿image图片组件举例,它的结构代码
<!-- 组件1:图片组件 -->
<view class="component-wrapper image-component" style="{{ wrapperStyle }}">
<view class="image-list">
<view class="image-item" wx:for="{{ imgObject.items }}" wx:for-index="imgIndex" wx:for-item="img"wx:key="imgIndex">
<image class="image" src="{{ img.imageUrl }}" style="width: {{ img.imageWidth }}px;" wx:if="{{ img.imageUrl }}" mode="widthFix"></image>
<view class="hotarea" style="{{ img.hotAreaStyle }}" wx:if="{{ img.action !== 'nothing' }}"bindtap="redirectPageTo" data-com="{{ img }}"></view>
</view>
</view>
</view>
attached() {
this.data.comData.image.items.map((item) => {
if (this.data.comData.image.action !== 'nothing') {
let width = item.actionArea === 'hotArea' ? item.hotAreas.width : item.imageWidth
let height = item.actionArea === 'hotArea' ? item.hotAreas.height : item.imageHeight
let left = item.actionArea === 'hotArea' ? item.hotAreas.xAxis : 0
let top = item.actionArea === 'hotArea' ? item.hotAreas.yAxis : 0
item.hotAreaStyle = 'width: ' + app.pxToRpx(width) + 'rpx;height: ' +
app.pxToRpx(height) + 'rpx;left: ' + app.pxToRpx(left) + 'rpx;top: ' + app.pxToRpx(top) + 'rpx;'
}
})
this.setData({
wrapperStyle: 'padding: 0 ' + app.pxToRpx(this.data.comData.image.pageMargin) + 'px',
imgObject: this.data.comData.image
})
}
像素单位转化方法封装在app下
pxToRpx(value) {
return value * (750 / this.globalData.system.windowWidth);
}
三、开发步骤
后台部分
1. 增加组件图标
首先在leftComponentsPage.vue为该组件指定显示的图标
comList(val) {
val.map((item) = >{
switch (item.type) {
case 'image':
item.icon = 'pic';
break;
case 'absolute':
item.icon = 'absolutebtn';
break;
case 'btn':
item.icon = 'operation';
break;
default:
item.icon = 'pic'
break;
}
}) this.buildComList = val
}
2. 给组件增加配置文件
在configComponents目录下新增 组件名.vue 对应的配置文件,然后在components下的rightConfigPage.vue中引入该组件
<!-- 组件配置 -->
<div v-else-if="activeBtn === 'com'">
<!-- 1、图片组件 -->
<image-config v-if="previewComList[selectedComIndex].type === 'image'"
v-on="$listeners"
:configData="previewComList[selectedComIndex]"></image-config>
<!-- 2、悬浮按钮组件 -->
<absolute-config v-if="previewComList[selectedComIndex].type === 'absolute'"v-on="$listeners"
:configData="previewComList[selectedComIndex]"></absolute-config>
<!-- 3、按钮组件 -->
<btn-config v-if="previewComList[selectedComIndex].type === 'btn'"
v-on="$listeners"
:configData="previewComList[selectedComIndex]"></btn-config>
</div>
配置文件通过props接收传过来的configData数据,赋值给本地的data里面的configs,配置文件里的input通过v-mode监听改变configs,然后通过监听configs数据调用$emit调用父组件传过来的方法,达到数据从父组件 -> 孙子组件 -> 父组件的响应式
3. 给预览页面增加组件
在viewComponents下新建组件名.vue文件,然后在detail.vue中引入
<div :style="{position: 'relative'}" v-for="(com, comIndex) in previewComList" :key="comIndex">
<div :class="['com-area', selectedComIndex === comIndex ? 'border-selected' : '']" @click="selectCom(com, comIndex)">
<!-- 组件1:图片组件 -->
<image-view :comData="com.configObj" :debugMode="debug" v-if="com.type ==='image'"></image-view>
<!-- 组件2:悬浮按钮组件 -->
<absolute-view :comData="com.configObj" :debugMode="debug" v-if="com.type ==='absolute'"></absolute-view>
<!-- 组件删除按钮 -->
<div v-if="selectedComIndex === comIndex" class="delete-com-btn"
@click="deleteCom(com, comIndex)">
<i class="el-icon-delete"></i>
</div>
</div>
1. 增加组件对应的视图组件
在根目录custom-components下面的landingPage下新建以组件名命名的目录,里面包含js,json,wxml,wxss文件,在subpackage/landingPage/index.json中引入该组件
"usingComponents": {
"image-view": "../../custom-components/landingPage/image/index",
"button-view": "../../custom-components/landingPage/button/index",
"absolute-view": "../../custom-components/landingPage/absolute/index"
}
在subpackage/landingPage/index.wxml文件中增加组件代码
<!-- 图片组件渲染 -->
<image-view comData="{{ item.components }}" wx:if="{{ item.comType === 'image' }}" />
最终实现
四. 注意事项
本文来自网络或网友投稿,如有侵犯您的权益,请发邮件至:aisoutu@outlook.com 我们将第一时间删除。
相关素材