从零搭建低代码平台(六)实现预览区组件获取焦点功能

目录

大体介绍

主要思路

创建useFocus.js用来改变focus属性

在editor.js中进行引用

预期结果


大体介绍

在上一篇文章中,我们实现了预览区中的组件的展示功能,接下来我们打算实现组件的获取焦点的功能,为之后预览区组件的拖拽功能做伏笔。

主要思路

我们可以首先获取data中的数值,遍历data中blocks数组,获取点击组件的下标,将该组件blocks中的属性focus改为true,同时为组件的容器添加一个css样式,当且仅当focus为true的时候可以显示,这样,我们就可以在进行鼠标点击的时候,显示出想要的css样式,从而获取预览区组件获取焦点的功能。

创建useFocus.js用来改变focus属性

// 实现获取焦点
import {computed, ref} from "vue";

export function useFocus(data,callback) {

    const selectIndex = ref(-1);

    const lastSelectBlock = computed(() => data.value.blocks[selectIndex.value])

    const focusData = computed(() => {
        let focus = [];
        let unfocused = [];
        data.value.blocks.forEach(block => (block.focus ? focus : unfocused).push(block));
        return {focus, unfocused}
    });

    const clearBlockFocus = () => {
        data.value.blocks.forEach(block => block.focus = false)
    }
    const containerMousedown = (e) => {
        e.preventDefault();
        e.stopPropagation();
        if (e.button === 0) {
            clearBlockFocus();
            selectIndex.value = -1;
        }
    }

    const blockMousedown = (e, block, index) => {
        e.preventDefault();
        e.stopPropagation();
        // console.log(e)
        if (e.button === 0) {
            // block上规划一个属性 focus 获取焦点后就将focus变为true
            if (e.shiftKey) {
                if (focusData.value.focus.length <= 1) {
                    block.focus = true
                } else {
                    block.focus = !block.focus;
                }
            } else {
                if (!block.focus) {
                    clearBlockFocus();
                    block.focus = true;
                }
            }
            selectIndex.value = index;
            // console.log(typeof (data.value.blocks[selectIndex.value]))
            callback(e)
        }
    }


    // window.addEventListener("blockMousedown", blockMousedown, { passive: false});

    return {
        blockMousedown,
        containerMousedown,
        focusData,
        lastSelectBlock,
    }
}

其中返回值有四个变量。

        blockMousedown:鼠标点击一个组件或者是shift+鼠标点击多个组件,这个函数实现了将一个组件或多个组件的blocks中的focus变为true

        containerMousedown:鼠标点击非组件的画布区域,这个函数实现了将一个组件或多个组件的blocks中的focus变为false

        focusData:这个数组中保存了所有blocks中focus为true的所有组件。

        lastSelectBlock:这个数最后一个点击的组件,亦或是最有一个focus变为true的组件数据

在editor.js中进行引用

let {blockMousedown, focusData, containerMousedown, lastSelectBlock} = useFocus(data, (e) => {
            mousedown(e)
            // console.log(JSON.stringify(attrs_style.value.attribute))
            // console.log(JSON.stringify(attrs_style.value.block))
        });



 <div class="editor-container-canvas">
                    {/*产生内容区域*/}
                    <div
                        class="editor-container-canvas_content"
                        style={containerStyles.value}
                        ref={containerRef}
                        onmousedown={containerMousedown}
                        oncontextmenu={containerRightClick}
                    >
                        <RightClick v-model={copyContent}/>
                        {/*网格线*/}
                        <Grid/>


                        {
                            (data.value.blocks.map((block, index) => {
                                // console.log(index)
                                return <EditorBlock
                                    // class={"iconfont icon-suo"}
                                    // cursor="move"
                                    class={block.lock ? 'iconfont icon-suo' : ''}
                                    class={block.focus ? 'editor-block-focus' : ''}
                                    block={block}
                                    data={data}
                                    index={index}
                                    onmousedown={(e) => e.target.className === 'editor-block' || e.target.className === 'editor-block editor-block-focus' || e.target.className === 'editor-block iconfont icon-suo' ? blockMousedown(e, block, index) : ''}
                                    onmouseover={(e) => e.target.className === 'editor-block' || e.target.className === 'editor-block editor-block-focus' || e.target.className === 'editor-block iconfont icon-suo' ? e.target.style.cursor = block.moveSign : ''}
                                    // onmouseover={(e) => e.target.children.length === 0 ? '' : e.target.children[0].style.cursor ='move'}
                                    // onmouseover={(e) => console.log(e.target.className)}
                                    oncontextmenu={(e) => blockRightClick(e, block)}
                                />
                            }))
                        }
                        {markLine.x !== null && <div class='line-x' style={{left: markLine.x + 'px'}}/>}
                        {markLine.y !== null && <div class='line-y' style={{top: markLine.y + 'px'}}/>}

                    </div>
                </div>

预期结果

单个组件获取焦点

多个组件获取焦点

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值