当前位置: 首页 > news >正文

外贸常用网站磁力帝

外贸常用网站,磁力帝,网站建设七点,建网站地址编辑器主要分为三部分,左侧是组件模板库,中间是画布区域,右侧是面板设置区域。 左侧是预设各种组件模板进行添加 中间是使用交互手段来更新元素的值 右侧是使用表单的方式来更新元素的值。 大致效果: 左侧组件模板库 最初的模板…

编辑器主要分为三部分,左侧是组件模板库,中间是画布区域,右侧是面板设置区域。
左侧是预设各种组件模板进行添加
中间是使用交互手段来更新元素的值
右侧是使用表单的方式来更新元素的值。
大致效果:
在这里插入图片描述

  1. 左侧组件模板库
    最初的模板配置:
export const defaultTextTemplates = [{text: '大标题',fontSize: '30px',fontWeight: 'bold',tag: 'h2'},{text: '楷体副标题',fontSize: '20px',fontWeight: 'bold',fontFamily: '"KaiTi","STKaiti"',tag: 'h2'},{text: '正文内容',tag: 'p'},{text: '宋体正文内容',tag: 'p',fontFamily: '"SimSun","STSong"'},{text: 'Arial style',tag: 'p',fontFamily: '"Arial", sans-serif'},{text: 'Comic Sans',tag: 'p',fontFamily: '"Comic Sans MS"'},{text: 'Courier New',tag: 'p',fontFamily: '"Courier New", monospace'},{text: 'Times New Roman',tag: 'p',fontFamily: '"Times New Roman", serif'},{text: '链接内容',color: '#1890ff',textDecoration: 'underline',tag: 'p'},{text: '按钮内容',color: '#ffffff',backgroundColor: '#1890ff',borderWidth: '1px',borderColor: '#1890ff',borderStyle: 'solid',borderRadius: '2px',paddingLeft: '10px',paddingRight: '10px',paddingTop: '5px',paddingBottom: '5px',width: '100px',tag: 'button',textAlign: 'center'}
]

在component-list组件中循环渲染这个模板
compnent-list组件:

<divclass="component-item"v-for="(item, index) in props.list"@click="onItemClick(item)":key="index"
><LText v-bind="item"></LText>
</div>// LText组件
<component class="l-text-component" :is="props.tag" :style="styleProps" @click="handleClick">{{ props.text }}
</component>
  1. 中间画布区
    基本的数据结构
export interface ComponentData {props: { [key: string]: any }id: stringname: string
}

在左侧模板区域点击的时候,会emit一个onItemCreated事件:

const onItemCreated = (props: ComponentData) => {store.commit('addComponent', props)
}

store里面的addComponent方法:

addComponent(state, props) {const newComponent: ComponentData =id: uuidv4(),name: 'l-text',props}state.components.push(newComponent)
},

渲染中间画布区域:

<div v-for="component in components" :key="component.id"><EditWrapper v-if="!component.isHidden":id="component.id"@set-active="setActive":active="component.id === (currentElement && currentElement.id)" :props="component.props"><component :is="canvasComponentList[component.name as 'l-text' | 'l-image' | 'l-shape']" v-bind="component.props" :isEditing="true"/></EditWrapper></div>

editWrapper组件就是为了隔离两个组件,方便后续的一些拖拽,拉伸,吸附的一些效果。

<template>
<div class="edit-wrapper" @click="itemClick"@dblclick="itemEdit"ref="editWrapper":class="{active: active}" :style="styleProps":data-component-id="id"
> <!-- 元素的扩大 --><div class="move-wrapper" ref="moveWrapper" @mousedown="startMove"><slot></slot></div><div class='resizers'><div class='resizer top-left' @mousedown="startResize($event, 'top-left')"></div><div class='resizer top-right'  @mousedown="startResize($event, 'top-right')"></div><div class='resizer bottom-left' @mousedown="startResize($event, 'bottom-left')"></div><div class='resizer bottom-right' @mousedown="startResize($event, 'bottom-right')"></div></div>
</div>
</template>
  1. 右侧设置面板区域的渲染:
    在中间画布区域进行点击的时候,通过setActive事件,我们可以拿到当前的元素,
// store中的setActive
setActive(state, currentId: string) {state.currentElement = currentId;
},

然后就可以通过props-table组件进行渲染了:

<PropsTable v-if="currentElement && currentElement.props" :props="currentElement.props"@change="handleChange"
></PropsTable>

props-table比较麻烦我们来一一讲解,首先来看一下props-talbe的template部分:

<template><div class="props-table"><divv-for="(value, key) in finalProps":key="key":class="{ 'no-text': !value.text }"class="prop-item":id="`item-${key}`"><span class="label" v-if="value.text">{{ value.text }}</span><div :class="`prop-component component-${value.component}`"><component:is="value.component":[value.valueProp]="value.value"v-bind="value.extraProps"v-on="value.events"><template v-if="value.options"><component:is="value.subComponent"v-for="(option, k) in value.options":key="k":value="option.value"><render-vnode :vNode="option.text"></render-vnode></component></template></component></div></div></div>
</template>

