思路
- 点击 -> 记录鼠标点击的位置,距离目标元素的位置(left, top) -> 存放到React-redux;
- 拖动
- 放置 -> 取React-redux中记录的位置;
实现
一、子组件(被拖动)
import image from "@/assets/20200921.jpg";
import "./index.scss";
import { connect } from "react-redux";
function Child(props) {
const dragStart = (event) => {
let x = event.clientX - event.target.offsetLeft;
let y = event.clientY - event.target.offsetTop;
props.setMousePosition({ x, y });
event.dataTransfer.setData("Text", event.target.id);
};
return (
<>
<article id="drag1" draggable="true" onDragStart={dragStart}>
<section className="section" onMouseEnter={handleHover}>
<img className="image" src={image} alt="" />
<div className="card_content">
<span>{title}</span>
</div>
</section>
</article>
</>
);
}
const mapStateToProps = (state) => {
return {
state,
};
};
const mapDispatchToProps = (dispatch) => {
return {
setMousePosition: (mousePosition) => {
dispatch({ type: "SET_MOUSE_POSITION", mousePosition });
},
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Child);
二、父组件
import "./styles/App.css";
import Router from "./router";
import { connect } from "react-redux";
import Child from "./Child";
function App(props) {
const allowDrop = (event) => {
event.preventDefault();
};
const drop = (event) => {
event.preventDefault();
let data = event.dataTransfer.getData("Text");
let leftPx = event.clientX - props.state.mousePosition.x + "px";
let topPx = event.clientY - props.state.mousePosition.y + "px";
document.getElementById(data).style.left = leftPx;
document.getElementById(data).style.top = topPx;
};
return (
<div className="App" onDragOver={allowDrop} onDrop={drop}>
<Child />
</div>
);
}
const mapStateToProps = (state) => {
return {
state,
};
};
export default connect(mapStateToProps)(App);
三、React-redux
import { createStore } from "redux";
let initState = {
count: 0,
mousePosition: { x: 0, y: 0 },
};
function rootReducer(state = initState, action) {
switch (action.type) {
case "SET_MOUSE_POSITION":
return {
...state,
mousePosition: {
x: action.mousePosition.x,
y: action.mousePosition.y,
},
};
default:
return state;
}
}
let store = createStore(
rootReducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
export default store;