vue 드래그 동적 생 성 구성 요소 수요 실현

제품 수요
제품 수요 회 의 를 마치 고 하나의 수 요 를 만 났 습 니 다.먼저 페이지 는 두 칸 으로 나 뉘 어 있 고 왼쪽 에 데이터 구성 요 소 를 보 여 줍 니 다.드래그 정렬 을 지원 하고 단 추 를 누 르 면 구성 요 소 를 제거 합 니 다.오른쪽 은 구성 요소 의 미리 보기 그림 을 왼쪽으로 끌 어 당 겨 새로운 구성 요 소 를 만 드 는 것 을 지원 합 니 다.
사고의 방향
동적 생 성 구성 요소 에 있어 서 매번 새로운 구성 요 소 를 생 성 한다 면 구성 요 소 를 함수 에 넣 을 수 있 습 니 다 return.JSX 에서 함 수 를 호출 하면 호출 함수 마다 새로운 구성 요 소 를 되 돌려 줍 니 다.이것 은 React 에 있어 서 매우 간단 하지만 Vue 에 있어 서 구성 요 소 를 직접 되 돌려 주 는 것 은 불가능 하 다.비록 이 return 쓰기 가 Vue 에 적합 하지 않 지만 우 리 는 부인 할 수 없습니다.생각 이 매우 정확 하기 때문에 우 리 는 다른 쓰기 방법 을 고려 해 야 합 니 다.동적 생 성 구성 요소 에 대해 서 는 데이터 로 구성 요소 의 생 성 을 구동 해 야 합 니 다.끌 어 당 기 는 구성 요소 의 정렬 에 대해 서 는 끌 어 당 기 는 라 이브 러 리 를 사용 하면 됩 니 다!!
당면 한 문제
라 이브 러 리 의 선택
구성 요 소 를 어떻게 생 성 합 니까?
데이터 구동 동적 생 성 구성 요소
드래그 라 이브 러 리 선택
드래그 라 이브 러 리 여기 있 습 니 다.제 가 선택 한 것 은 프로젝트 에 존재 하 는 드래그 라 이브 러 리 Vue.draggable 점 입 니 다.만약 당신들 의 Vue 프로젝트 에 이 드래그 라 이브 러 리 를 사용 하지 않 았 다 면,당신들 은 스스로 이 글 의 디자인 방향 을 참고 할 수 있 습 니 다.
구성 요소 생 성 방법
여기 서 제 가 사용 하 는 것 은 Vue.extend()입 니 다.어떻게 사용 하 는 지 모 르 는 파트너 는 공식 문서 에서 확인 한 후에 이 글 을 배 워 보 세 요.Vue.extend.다음 에 우 리 는 구성 요 소 를 만 드 는 코드 를 쓰기 위해 js 파일 을 만 듭 니 다.
구성 요소 생 성

/* generateComponents.js     */

import Vue from "vue";

//          ,       。
import components1 from "./components/TestCom1.vue";
import components2 from "./components/TestCom2.vue";

//               Map
const comMap = {
  components1,
  components2,
};

//              ,         
// props,     
const ReturnNewCom = function ({ props, on }) {
  const {
    comItem: { name },
  } = props;
  const newComponent = Vue.extend({
    render(createElement) {
      //         name          。
      return createElement(comMap[name], {
        props,
        on,
      });
    },
  });
  return new newComponent();
};

export default ReturnNewCom;

구성 요소
여기 서 우 리 는 두 개의 구성 요 소 를 써 서 이 Demo 를 보 여 줍 니 다.각각 components 1.vue,components 2.vue 입 니 다.

/*components1.vue*/
<template>
  <div class="widget-wrapper">
    <header class="header">{{ comDetail.name }}--{{ comDetail.id }}</header>
    <h1>    :{{ queryObj }}</h1>
    <button @click="handleDelete">  </button>
  </div>
</template>
<script>
export default {
  data() {
    return {
      comDetail: this.comItem,
      _queryObj: this.queryObj,
    };
  },
  props: {
    comItem: {
      type: Object,
      default() {
        return {
          id: 0,
          name: "",
        };
      },
    },
    queryObj: {
      //               ,   Object
      type: Object,
      default() {
        //          。
        return {
          num: 0,
        };
      },
    },
  },
  watch: {
    comItem(val) {
      this.comDetail = val;
      return val;
    },
    queryObj(val) {
      this._queryObj = val;
      return val;
    },
  },
  created() {
    console.log("data -> this.comItem", this.comItem);
  },
  methods: {
    handleDelete() {
      //       
      this.$el.remove();
      //         。        leftComList      。
      this.$emit("handleDelete", this.comDetail);
    },
  },
};
</script>
<style scoped>
.widget-wrapper {
  background: #ff7b7b;
  border-radius: 12px;
  overflow: hidden;
  width: 200px;
}
.header {
  height: 50px;
  padding: 0 15px;
}
</style>

