首页前端开发JavaScript如何在vue中使用HTML 5 拖放API

如何在vue中使用HTML 5 拖放API

时间2024-01-31 14:45:03发布访客分类JavaScript浏览317
导读:收集整理的这篇文章主要介绍了如何在vue中使用HTML 5 拖放API,觉得挺不错的,现在分享给大家,也给大家做个参考。 拖放 API 将可拖动元素添加到 HTML,使我们可以构建包含可...
收集整理的这篇文章主要介绍了如何在vue中使用HTML 5 拖放API,觉得挺不错的,现在分享给大家,也给大家做个参考。

拖放 API 将可拖动元素添加到 HTML,使我们可以构建包含可以拖动的具有丰富 UI 元素的 Web 应用。

在本文中我们将用 Vue.js 构建一个简单的看板应用。看板是一种项目管理工具,使用户可以从头到尾直观地管理项目。 Trello、Pivotal Tracker 和 Jira 等工具都属于看板应用。

设置看板

运行以下命令创建我们的看板项目:

vue create kanban-board

在创建项目时,该选择只包含 Babel 和 ESlint 的默认预设。

完成后,删除默认组件 HelloWorld ,将 App 组件修改为空,仅包含裸组件模板:

template>
     div>
    /div>
     /template>
    script>
export default {
 name: 'App', components: {
}
,}
    ;
    /script>
    style>
    /style>
    

接下来用 Bootstrap 进行样式设置,只需 Bootstrap CSS CDN 就够了。将其添加到 public/index.html 的 head 重。

head>
     meta charset="utf-8">
     meta http-equiv="X-UA-Compatible" content="IE=Edge">
     meta name="viewport" content="width=device-width,inITial-scale=1.0">
     link rel="icon" href="%= BASE_URL %>
    favicon.ico" rel="external nofollow" >
     link rel="stylesheet" href="https://stackpath.bootstrapcdn.COM/bootstrap/4.5.2/css/bootstrap.min.css" rel="external nofollow"  integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
     title>
    %= htmlWebpackPlugin.options.title %>
    /title>
     /head>
    

在看板中构建 UI 组件

看板的样子应该是这样的:

通常看板要有列和卡片。卡片是要执行的单个项目或任务,列用来显示特定卡片的状态。

所以需要创建三个 Vue 组件:一个用于列,一个用于卡片,最后一个用于创建新卡片。

创建 card 组件

先来创建 card 组件。在 /component 目录中创建一个新文件 Card.vue。

把下面的代码添加到组件中:

template>
     div class="card">
     div class="card-body">
    A Sample Card/div>
     /div>
    /template>
    script>
export default {
}
    ;
    /script>
    style scoPEd>
div.card {
     margin-bottom: 15px;
     box-shadow: 0 0 5px #cccccc;
     transition: all ease 300ms;
     background: #fDFdfd;
}
div.card:hover {
     box-shadow: 0 0 10px #aaaaaa;
     background: #ffffff;
}
    /style>
    

这样就创建并设置了卡片组件的样式。不过还没有向组件添加可拖动功能,因为这只是组件的框架。

创建 AddCard 组件

顾名思义,这个组件将负责创建新卡片并将其添加到列中。

在 /components 目录中创建一个 AddCard.vue 文件,并添加以下代码:

template>
     div class="">
     button  class="BTn btn-sm btn-info w-100"  v-if="!inAddMode"  @click="inAddMode = true" >
      Add Card /button>
     form action="#" class="card p-3" ref="form" v-else>
      div class="form-group">
      input   type="text"   name="title"   id="title"   class="form-control"   placeholder="Something interesting..."   v-model="cardData"  />
      /div>
      div class="d-flex justify-content-center">
      button type="submit" class="btn w-50 btn-Primary mr-3">
    Save/button>
      button type="reset" class="btn w-50 btn-danger">
       Cancel  /button>
      /div>
     /form>
     /div>
    /template>
    script>
export default {
 data() {
 return {
  inAddMode: false,  cardData: '', }
    ;
 }
, methods: {
}
,}
    ;
    /script>
    style>
    /style>
    

具体功能将在后面进行构建。

创建 Column 组件

这是最后一个组件,它用来显示卡列表,还会包含 AddCard 组件,以便可以将新卡片直接创建到列中。

