iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >vue 实现拖拽动态生成组件的需求
  • 571
分享到

vue 实现拖拽动态生成组件的需求

2024-04-02 19:04:59 571人浏览 泡泡鱼
摘要

目录产品需求思路面临的问题拖拽库的选择如何生成组件生成组件组件以数据驱动动态组件的生成效果源码产品需求 开完产品需求会议,遇到了一个需求,首先页面分成两栏布局,左侧展示数据组件,支

产品需求

开完产品需求会议,遇到了一个需求,首先页面分成两栏布局,左侧展示数据组件,支持拖拽排序,点击按钮清除组件。右侧支持将组件的缩略图拖拽至左侧生成一个新的组件。

思路

对于动态生成组件来说每一次都要是生成全新的一个组件,那么就可以把 组件放进函数当中 return。在jsX中调用函数,每次调用函数都会返回一个全新的组件。这对React来说非常简单,但是对于Vue来说,直接将组件返回是不可能的。尽管这个 return 写法不适合Vue,但是我们不可否认,思路是非常正确的,所以我们应该考虑一个别的写法。至于动态的生成组件,我们必须以数据来驱动组件的生成。对于拖拽组件的排序,直接使用拖拽库就OK了!!

面临的问题

  1. 拖拽库的选择
  2. 如何生成组件
  3. 以数据驱动动态生成组件

拖拽库的选择

拖拽库在这里我选择的是项目中存在的一个拖拽库 Vue.Draggable 点这里链接查看 Start 14.9K 蛮不错的。如果你们的Vue项目中没有用到这个拖拽库,你们可以自行参考本片文章的设计思路。

如何生成组件

在这里我使用的是 Vue.extend() 不清楚如何使用的小伙伴请在官方文档中查看过后再来学习这篇文章 Vue.extend 。 接下来我们创建一个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,分别为components1.vue,components2.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>

其实components2.vue文件中的代码和components1.vue文件的代码类似,唯一不同的地方就是背景颜色不一样。

以数据驱动动态组件的生成

接下来就得使用Vue.Draggable 这个拖拽库进行拖拽和数据的修改。 我们可以直接在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拖拽动态生成组件的资料请关注编程网其它相关文章!

--结束END--

本文标题: vue 实现拖拽动态生成组件的需求

