获取拖到内容区组件的焦点,点击显示红色虚线框,其可以选择多个组件
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
}
}
}
效果图