在 components 目录中创建一个 Column.vue 文件,并添加以下代码:

template>
     div class="col-md-3 card column" ref="column">
     header class="card-header">
      h3 class="col">
    Column Name/h3>
     /header>
     div class="card-list">
    /div>
     /div>
    /template>
    script>
export default {
}
    ;
    /script>
    style scoped>
div.column {
     padding: 0;
     padding-bottom: 15px;
     margin: 0 15px;
     box-shadow: 0 0 10px #cccccc;
}
div.card-list {
     padding: 0 15px;
}
header {
     margin-bottom: 10px;
}
header h3 {
     text-align: center;
}
    /style>
    

现在项目的框架搭好了,接下来先概述一下拖放功能在浏览器中是怎样工作的。

HTML5 拖放 API 是什么?

当用户将鼠标移到可拖动元素上时,拖动操作开始,然后将元素移动到启用拖放的元素上。

再默认情况下,唯一可拖动的 HTML 元素是图像和链接。为了使其他元素可拖动,需要通过将 Draggable 属性添加到元素;也可以在 JavaScript 中选择元素并将 draggable 属性设置为 true 来显式创建功能。

在元素上将 draggable 属性设置为 true 之后,你会注意到 draggable 属性已添加到该元素。

!-- Making an element draggable in HTML -->
    div draggable="true">
    This is a draggable div in HTML/div>
    script>
    // Making an element draggable in javascriptconst div = document.querySelector('div');
    div.draggable = true;
    /script>
    

拖动元素的目的是将数据从页面的一个部分传输到另一部分。

对于图像,要传输的数据是图像 URL 或它的 base 64 表示形式。如果是链接,传输的数据是 URL。可以将链接移动到浏览器的 URL 栏中,这样使浏览器跳转到该 URL。

所以,如果没有数据传输的能力,那么拖动元素就毫无用处了。可以通过 Datatransfer API 把通过拖动操作传输的数据保存在拖动数据存储区中,这个 API 提供了在拖放操作期间存储和访问数据的方式。

DataTransfer 提供了添加要通过拖放传输的项目的位置。可以在开始拖动操作时(调用 dragstart 事件时)将数据添加到拖动数据存储中,并且只能在完成拖放操作后(调用 drop 事件时)才能接收数据。

从拖动到释放元素的这段时间中,元素被拖放后,将会在被拖动的元素上触发两个事件:dragstart 和 dragend。

现在还不能把可拖动元素拖放到任何地方。与需要显式的使元素可拖动一样,它也需要启用放置。

要启用元素拖放功能需要侦听 dragover 事件并阻止默认的浏览器操作。

!-- Make a section drop-enabled -->
    section class="section">
    /section>
    script>
    const section = document.querySelector('.section');
    section.addEventListener('dragover', (e) =>
 {
     e.preventDefault();
}
    );
    /script>
    

将元素拖动到启用拖放的元素上时,将会在启用拖放的元素上触发以下事件:

Dragenter:当一个元素被拖动到启用拖放的元素上时触发一次
Dragover:只要元素仍然位于启用了 drop 的元素上,就会连续触发
Drop:在把拖动的元素拖放到启用了拖放的元素上之后触发。

需要注意的是,仅在触发放置事件时才能访问存储在 DataTransfer 对象中的数据,而不能在 dragenter 或 dragover 上访问。

组合所有的组件

在向组件添加拖放功能之前,先讨论一下 app state。

这里的 app state 将存储在 App 组件中,然后可以作为 PRops 向下传递到 Column 组件。另一方面,列组件在渲染时会将所需的 props 传递给卡片组件。

修改 App.vue 使其能够反映状态和组件组成:

// App.vuetemplate>
     div class="container-fluid">
     h2 class="m-5">
      Vue Kanban Board /h2>
     div class="row justify-content-center">
      Column  v-for="(column, index) in columns"  :column="column"  :key="index"  />
     /div>
     /div>
    /template>
    script>
    import Column From './components/Column';