사실 components 2.vue 파일 의 코드 는 components 1.vue 파일 의 코드 와 유사 합 니 다.유일한 차이 점 은 배경 색 이 다르다 는 것 입 니 다.
데이터 로 동적 구성 요소 생 성
다음은 Vue.draggable 이라는 드래그 라 이브 러 리 를 사용 하여 드래그 와 데 이 터 를 수정 해 야 합 니 다.우 리 는 앱 vue 파일 에 직접 쓸 수 있다.

/* App.vue */
<template>
  <div class="dragCom">
    <h1>{{ leftComList }}</h1>
    <button @click="queryObj.num++">      </button>
    <div class="body">
      <div class="left">
        <draggable class="left" :list="leftComList" :group="'people'">
          <div
            ref="comBody"
            v-for="({ name, id }, index) in leftComList"
            :key="id"
            class="comCard"
          >
            <!--    leftComList   ,         , 
                         DOM    。 -->
            {{
              handleAddCom({
                props: { comItem: { name, id }, queryObj },
                index,
              })
            }}
          </div>
        </draggable>
      </div>
      <div class="right">
        <draggable
          class="dragArea"
          :list="rightComList"
          :group="{ name: 'people', pull: 'clone', put: false }"
          :clone="handleCloneDog"
        >
          <div class="card" v-for="element in rightComList" :key="element.id">
            {{ element.name }}
          </div>
          <!--          , rightComList       name    generateComponents.js
            ComMap     -->
        </draggable>
      </div>
    </div>
  </div>
</template>

<script>
import draggable from "vuedraggable";
import CreateCom from "./generateComponents";
export default {
  components: {
    draggable,
  },
  data() {
    return {
      rightComList: [
        {
          id: Math.random(),
          name: "components1",
        },
        {
          id: Math.random(),
          name: "components2",
        },
      ],
      leftComList: [], //              。
      comMap: new Map(), //             
      //          class="comCard"   DOM ,
      //                  。
      queryObj: {
        //                  
        num: 0,
      },
    };
  },
  beforeDestroy() {
    //          
    this.comMap.clear();
  },
  methods: {
    handleAddCom({ index, on = {}, props = { comItem: { name: "", id: 0 } } }) {
      const {
        comItem: { id },
      } = props;
      this.$nextTick(() => {
        //             
        const childNodesLength = this.$refs.comBody[index].childNodes.length;
        //   comBody   DOM      
        const comLine = this.$refs.comBody.length;
        if (!this.comMap.get(id)) {
          //          

          // 1.    CreateCom        。     props     
          const com = CreateCom({
            props,
            on: {
              handleDelete: this.handleDeleteCom,
              ...on,
            },
          });
          // 2.     
          com.$mount();
          if (childNodesLength === 2) {
            //             。          DOM          。
            //       DOM        
            this.$refs.comBody.splice(
              index,
              0,
              this.$refs.comBody[comLine - 1]
            );
          }
          // 3.           DOM 。
          this.$refs.comBody[index].appendChild(com.$el);
          // 4.           。
          this.comMap.set(id, true);
        } else {
          //           ,           
          return;
        }
      });
    },
    handleDeleteCom({ id }) {
      //            ,     id     
      const index = this.leftComList.findIndex((item) => item.id === id);
      if (~index) {
        //       id   ,   
        this.leftComList.splice(index, 1);
      }
    },
    handleCloneDog(item) {
      //   leftComList       
      return {
        ...item,
        id: Math.random(),
      };
    },
  },
};
</script>

<style>
.dragCom {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
.body {
  width: 100%;
  height: 800px;
  display: flex;
  justify-content: space-between;
}
.left {
  flex: 1;
  height: 800px;
  border: 1px solid pink;
}
.right {
  width: 20%;
  height: 800px;
}
.card {
  height: 50px;
  background-color: #40cec7;
  margin: 12px 0;
  font-size: 12px;
  line-height: 50px;
  cursor: pointer;
}
.comCard {
  margin: 12px;
  display: inline-block;
}
</style>


이렇게 하면 동적 구성 요소 렌 더 링 과 드래그 정렬 을 실현 합 니 다.
효과.
 
소스 코드
시도 하고 싶 은 학생 은 본문의 코드 원본 github 를 스스로 다운로드 할 수 있 습 니 다.
이상 은 vue 가 드래그 동적 생 성 구성 요 소 를 실현 하 는 데 필요 한 상세 한 내용 입 니 다.vue 드래그 동적 생 성 구성 요소 에 대한 자 료 는 다른 관련 글 을 주목 하 십시오!

좋은 웹페이지 즐겨찾기