我们最终渲染的是finalProps这个数据,finalProps数据的生成:

// 属性转化成表单的映射表 key:属性  value:使用的组件
export const mapPropsToForms: PropsToForms = {// 比如: text 属性,使用 a-input 这个组件去编辑text: {text: '文本',component: 'a-input',afterTransform: (e: any) => e.target.value,},fontSize: {text: '字号',component: 'a-input-number',// 为了适配类型,进行一定的转换initalTransform: (v: string) => parseInt(v),afterTransform: (e: number) => e ? `${e}px` : '',},lineHeight: {text: '行高',component: 'a-slider',extraProps: {min: 0,max: 3,step: 0.1},initalTransform: (v: string) => parseFloat(v)},textAlign: {component: 'a-radio-group',subComponent: 'a-radio-button',text: '对齐',options: [{value: 'left',text: '左'},{value: 'center',text: '中'},{value: 'right',text: '右'}],afterTransform: (e: any) => e.target.value},fontFamily: {component: 'a-select',subComponent: 'a-select-option',text: '字体',options: [{value: '',text: '无'},...fontFamilyOptions],afterTransform: (e: any) => e},color: {component: 'color-pick',text: '字体颜色',afterTransform: (e: any) => e}
}
const finalProps = computed(() => {// reduce是使用loadsh里面的return reduce(props.props,(result, value, key) => {const newKey = key as keyof AllComponentProps;const item = mapPropsToForms[newKey];if (item) {// v-model默认绑定的值,是value,可以自定义// v-model双向数据绑定的事件,默认是change事件,也可以自定义// initalTransform编辑前的value转换,为了适配类型,进行一定的转换// afterTransform 处理上双向数据绑定后的值。const {valueProp = 'value',eventName = 'change',initalTransform,afterTransform,} = item;const newItem: FormProps = {...item,value: initalTransform ? initalTransform(value) : value,valueProp,eventName,events: {[eventName]: (e: any) => {context.emit('change', {key,value: afterTransform ? afterTransform(e) : e,});},},};result[newKey] = newItem;}return result;},{} as { [key: string]: FormProps });
});

我们传递的props值是这样的:
在这里插入图片描述
最终转换成出来的值是这样的
在这里插入图片描述
在这里插入图片描述
当组件内的change事件改变后,组件内部会触发

context.emit('change', { key, value: afterTransform ? afterTransform(e) : e,});

在父组件中接收change事件来改变stroe中的compoents的值

const handleChange = (e) => {console.log('event', e);store.commit('updateComponent', e)
}

在store中改变components属性

updateComponent(state, { id, key, value, isProps}) {const updatedComponent = state.components.find((component) => component.id === (id || state.currentElement)) as anyif(updatedComponent) {updatedComponent.props[key as keyof TextComponentProps] = value;}
}

难点:

http://www.yayakq.cn/news/465550/

相关文章:

  • 网站开发职业生涯规划范文阿里云宝塔面板一键安装wordpress
  • 郑州网站建设公司电话上海网站建设公司排名
  • 公司的网站建设费入什么科目全球网站开发者大会
  • 中国机械加工网订单临沂seo推广外包
  • 深圳企业网站建设优惠长沙房地产新政策
  • 彩票网站net网站开发网站购物车代码怎么做
  • 网站快照不更新原因seo如何优化关键词排名
  • 网站管理助手哪个好用鸿星尔克网络营销案例分析
  • 开发个网站多少钱产品界面设计
  • 长春高端模板建站互联网推广平台
  • 影视网站建设的总体目标网站为什么吸引人
  • 沈阳网站建设哪家做得好怎样做互联网推广
  • 做衣服的网站推荐视频网站开发意义
  • 网站建设公司不让放自己空间站毕业设计做一个网站怎么做
  • dm网站制作软件小型公司网站建设
  • 列车营销网站怎么做做美食网站首页怎么做
  • 企业网址是什么?裤子seo优化标题
  • 做网站充值微信必须是企业iapp登录wordpress
  • 大型地方门户网站源码长春关键词优化
  • 龙华龙岗网站建设公司徐州网站开发设计公司电话
  • ruhe用dw做网站搜索推广渠道
  • 基于php的网站建设思路方案网页配色设计手册
  • 忘记网站后台admin密码网店装修教程
  • 织梦网站2个模型手机网站开发者模式
  • 做网站就用建站之星延安软件开发公司
  • 行业网站制作wordpress硬件接口
  • 郑州 网站 公司那些网站布局好看
  • 淘宝可做的团购网站郑州 中原区
  • 做seo网站的公司哪家好安装网站模版视频
  • 提高网站的权重的最佳方法站长素材官网