export default {
 name: 'App', components: {
 Column, }
, data() {
 return {
  columns: [  {
   name: 'TO-DO',   cards: [   {
    value: 'Prepare breakfast',   }
,   {
    value: 'Go to the market',   }
,   {
    value: 'Do the laundry',   }
,   ],  }
,  {
   name: 'In Progress',   cards: [],  }
,  {
   name: 'Done',   cards: [],  }
,  ], }
    ;
 }
,}
    ;
    /script>
    style>
h2 {
     text-align: center;
}
    /style>
    

在这里,我们导入了列组件,并在状态为 columns 的状态下循环访问数据时,将每一列的数据传递给 column 组件。在这种情况下,只有 “To-Do”,“In Progress” 和 “Done” 三列,每列都有一个卡片数组。

接下来,更新 Column 组件来接收 props 并显示它:

// Column.vuetemplate>
     div class="col-md-3 card column" ref="column">
     header class="card-header">
      h3 class="col">
{
{
 column.name }
}
    /h3>
      AddCard />
     /header>
     div class="card-list">
      Card v-for="(card, index) in column.cards" :key="index" :card="card" />
     /div>
     /div>
    /template>
    script>
    import Card from './Card';
    import AddCard from './AddCard';
export default {
 name: 'Column', components: {
 Card, AddCard, }
, props: {
 column: {
  type: Object,  required: true, }
, }
,}
    ;
    /script>
    ...

Column 组件从 App 组件接收 props,并用 props 渲染 Card 组件列表。在这里还会使用 AddCard 组件,因为应该可以将新卡直接添加到列中。

最后更新 Card 组件显示从 Column 接收的数据。

// Card.vuetemplate>
     div class="card" ref="card">
     div class="card-body">
{
{
 card.value }
}
    /div>
     /div>
    /template>
    script>
export default {
 name: 'Card', props: {
 card: {
  type: Object,  required: true, }
, }
,}
    ;
    /script>
    

Card 组件仅从 Column 接收它需要的所有数据并显示出来。我们还在此处添加了对 card 元素的引用,这样在用 JavaScript 访问 card 元素时非常有用。

完成上述操作后,你的应用应该是下面这样了:

添加拖放功能

添加拖放功能的第一步是识别可拖动组件和放置目标。

用户应该能够按照卡片中的活动进度将卡片从一列拖到另一列。所以可拖动组件应该是 Card 组件,而放置目标是 Column 组件。

使卡片可拖动

需要执行以下操作才能使卡组件可拖动:

  1. 将 draggable 属性设置为 true
  2. 用 DataTransfer 对象设置要传输的数据

应该先把 draggable 设置为 true,根据 Vue 生命周期 hook,安全的位置应该是已安装的 hook。把以下内容添加到 Card 组件的已安装 hook 中:

