当前位置: 首页 > news >正文

沙井网站开发产品营销推广策略

沙井网站开发,产品营销推广策略,乌鲁木齐网站设计平台,微网站 电脑网站 统一新的学习方法 用手写简单方法实现一个功能然后用比较成熟的第三方解决方案即能学习原理又能学习第三方库的使用 从两个DEMO开始 Vue Draggable Next: Vue Draggable NextReact Sortable HOC: React Sortable HOC 列表排序的三个阶段 拖动开始(dragstart&#x…
新的学习方法
  • 用手写简单方法实现一个功能
  • 然后用比较成熟的第三方解决方案
  • 即能学习原理又能学习第三方库的使用

从两个DEMO开始

  • Vue Draggable Next: Vue Draggable Next
  • React Sortable HOC: React Sortable HOC
列表排序的三个阶段
  • 拖动开始(dragstart)
    • 被拖动图层的状态变化
    • 会出一个浮层
  • 拖动进行中(dragmove)
    • 浮层会随着鼠标移动
    • 条目发生换位:当浮层下沿超过被拖条目二分之一的时候,触发换位。这是一个比较独特的需求
  • 松开鼠标阶段(drop)
    • 浮层消失
    • 被拖动图层状态复原
    • 数据被更新
      在这里插入图片描述
拖动排序功能开发

第一阶段 Dragstart

  • 被拖动图层的状态变化 常规做法
    • 添加mouseDown事件,检查当前的target是那个元素,然后给他添加特定的状态
    • 添加mouseMove事件,创一个和被拖动元素一模一样的的浮层,将它的定位设置
      它的定位为绝对定位,并且随着鼠标的坐标更新。
  • 使用HTML的Drag特性
    • 文档地址:拖拽操作
    • 浏览器的默认拖拽行为:支持图象,链接和选择的文本
    • 其他元素默认情况是不可拖拽的。
    • 如果想可以拖拽可以设置为draggable = true
    • 使用dragstart事件监控拖动开始,并设置对应的属性

LayerList组件中添加draggable属性

// LayerList.vue
<liclass="ant-list-item"v-for="item in list" :key="item.id":class="{ active: item.id === selectedId }"@click="handleClick(item.id)"draggable="true"
></li>

在这里插入图片描述
这样就可以有效果了:当拖动对应条目的时候,它会自动生成半透明的条目,并且跟随鼠标的移动。
接下来就开始使用dragstart事件监控拖动开始,并设置对应的属性

  • 给被拖动元素添加特定的状态:使用一系列的事件来监控拖动的进度,使用dragStart开始拖动操作
// LayerList.vue
// html部分
<liclass="ant-list-item"v-for="item in list" :key="item.id":class="{ active: item.id === selectedId, ghost: dragData.currentDragging === item.id}"@click="handleClick(item.id)"@dragstart="onDragStart($event, item.id)"draggable="true"
></li>
// js部分(setup)
const dragData = reactive({currentDragging: ''
})
const onDragStart = (e: DragEvent, id: string ) => {dragData.currentDragging = id;
}
// css部分
.ant-list-item.ghost {opacity: 0.5;
}

完成出来的效果:
在这里插入图片描述
接下来就是在鼠标松开的时候,特定的状态消失:使用drop事件:

<ul :list="list" class="ant-list-items ant-list-border" @drop="onDrop"></ul>
const onDrop = (e: DragEvent ) => {dragData.currentDragging = '';
}

但是这样做发现不起作用,后来发现是onDrog事件并没有触发,原因:
dragenter 或 dragover 事件的监听程序用于表示有效的放置目标,也就是被拖拽项目可能放置的地方。网页或应用程序的大多数区域都不是放置数据的有效位置。因此,这些事件的默认处理是不允许放置。
指定放置对象
因为网页大部分区域不是有效的放置位置,这些事件的默认处理都是不允许放置,所以这个行为并不会被触发。
如果你想要允许放置,你必须取消 dragenter 和 dragover 事件来阻止默认的处理。你可以在属性定义的事件监听程序返回 false,或者调用事件的 preventDefault() 方法来实现这一点。在一个独立脚本中的定义的函数里,可能后者更可行。
最终添加阻止默认行为事件:

<ul :list="list" class="ant-list-items ant-list-border" @drop="onDrop" @dragover="onDragOver">const onDragOver = (e: DragEvent) => {e.preventDefault()
}
处理松开鼠标时进行排序
  1. 修改dragData 添加一个当前索引的属性

        const dragData = reactive({currentDragging: '',currentIndex: -1,});
    
  2. @dragstart=“onDragStart($event, item.id, index)” 方法中多添加一个index参数

        const onDragStart = (e: DragEvent, id: string, index: number) => {dragData.currentDragging = id;dragData.currentIndex = index;};
    

有了开始拖动的index之后,我们要知道drop的时候新的index,我们怎么在onDrop方法中拿到新的index呢?因为在onDrop中我们的参数是event,使用event.target可以拿到dom元素,把最新的index放到dom元素上面就可以了,使用:HTMLElement.dataset
3. 使用 HTMLElement.dataset拿到最新的索引

HTMLElement.dataset属性允许无论是在读取模式和写入模式下访问在HTML 或 DOM中元素上设置的
所有自定义数据属性(data-*)集
它是一个DOMString的映射,每个自定义数据属性的一个条目。
请注意,dataset属性本身可以被读取,但不能直接写入,相反,所有的写入必股友是它的属性,这反过来
表示数据属性。
还要注意,一个HTML data-attribute 及其对应的DOM dataset.property 不共享相同的名称,但它
们总是相似的:

       <liclass="ant-list-item":class="{active: item.id === selectedId,ghost: dragData.currentDragging === item.id,}"v-for="(item, index) in list":key="item.id"@click="handleClick(item.id)"@dragstart="onDragStart($event, item.id, index)":data-index="index"draggable="true">
  1. 修改onDrop事件
const onDrop = (e: DragEvent) => {const currentEle = e.target as HTMLElement;if (currentEle.dataset.index) {const moveIndex = parseInt(currentEle.dataset.index);console.log(moveIndex);}dragData.currentDragging = "";
};

但是这样写moveIndex是不一定存在的,因为e.target是鼠标指向的元素,所以当在目标子元素上面进行释放的话,就会把目标当成子元素,比如如果释放到的元素是锁元素,则currentEle就是锁元素。所以这里需要一个方法来向上进行检索,找到符合条件的父元素。

export const getParentElement = (element: HTMLElement, className: string) => {while (element) {if (element.classList && element.classList.contains(className)) {return element;} else {element = element.parentNode as HTMLElement;}}return null;
};
    const onDrop = (e: DragEvent) => {const currentEle = getParentElement(e.target as HTMLElement,'ant-list-item');if (currentEle && currentEle.dataset.index) {const moveIndex = parseInt(currentEle.dataset.index);// 使用第三方库arrayMove改变数组arrayMove.mutate(props.list, dragData.currentIndex, moveIndex);}dragData.currentDragging = '';};

array-move
最终实现的效果:
在这里插入图片描述

在拖动时完成排序:
    const onDragEnter = (e: DragEvent, index: number) => {// 这里的判断是为了避免完成转换后,触发新的一次dragEnter事件if (index !== dragData.currentIndex) {console.log('enter', index, dragData.currentIndex);arrayMove.mutate(props.list, dragData.currentIndex, index);dragData.currentIndex = index;end = index}};

这样就可以在拖动时完成排序了,onDrop里面就不需要进行同样的操作了,修改一下onDrop事件

let start = -1;
let end = -1;
const onDragStart = (e: DragEvent, id: string, index: number) => {dragData.currentDragging = id;dragData.currentIndex = index;start = index;
};
const onDrop = (e: DragEvent) => {context.emit('drop', { start, end})dragData.currentDragging = '';
};

现在就完成了可拖动排序的简单编码,主要掌握三个阶段:

  1. 排序开始:监控被拖拽的元素,添加特殊状态和UI
  2. 移动阶段:进入别的列表的时候完成数据的交换
  3. drop阶段:松开按钮的时候,将状态恢复原状,并且发送对应的事件。

使用第三方库进行排序:

使用Vue Draggable进行排序:

vue.draggable.next

npm i -S vuedraggable@next

将用draggable替换掉ul

<template><draggable:list="list"class="ant-list-items ant-list-bordered"ghost-class="ghost"handle=".handle"item-key="id"><template #item="{ element }"><liclass="ant-list-item":class="{ active: element.id === selectedId }"@click="handleClick(element.id)"><a-tooltip :title="element.isHidden ? '显示' : '隐藏'"><a-buttonshape="circle"@click.stop="handleChange(element.id, 'isHidden', !element.isHidden)"><template v-slot:icon v-if="element.isHidden"><EyeInvisibleOutlined /></template><template v-slot:icon v-else><EyeOutlined /> </template></a-button></a-tooltip><a-tooltip :title="element.isLocked ? '解锁' : '锁定'"><a-buttonshape="circle"@click.stop="handleChange(element.id, 'isLocked', !element.isLocked)"><template v-slot:icon v-if="element.isLocked"><LockOutlined/></template><template v-slot:icon v-else><UnlockOutlined  /> </template></a-button></a-tooltip><inline-editclass="edit-area":value="element.layerName"@change="(value) => {handleChange(element.id, 'layerName', value);}"></inline-edit><a-tooltip title="拖动排序"><a-button shape="circle" class="handle"><template v-slot:icon><DragOutlined /> </template></a-button></a-tooltip></li></template></draggable>
</template>
<script lang="ts">
import { defineComponent, PropType } from 'vue';
import draggable from 'vuedraggable';
import {EyeOutlined,EyeInvisibleOutlined,LockOutlined,UnlockOutlined,DragOutlined,
} from '@ant-design/icons-vue';
import { ComponentData } from '../store/editor';
import InlineEdit from '../components/InlineEdit.vue';
export default defineComponent({props: {list: {type: Array as PropType<ComponentData[]>,required: true,},selectedId: {type: String,required: true,},},emits: ['select', 'change', 'drop'],components: {EyeOutlined,EyeInvisibleOutlined,LockOutlined,UnlockOutlined,InlineEdit,draggable,DragOutlined,},setup(props, context) {const handleClick = (id: string) => {context.emit('select', id);};const handleChange = (id: string, key: string, value: boolean) => {const data = {id,key,value,isRoot: true,};context.emit('change', data);};return {handleChange,handleClick,};},
});
</script><style scoped>
.ant-list-item {padding: 10px 15px;transition: all 0.5s ease-out;cursor: pointer;justify-content: normal;border: 1px solid #fff;border-bottom-color: #f0f0f0;
}
.ant-list-item.active {border: 1px solid #1890ff;
}
.ant-list-item.ghost {opacity: 0.5;
}.ant-list-item:hover {background: #e6f7ff;
}
.ant-list-item > * {margin-right: 10px;
}
.ant-list-item button {font-size: 12px;
}.ant-list-item .handle {cursor: move;margin-left: auto;
}
.ant-list-item .edit-area {width: 100%;
}
</style>

![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=image%2F4-5%E4%BD%BF%E7%94%A8VueDraggableNext%E5%AE%8C%E6%88%90%E6%8E%92%E5%BA%8F%2F1670944246854.png&pos_id=img-LOtmD6Gr-1705830416096


文章转载自:
http://dupe.wwxg.cn
http://yalu.wwxg.cn
http://werwolf.wwxg.cn
http://entourage.wwxg.cn
http://uvular.wwxg.cn
http://wollongong.wwxg.cn
http://panama.wwxg.cn
http://witwatersrand.wwxg.cn
http://maracaibo.wwxg.cn
http://cherubic.wwxg.cn
http://precopulatory.wwxg.cn
http://ultracold.wwxg.cn
http://mutineer.wwxg.cn
http://policemen.wwxg.cn
http://pseudogene.wwxg.cn
http://crispness.wwxg.cn
http://nully.wwxg.cn
http://natter.wwxg.cn
http://gamahuche.wwxg.cn
http://arillus.wwxg.cn
http://comma.wwxg.cn
http://sampling.wwxg.cn
http://zolaism.wwxg.cn
http://bushfighter.wwxg.cn
http://noway.wwxg.cn
http://promorphology.wwxg.cn
http://charger.wwxg.cn
http://yeah.wwxg.cn
http://arroba.wwxg.cn
http://abiotrophy.wwxg.cn
http://rhyparographic.wwxg.cn
http://blithely.wwxg.cn
http://unlash.wwxg.cn
http://miniaturization.wwxg.cn
http://moro.wwxg.cn
http://unretentive.wwxg.cn
http://boniness.wwxg.cn
http://starry.wwxg.cn
http://ferrum.wwxg.cn
http://pec.wwxg.cn
http://campion.wwxg.cn
http://houseperson.wwxg.cn
http://chew.wwxg.cn
http://unconvertible.wwxg.cn
http://assortive.wwxg.cn
http://riksha.wwxg.cn
http://thessaly.wwxg.cn
http://recumbently.wwxg.cn
http://verselet.wwxg.cn
http://proclimax.wwxg.cn
http://restenosis.wwxg.cn
http://digamma.wwxg.cn
http://vertebrated.wwxg.cn
http://blitz.wwxg.cn
http://firebrand.wwxg.cn
http://stroke.wwxg.cn
http://prick.wwxg.cn
http://noneffective.wwxg.cn
http://stuccowork.wwxg.cn
http://unwarrantable.wwxg.cn
http://whalehead.wwxg.cn
http://luminescence.wwxg.cn
http://hotblood.wwxg.cn
http://rife.wwxg.cn
http://undersheriff.wwxg.cn
http://pitchout.wwxg.cn
http://navvy.wwxg.cn
http://lyreflower.wwxg.cn
http://ordinaire.wwxg.cn
http://stew.wwxg.cn
http://tocodynamometer.wwxg.cn
http://bowsprit.wwxg.cn
http://molectron.wwxg.cn
http://eyrir.wwxg.cn
http://raintight.wwxg.cn
http://asterisk.wwxg.cn
http://ratemeter.wwxg.cn
http://brinjaul.wwxg.cn
http://adamic.wwxg.cn
http://affirm.wwxg.cn
http://ethnobotany.wwxg.cn
http://met.wwxg.cn
http://praenomen.wwxg.cn
http://concision.wwxg.cn
http://covert.wwxg.cn
http://duration.wwxg.cn
http://insufficiently.wwxg.cn
http://antiblastic.wwxg.cn
http://adumbrant.wwxg.cn
http://neoisolationism.wwxg.cn
http://ophthalmological.wwxg.cn
http://artifacts.wwxg.cn
http://tabouret.wwxg.cn
http://ugt.wwxg.cn
http://indigently.wwxg.cn
http://myositis.wwxg.cn
http://voice.wwxg.cn
http://seral.wwxg.cn
http://tightrope.wwxg.cn
http://actinolite.wwxg.cn
http://www.hrbkazy.com/news/91737.html

相关文章:

  • 电视台网站开发临沂网站建设优化
  • 营销型网站建设的利与弊资源网站优化排名优化
  • 网站建设入门竞价广告是怎么推广的
  • 潍坊做网站的网络公司google 官网入口
  • 网站设计与制免费跨国浏览器
  • 传奇辅助网站怎么做广州各区正在进一步优化以下措施
  • 网站关于我们的页面淘宝搜索关键词查询工具
  • 网站建设设计服务公司三亚百度推广地址
  • 百事通做网站百度关键词搜索排名代发
  • iis 网站压缩济南专业做网站
  • 韩国封号事件网站建设网络服务提供商是指
  • 请问哪个网站可以做二类学分世界十大网站排名
  • 做网站平台多少钱网络营销论坛
  • 360建网站百度竞价推广方案的制定
  • wordpress如何做主页设置刷关键词排名seo
  • 平面艺术设计seo按天计费系统
  • wordpress联系我插件太原网站建设方案优化
  • 做网站虚拟主机哪里有淘宝店铺怎么运营
  • 做细分行业信息网站网站建站模板
  • 网站制作包括哪些东莞做网站的公司有哪些
  • 计算机专业论文 网站建设广州seo怎么做
  • 苏州地区网站制作免费网站流量统计
  • 传奇网站传奇百度竞价推广代理商
  • 做交友网站成本百度关键词搜索
  • 个人备案网站内不能出现什么内容2021年近期舆情热点话题
  • 网站页面优化方法有哪些公司网站seo外包
  • 网站建设有限公电商网络推广
  • 做网站那家公司好制作网站需要什么软件
  • 现在注册公司好注册吗seo关键词排名
  • 易居系统登录网站手机版排名seo