低代码平台开发六

获取拖到内容区组件的焦点,点击显示红色虚线框,其可以选择多个组件

1.绑定onMousedown事件,EditorComp.jsx代码

import { computed, defineComponent, inject, ref } from "vue";
import './editor.scss'
// import { inject } from 'vue'
import EditorBlock from "./EditorBlock";
import { useMenuDragger } from "./useMenuDragger";
import GridLine from "./GridLine.vue";
export default defineComponent({
    props: {
        modelValue: { type: Object }
    },
    emits:["update:modelValue"],
    setup(props,ctx) {
        // console.log(props.modelValue)
        const config = inject('config')
        const data = computed({
            get() {
                return props.modelValue
            },
            set(newValue){
                //抛出更改后的值
                ctx.emit('update:modelValue',newValue)
            }
        })
        // console.log('data', data)
        //内容区宽高
        const containerStyle = computed(() => ({
            width: data.value.container.width + 'px',
            height: data.value.container.height + 'px'
        }))
        
        //获取拖拽和目的地元素
        const containerRef = ref(null)
        //1.封装拖拽方法
        const {dragstart,dragend} = useMenuDragger(data,containerRef)
        //2.实现获取内容区组件焦点
        const blockClear = ()=>{
            data.value.blocks.forEach(block=>block.focus = false)
        }
        const mousedown = (e,block)=>{
            console.log('鼠标点击了目标元素',block)
            console.log('鼠标点击了目标元素',e)
            if(!block.focus){
                blockClear()  //清空所有组件点击效果
                block.focus = true  //点击组件获取焦点
            }else{
                block.focus = false
            }
        }
        //3.实现拖拽多个组件
       
        return () =>
            <div class="editor">
                <div class="editor-left">
                    {config.componentList.map(component => (
                        <div class="editor-left-item" 
                            draggable
                            onDragstart={e => dragstart(e,component)}
                            onDragEnd={dragend}
                        >
                            <span>{component.label}</span>
                            <div>{component.preview()}</div>
                        </div>

                    ))}
                </div>
                <div class="editor-top">编辑区</div>
                <div class="editor-right">属性区</div>
                <div class="editor-container">
                    {/* 生成滚动条 */}
                    <div class="editor-container-canvas" >
                        {/* 内容区 */}
                        <div class="editor-container-canvas_content" 
                        ref={containerRef}
                        
                        style={containerStyle.value}>
                            {/* 网格线 */}
                            <GridLine></GridLine>
                            {
                                //抽出去作为一个组件
                                /* {
                                    (data.value.blocks.map(() => (
                                        <div>这是一个代码块</div>
                                    )))
                                } */
                                (data.value.blocks.map(block=>(
                                    <EditorBlock 
                                    class={block.focus? 'editor-block-focus':''}
                                    block={block}
                                    data={data}
                                    onMousedown={e=>mousedown(e,block)}
                                    ></EditorBlock>
                                )))
                            
                            }
                        </div>
                    </div>
                </div>
            </div>

    }
})

2.点击获取焦点后显示红色虚线框,editor.scss代码

.editor {
    width: 100%;
    height: 100%;

    &-left {
        position: absolute;
        width: 270px;
        background-color: rgb(178, 203, 203);
        top: 0;
        bottom: 0;


        &-item {
            display: flex;
            justify-content: center;
            align-items: center;
            width: 250px;
            padding: 20px;
            box-sizing: border-box;
            margin: 20px auto;
            background: white;
            cursor: move;
            position: relative;
            min-height: 100px;

            >span {
                position: absolute;
                top: 0;
                left: 0;
                color: white;
                padding: 4px;
                background-color: deepskyblue;
            }

            // >div{
            //     border: 2px solid black;
            // }
            &::after {
                content: '';
                position: absolute;
                top: 0;
                bottom: 0;
                left: 0;
                right: 0;
                background-color: #ccc;
                opacity: 0.2;
            }
        }

    }

    &-right {
        position: absolute;
        width: 270px;
        background-color: aqua;
        top: 0;
        bottom: 0;
        right: 0;

    }

    &-top {
        position: absolute;
        height: 80px;
        top: 0;
        left: 280px;
        right: 280px;
        background-color: rgb(175, 86, 188);
        display: flex;
        justify-content: center;
        align-items: center;

    }

    &-container {
        position: absolute;
        top: 90px;
        left: 280px;
        right: 280px;
        bottom: 0;
        background-color: rgb(121, 172, 167);

        &-canvas {
            overflow: scroll;
            height: 100%;

            &_content {
                margin: 5px auto;
                // width: 550px;
                // height: 550px;
                background-color: white;
                position: relative;
            }
        }
    }

    .editor-block {
        position: absolute;
        &::after {
            position: absolute;
            content: '';
            top: 0;
            bottom: 0;
            left: 0;
            right: 0;
        }
    }

    .editor-block-focus {
        &::after {
            border: 1px dashed red;
        }
    }
}

3.点击单个组件,网页渲染效果

3.按住shift键,点击多个组件

mousedown更改为

const mousedown = (e,block)=>{
            e.preventDefault();
            e.stopPropagation();
            // console.log('鼠标点击了目标元素',block)
            // console.log('鼠标点击了目标元素',e)
            if(e.shiftKey){
                block.focus = !block.focus  //按住shift键,选中多个组件
            }else{
                if(!block.focus){
                    blockClear()  //清空所有组件点击效果
                    block.focus = true  //点击组件获取焦点
                }else{
                    block.focus = false
                }
            }
            
        }

效果图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值