// Card.vuescript>
export default {
 name: 'Card', props: {
...}
, mounted() {
     this.setDraggable();
 }
, methods: {
 setDraggable() {
      // Get Card element.  const card = this.$refs.card;
      card.draggable = true;
      // SETUP event listeners.  card.addEventListener('dragstart', this.handleDragStart);
      card.addEventListener('dragend', this.handleDragEnd);
 }
, }
    ,/script>
    

在上面,我们创建了一个 setDraggable 方法来使卡片组件可拖动。

在 setDraggable 中,从上一节中添加的引用中得到卡片,并将 draggable 属性设置为 true 。

同时还需要设置事件监听器:

// Card.vuescript>
    export const CardDataType = 'text/x-kanban-card';
export default {
... methods: {
 setDraggable() {
...}
, handleDragStart(event) {
      const dataTransfer = event.dataTransfer;
      // Set the data to the value of the card which is gotten from props.  dataTransfer.setData(CardDataType, this.card.value);
      dataTransfer.effectAllowed = 'move';
      // Add Visual cues to show that the card is no longer in it's position.  event.target.style.opacity = 0.2;
 }
, handleDragEnd(event) {
      // Return the opacity to normal when the card is dropped.  event.target.style.opacity = 1;
 }
 }
}
    /script>
    

在前面提到,只有在 dragstart 事件被调用时,数据才可以被添加到拖动数据存储中。所以需要在 handleDragStart 方法中添加数据。

设置数据时要用到的重要信息是格式,可以是字符串。在我们的例子中,它被设置为 text/x-kanban-card。存储这个数据格式并导出它,因为在删除卡后获取数据时,Column 组件将会用到它。

最后,将 card 的透明度降低到 0.2 ,以便向用户提供一些反馈,表明该卡实际上已被拉出其原始位置。拖动完成后,再把透明度恢复为 1。

现在可以拖动卡片了。接下来添加放置目标。

把 dragover 设置为 drop-enabled

将卡片拖到列组件上时,会立即触发 dragover 事件,将卡放入列中后会触发 drop 事件。

要使卡片掉落到列中,需要侦听这些事件。

// Column.vuetemplate>
    .../template>
    script>
import Card {
 CardDataType }
     from './Card';
    import AddCard from './AddCard';
export default {
 name: 'Column', components: {
...}
, props: {
...}
, mounted() {
     this.enableDrop();
 }
, methods: {
 enableDrop() {
      const column = this.$refs.column;
      column.addEventListener('dragenter', this.handleDragEnter);
      column.addEventListener('dragover', this.handleDragOver);
      column.addEventListener('drop', this.handleDrop);
 }
, /**  * @param {
DragEvent}
 event  */ handleDragEnter(event) {
  if (event.dataTransfer.types.includes[CardDataType]) {
      // Only handle cards.  event.preventDefault();
  }
 }
, handleDragOver(event) {
      // Create a move effect.  event.dataTransfer.dropEffect = 'move';
      event.preventDefault();
 }
, /**  * @param {
DragEvent}
 event  */ handleDrop(event) {
      const data = event.dataTransfer.getData(CardDataType);
      // Emit a card moved event.  this.$emit('cardMoved', data);
 }
, }
,}
    ;
    /script>
    

在这里将设置在挂载 Column 组件之后启用 drop 所需的所有事件侦听器。

在这三个事件中,第一个被触发的是 dragenter ,当可拖动元素被拖到列中时会立即被触发。对于我们的程序,只希望将卡片放入一列中,所以在 dragenter 事件中,只阻止数据类型的默认值,数据类型包括在 card 组件中所定义的 card 数据类型。

在 dragover 事件中,把放置效果设置为 move。

在 drop 事件中获得从 dataTransfer 对象传输的数据。

接下来,需要更新状态并将卡片移动到当前列。因为我们的程序状态位于 App 组件中,所以在 drop 侦听器中发出 cardMoved 事件,传递已传输的数据,并在 App 组件中侦听 cardMoved 事件。

更新 App.vue 来监听 cardMoved 事件:

// App.vuetemplate>
     div class="container-fluid">
     ... div class="row justify-content-center">
      Column  v-for="(column, index) in columns"  :column="column"  :key="index"  @cardMoved="moveCardToColumn($event, column)"  />
     /div>
     /div>
    /template>
    script>
    import Column from './components/Column';
export default {
 name: 'App', components: {
...}
, data() {
 return {
...}
 }
, methods: {
 moveCardToColumn(data, newColumn) {
      const formerColumn = this.columns.find(column =>
 {
      // Get all the card values in a column.  const cardValues = column.cards.map((card) =>
     card.value);
      return cardValues.includes(data);
  }
    )  // Remove card from former column.  formerColumn.cards = formerColumn.cards.filter(  (card) =>
     card.value !== data  );
  // Add card to the new column.  newColumn.cards.push({
 value: data }
    );
 }
, }
,}
    /script>
    

在这里通过 @cardMoved 侦听 cardMoved 事件,并调用 moveCardToColumn 方法。 cardMoved 事件发出一个值(卡片数据),可以通过 $event 访问这个值,另外还传递了放置卡的当前列(这是调度事件的位置)。

moveCardToColumn 函数做了三件事:找到卡偏先前所在的列,从该列中取出卡片,最后把卡片加到新列中。

完成看板

现在我们已经实现了拖放功能,最后只剩下添加卡片的功能了。

在 AddCard.vue 中添加以下代码:

template>
     div class="">
     button  class="btn btn-sm btn-info w-100"  v-if="!inAddMode"  @click="inAddMode = true" >
      Add Card /button>
     form  action="#"  class="card p-3"  @submit.prevent="handleSubmit"  @reset="handleReset"  ref="form"  v-else >
      ... /form>
     /div>
    /template>
    script>
