制作插件

这里我们做一个DOM插件(可以自定义HTML代码的图层)

新建插件文件

|-- dom
    |-- Editor.jsx // 编辑部分
    |-- Origindata.js // 原始数据类
    |-- layerdom.js // jsx模版数据
    |-- phone.js // 手机端执行的代码
    |-- phone.less // 在手机端的组件样式
    |-- editor.less // 编辑器部分的样式
    |-- index.js // 方法的汇总

编写Origindata.js

/**
* @desc 原始数据类,原始数据是插件对应的一个对象数据,对象数据是一个类来实现的。
* 每次新建图层都会去new Origindata(); 获取new出来的实例对象数据,原始数据具体介
* 绍见 **3.2. data** 相关介绍。
*/
export class Origindata {
    constructor() {
        this.id = null; // 原始数据id。
        this.type = 'dom'; // 插件类型,必须确保唯一,且按照变量的命名规范
        this.animate = []; // 插件默认动画队列
        this.data = '<div>DOM</div>'; // 插件默认数据
        this.estyle = {}; // .element 样式
        this.style = { // .layer 样式
            width: 200,
            height: 100,
            top: 0,
            left: 0
        };
        this.color = ''; // 预留项
        this.ue = {}; // 交互配置
    }
}

编写layerdom.js

/**
* @desc 模版数据,最终会通过这个生成HTML代码
* @param layer{object} 图层对应的数据和原始数据格式一致。
* @param zIndex{number} 图层的z-index。
* @param layerfun{object} H5DS组件上面的参数集合。
* @param scene{object} 组件所在的场景。{ isMinPage, isPhoneView, isView }
    isMinPage===true表示在左侧小预览区域渲染,isPhoneView===true表示在中间操作区域渲染。
    isView表示在发布预览区域渲染。
* @return jsx 模版
*/
export function layerdom(layer, zIndex, layerfun, scene) {
    return <div className="dom-inner" dangerouslySetInnerHTML={{ __html: layer.data }} />;
}

编写Editor.jsx

import './style.less';

import React, { Component } from 'react';

import { Input } from 'antd';
import debounce from 'lodash/debounce';

const { TextArea } = Input;

/**
 * @desc dom 插件
 */
export default class Editor extends Component {
    constructor(props) {
        super(props);
        // 数据转由state管理。如果layer.data是object或者array 可以使用mobx的 toJS 转化
        this.state = {
            data: props.layer.data
        };
    }

    changeTextArea = e => {
        this.setState({ data: e.target.value });
        this.renderLayer();
    };

    // 更新视图,使用防抖函数做优化,因为layer由mobx管理,data重新赋值后会自动触发页面渲染
    renderLayer = debounce(() => {
        this.props.layer.data = this.state.data;
        $(document).trigger('h5ds.setHistory');
    }, 500);

    componentDidMount() {
        // h5ds.centerRenderEnd 是一个全局事件,如果中间的可视页面发生更新,会自动触发该事件
        $(document).on(
            'h5ds.centerRenderEnd',
            debounce(() => {
                console.log('重新渲染phone页面');
            }, 500)
        );
    }

    componentWillUnmount() {
        $(document).off('h5ds.centerRenderEnd');
    }

    render() {
        const { data } = this.state;
        return (
            <div className="ex-set-dom">
                <TextArea onChange={this.changeTextArea} placeholder="请填写HTML" rows={8} value={data} />
            </div>
        );
    }
}

编写phone.js

tips: phone.js 是在手机端以及发布预览时候运行的代码,所以这里要单独处理,这里没有再使用react,phone.js 必须继承编辑器提供的 H5DSComponent 类,这个类必须要设置一个静态参数 type = '插件类型名称'。该方法提供了3个默认方法(didMount, oneDidMount, willMount, willUnmount).页面进入的时候,插件会走渲染流程。见图

比如这样页面显示的时候,里面包括了图片图层(艺术字,花瓣),文字图层(促销文字500元),在滑动到这个页面的时候,所有的图层都会执行 willMount -> (didMount,oneDidMount) 方法,页面离开的时候,会执行 willUnmount 方法。


import './phone.less';
import { H5DSComponent } from '../plusClasses.js';

// 手机端执行
export default class PhoneDom extends H5DSComponent {
    static type = 'dom';

    constructor(props) {
        super(props);
    }

    willMount() {
        console.log('插件渲染前执行', this.props.target);
    }

    oneDidMount() {
        console.log('插件渲染后执行,且只执行一次,下次进入不会再执行', this.props.target);
    }

    didMount() {
        console.log('插件渲染后执行', this.props.target);
    }

    willUnmount() {
        console.log('插件被卸载前执行', this.props.target);
    }
}

编写index.js

制作完上面的代码后,别忘记less文件哟。我们需要对外提供一个入口

import React from 'react';
import { Origindata } from './Origindata';
import { layerdom } from './layerdom';
import Editor from './Editor';
import { didMount } from './didMount';

export default {
    type: 'dom',
    name: 'DOM',
    icon: <i className="h5ds ico5-domnode" />,
    editor: Editor, // 图层独有的编辑区域
    layerdom, // 图层对应生成的HTML
    origindata: Origindata, // 图层对应的json数据
    didMount // 图层挂载后执行, 这里的 didMount 只在PC端执行,不会在做好之后的页面中执行,做好后的页面只会执行phone.js 里面的代码
};

以上做完之后。一个插件就开发好了。是不是很简单!接下来就是使用插件环节了!

results matching ""

    No results matching ""