本文链接: https://www.lsjlt.com/news/125182.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • vue 实现拖拽动态生成组件的需求
    目录产品需求思路面临的问题拖拽库的选择如何生成组件生成组件组件以数据驱动动态组件的生成效果源码产品需求 开完产品需求会议,遇到了一个需求,首先页面分成两栏布局,左侧展示数据组件,支...
    99+
    2024-04-02
  • VUE使用draggable实现组件拖拽
    本文实例为大家分享了draggable组件拖拽实例,供大家参考,具体内容如下 实现步骤 1、导入draggable依赖 npm i -S vuedraggable 2、引入dragg...
    99+
    2024-04-02
  • Vue实现可拖拽组件的方法
    本文为大家分享了Vue实现可拖拽、拖拽组件,供大家参考,具体内容如下 描述: 组件仅封装拖拽功能,内容通过#header、#default、#footer插槽 自定义 效果:&nbs...
    99+
    2024-04-02
  • Vue实现动态查询规则生成组件
    1. 动态查询规则 动态查询规则,大致如下图所示。是可以按照用户的自定义进行组织查询语句的一种复杂组件,大致可以实现SQL查询的where条件,下面是摘自mongodb的某...
    99+
    2024-04-02
  • VUE怎么使用draggable实现组件拖拽
    这篇文章主要讲解了“VUE怎么使用draggable实现组件拖拽”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“VUE怎么使用draggable实现组件拖拽”吧!实现步骤1、导入draggab...
    99+
    2023-06-29
  • 实现vue图片缩放方式-拖拽组件
    目录实现效果如下父组件如下子组件imgbox.vue如下实现效果如下 这几天做了个没做过的组件,以此记录下,需要的效果是在一个dom内,缩放拖拽图片。 封装的子组件imgbox.V...
    99+
    2024-04-02
  • Vue怎么实现动态查询规则生成组件
    这篇文章给大家分享的是有关Vue怎么实现动态查询规则生成组件的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1. 动态查询规则动态查询规则,大致如下图所示。是可以按照用户的自定义进行组织查询语句的一种复杂组件,大致...
    99+
    2023-06-15
  • vue中怎么实现一个拖拽进度条滑动组件
    这期内容当中小编将会给大家带来有关vue中怎么实现一个拖拽进度条滑动组件,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。调用组件如下:<slider :mi...
    99+
    2024-04-02
  • vue拖拽组件vuedraggable API options如何实现盒子之间相互拖拽排序
    小编给大家分享一下vue拖拽组件vuedraggable API options如何实现盒子之间相互拖拽排序,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下...
    99+
    2024-04-02
  • vue项目中实现el-dialog组件可拖拽效果
    目录0. 首先上图,看效果1. 实现方法参考资料0. 首先上图,看效果 1. 实现方法 第一步:创建 drag.js文件 实现拖拽源码 export function start...
    99+
    2024-04-02
  • 利用vue组件实现图片的拖拽和缩放功能
    目录前言如图所示:方法如下:总结前言 vue实现一个组件其实很简单但是要写出一个好的可复用的组件那就需要多学习和钻研一下,一个好的组件必须有其必不可少的有优点:一是能提高应用开发效率...
    99+
    2024-04-02
  • vue draggable组件实现拖拽及点击无效问题的解决
    目录一、效果图二、拖拽及点击无效解决方法三、vuedraggable的使用在实现一个移动端项目的时候,根据产品需求,要实现一个既能增加删除又可以拖拽调换位置的效果,然后我使用了dra...
    99+
    2024-04-02
  • vue项目中怎么实现el-dialog组件可拖拽效果
    今天小编给大家分享一下vue项目中怎么实现el-dialog组件可拖拽效果的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。0....
    99+
    2023-06-26
  • Vue怎么实现自定义组件自动生成
    本文小编为大家详细介绍“Vue怎么实现自定义组件自动生成”,内容详细,步骤清晰,细节处理妥当,希望这篇“Vue怎么实现自定义组件自动生成”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。就目前三大前端主流数据驱动框架...
    99+
    2023-07-04
  • vue3实现手机上可拖拽元素的组件
    前言: 用vue3实现一个可在手机上拖拽元素的组件,可拖拽至任意位置,并且可以防止拖拽元素移出屏幕边缘。 <script setup> import { ref } fr...
    99+
    2024-04-02
  • 怎么利用vue组件实现图片的拖拽和缩放功能
    这篇文章将为大家详细讲解有关怎么利用vue组件实现图片的拖拽和缩放功能,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。前言vue实现一个组件其实很简单但是要写出一个好的可复用的组件那就需要多学...
    99+
    2023-06-26
  • 使用vue自定义如何实现Tree组件和拖拽功能
    目录vue自定义实现Tree组件和拖拽功能vue2 + js版vue2 + ts 版总结vue自定义实现Tree组件和拖拽功能 实现功能:树结构、右键菜单、拖拽 效果图 vue2 ...
    99+
    2022-12-09
    vue自定义Tree组件 vue Tree组件 vue拖拽功能
  • Vue组件设计之多列表拖拽交换排序功能实现
    目录1. 安装所需依赖2. 组件设计实现3. 组件使用示例在前端开发中,拖拽排序是一种提升用户体验非常好的方式,常见的场景有单列表拖拽排序,多列表拖拽交换排序,比如以下这种效果: ...
    99+
    2023-05-18
    vue拖拽交换排序 vue多列表拖拽交换排序 vue列表拖拽排序
  • Vue动态组件表格的实现代码
    目录Vue组件数据源框架结构组件这里我自己封装了几个组件按钮组件图片组件滑动开关tap组件text组件Vue组件 数据源 //这里是HTML内容 这里通过下面的引入框架结构把数据源传...
    99+
    2022-11-13
    Vue动态组件 表格 Vue动态组件 Vue 表格
  • Vue结合原生js如何实现自定义组件自动生成
    这篇文章主要介绍Vue结合原生js如何实现自定义组件自动生成,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!就目前三大前端主流数据驱动框架(vue,ng,react)而言,均具有创建自...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作