export default {
 data() {
 return {
...}
    ;
 }
, methods: {
 handleSubmit() {
  if (this.cardData.trim()) {
      this.cardData = '';
      this.inAddMode = false;
      this.$emit('newcard', this.cardData.trim());
  }
 }
, handleReset() {
      this.cardData = '';
      this.inAddMode = false;
 }
, }
,}
    ;
    /script>
    

上面的代码是在提交“add card”表单或重置时运行的函数。

重置后清除 cardData,并将 inAddMode 设置为 false。

在提交表单后还要清除 cardData ,以便在添加新项目时不会显示以前的数据,并且还要将 inAddMode 设置为 false 并发出 newcard 事件。

Column组件中使用了AddCard组件,所以需要在 Column 组件中监听 newcard 事件。在 Column 组件中添加侦听 newcard 事件的代码:

template>
     div class="col-md-3 card column" ref="column">
     header class="card-header">
      h3 class="col">
{
{
 column.name }
}
    /h3>
      AddCard @newcard="$emit('newcard', $event)">
    /AddCard>
     /header>
     .../template>
    ...

在这里重新发出 newcard 事件,这样可以使它到达 App 组件,实际的动作将在该组件上发生。

自定义 Vue 事件不会冒泡,因此 App 组件无法侦听 AddCard 组件中发出的 newcard 事件,因为它不是直接子组件。
更新 App 组件处理 newcard 事件的代码:

// App.vuetemplate>
     div class="container-fluid">
     ... div class="row justify-content-center">
      Column  v-for="(column, index) in columns"  :column="column"  :key="index"  @cardMoved="moveCardToColumn($event, column)"  @newcard="handleNewCard($event, column)"  />
     /div>
     /div>
    /template>
    script>
    import Column from './components/Column';
export default {
 name: 'App', components: {
...}
, data() {
 return {
...}
 }
, methods: {
 moveCardToColumn(data, newColumn) {
...}
, handleNewCard(data, column) {
  // Add new card to column.  column.cards.unshift({
 value: data }
    );
 }
, }
,}
    ;
    /script>
    

在这里侦听从 Column 组件调用的 newcard 事件,在获取数据后,创建一个新卡片并将其添加到创建该卡的列中。

总结

在本文中,我们介绍了什么是 html 5 拖放 API ,如何使用,以及如何在 Vue.js 中实现。

拖放功能也可以在其他前端框架和原生 JavaScript 中使用。

以上就是如何在vue中使用HTML 5 拖放API的详细内容,更多关于vue中拖放api的资料请关注其它相关文章!

您可能感兴趣的文章:
  • vue中封装axios并实现api接口的统一管理
  • 详解vue3.0 的 Composition API 的一种使用方法
  • vue3.0 的 Composition API 的使用示例
  • 详解Vue中Axios封装API接口的思路及方法
  • vue项目打包为APP,静态资源正常显示,但API请求不到数据的操作
  • vue设置全局访问接口API地址操作
  • vue接通后端api以及部署到服务器操作
  • SpringBoot+Vue前后端分离实现请求api跨域问题
  • 使用Vue Composition API写出清晰、可扩展的表单实现
  • 浅谈Vue3.0新版API之composition-api入坑指南
  • Vue常用API、高级API的相关总结

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!

上一篇: Vue实现多页签组件下一篇:Vue中引入svg图标的两种方式猜你在找的JavaScript相关文章 html font标签如何设置字体大小?html font标签属性用法介绍2022-05-16vue3+TypeScript+vue-router的使用方法2022-04-16vue3获取当前路由地址2022-04-16如何利用React实现图片识别App2022-04-16JavaScript展开运算符和剩余运算符的区别详解2022-04-16微信小程序中使用vant框架的具体步骤2022-04-16Vue elementUI表单嵌套表格并对每行进行校验详解2022-04-16如何利用Typescript封装本地存储2022-04-16微信小程序中wxs文件的一些妙用分享2022-04-16JavaScript的Set数据结构详解2022-04-16 其他相关热搜词更多phpjavapython程序员loadpost-format-gallery

若转载请注明出处: 如何在vue中使用HTML 5 拖放API
本文地址: https://pptw.com/jishu/594097.html
关于uniApp editor微信滑动问题 c语言中的“?:”是什么运算符

游客 回复需填写必要信息