最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue?elementui?實(shí)現(xiàn)圖片上傳后拖拽排序功能示例代碼

 更新時(shí)間:2023年01月16日 11:18:27   作者:醉逍遙neo  
這篇文章主要介紹了vue?elementui?實(shí)現(xiàn)圖片上傳后拖拽排序功能,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

很久沒(méi)寫技術(shù)博客了,今天是春節(jié)假期前最后一天上班,沒(méi)什么事情,就隨便寫寫吧,這次就分享一下之前封裝的一個(gè)圖片上傳組件的實(shí)現(xiàn)過(guò)程,這里主要分享下拖拽排序功能的一種實(shí)現(xiàn)方式。

在這里插入圖片描述

2021-11-17 更新:
文末附完整源碼及使用示例代碼

2021-08-30 更新:
新增vue3支持組件,采用script setup語(yǔ)法+ts語(yǔ)言,并拓展了一些功能,代碼見(jiàn)文章末尾。

1、主要技術(shù)棧

vue2、elementui2、vuedraggable2

2、需求分析

產(chǎn)品的要求就是多圖上傳完后,可以對(duì)圖片列表進(jìn)行拖拽排序。本身elementui的el-upload組件已經(jīng)支持很多功能,但是唯獨(dú)沒(méi)有拖拽排序,它的多圖上傳是按你上傳時(shí)選擇的文件的順序來(lái)展示。

一般產(chǎn)品提出的復(fù)雜功能咱開(kāi)發(fā)人員都是盡量簡(jiǎn)化或者砍掉哈哈,不過(guò)呢這個(gè)功能還是對(duì)用戶非常友好的,秉承著用戶至上的原則那就接下吧。

3、思路

要是用原生js手寫一個(gè)拖拽功能做起來(lái)會(huì)很復(fù)雜,h5的draggable原生api有點(diǎn)雞肋,很難實(shí)現(xiàn)一個(gè)比較好的交互效果,用js的mouseover不錯(cuò),但是要實(shí)現(xiàn)最終完整的交互效果還是很費(fèi)時(shí)間精力,所以還是找插件吧,通過(guò)拖拽插件和el-upload結(jié)合實(shí)現(xiàn)。

然后網(wǎng)上找到一個(gè)vuedraggable插件,github傳送門,看demo效果還可以,那么問(wèn)題來(lái)了,vuedraggable的使用方式是這樣的:

<draggable v-model="myArray" group="people" @start="drag=true" @end="drag=false">
   <div v-for="element in myArray" :key="element.id">{{element.name}}</div>
</draggable>

就是通過(guò)slot插槽的方式傳遞列表,只對(duì)插槽內(nèi)第一層級(jí)的元素起作用。而el-upload使用上傳后生成的列表是動(dòng)態(tài)生成的且無(wú)法手動(dòng)控制,也就是說(shuō)vuedraggable無(wú)法作用到el-upload生成的圖片列表,那就放棄使用el-upload的圖片列表,自己手動(dòng)寫個(gè)列表盒子來(lái)展示圖片,并把這個(gè)列表放在vuedraggable組件插槽中,上傳完后把獲取的url地址賦值過(guò)去。

DOM結(jié)構(gòu)大概如下:

<vuedraggable tag="ul" draggable=".draggable-item">
   <!-- 拖拽元素 -->
   <li
     v-for="(item, index) in imgList"
     :key="item + index"
     class="draggable-item"
   >
     <el-image :src="item" :preview-src-list="[item]"></el-image>
   </li>
   <!-- 上傳按鈕 -->
   <el-upload slot="footer">
     <i class="el-icon-plus uploadIcon"></i>
   </el-upload>
 </vuedraggable>

4、其他一些處理點(diǎn)

(1)圖片刪除

我的效果是鼠標(biāo)懸浮在圖片上時(shí)圖片右上角展示刪除按鈕,鼠標(biāo)移下時(shí)消失,這樣會(huì)有一個(gè)問(wèn)題就是用鼠標(biāo)拖拽完圖片后可能出現(xiàn)拖拽之前的位置換了新圖片但刪除按鈕還在,處理方式就是給vuedraggable綁定拖拽開(kāi)始和拖拽結(jié)束事件,拖拽開(kāi)始時(shí)添加隱藏刪除按鈕的類名,使拖拽過(guò)程中都不顯示刪除按鈕,拖拽結(jié)束再移除這個(gè)類名恢復(fù)正常。

onDragStart (e) {
  e.target.classList.add('hideShadow')
},
onDragEnd (e) {
  e.target.classList.remove('hideShadow')
}

(2)圖片預(yù)覽

單擊圖片即可預(yù)覽,我這里使用了el-image的組件,設(shè)置preview-src-list屬性就可以實(shí)現(xiàn)預(yù)覽,但是它的預(yù)覽會(huì)保留預(yù)覽時(shí)的狀態(tài),包括圖片翻頁(yè)的位置,所以這里就不要它的圖片翻頁(yè)功能了,直接通過(guò)數(shù)組[]包裹下該圖片的地址字符串。

<el-image :src="item" :preview-src-list="[item]"></el-image>

(3)上傳數(shù)量限制

由于圖片上傳仍然使用的el-upload組件,而圖片上傳是接口請(qǐng)求異步的,所以無(wú)法通過(guò)判斷圖片展示列表數(shù)量來(lái)控制圖片超限,那還是繼續(xù)使用el-upload自帶的上傳限制功能吧,也就是綁定on-exceed屬性。

需要處理的一點(diǎn)是在圖片展示列表刪除單張圖片后要同步下el-upload組件里上傳完的圖片數(shù)據(jù),這樣它才能正確判斷數(shù)量是否超限,而它的圖片數(shù)據(jù)都存儲(chǔ)在el-upload元素的uploadFiles屬性里,這個(gè)屬性在elementui官方文檔里沒(méi)有說(shuō)明,可以通過(guò)給el-upload綁定一個(gè)ref屬性,通過(guò)this.$refs.uploadRef.uploadFiles獲取,里面是一個(gè)數(shù)組,數(shù)組項(xiàng)是對(duì)象格式,有name、url、status、uid四個(gè)屬性,uid需要保證值的唯一性,

5、使用方式示例

引入封裝好的組件imgUpload,可以配合element的表單組件el-form:

<el-form
  label-position="right"
  label-width="120px"
  :model="formData"
  ref="formRef"
>
  <el-form-item label="文章圖片:" prop="imgList">
    <imgUpload v-model="formData.imgList"/>
  </el-form-item>
</el-form>

......

<script>
import imgUpload from '@/components/imgUpload'

export default {
  components: {
    imgUpload
  }
  data () {
    return {
      formData: {
        imgList: [] // formData初始值要帶上imgList屬性,以保證數(shù)據(jù)響應(yīng)式
      }
    }
  }
  ......
}
</script>
  • 使用封裝好的組件時(shí)通過(guò) v-model=“formData.imgList” 綁定了formData對(duì)象的imgList屬性,那么在vue的data給formData設(shè)置初始值時(shí)就必須添加imgList屬性,給一個(gè)默認(rèn)值空數(shù)組即可。(因?yàn)関ue2.0默認(rèn)無(wú)法監(jiān)聽(tīng)對(duì)象新增的屬性,所以初始結(jié)構(gòu)里就要包含這個(gè)屬性才能有響應(yīng)式,或者通過(guò)this.$set()手動(dòng)添加響應(yīng)式也可以。)

6、其他說(shuō)明

組件本身對(duì)外暴露了很多配置項(xiàng),包括一些配置項(xiàng)都依賴el-upload組件,這也是沒(méi)有自己手寫上傳功能的主要原因。
el-upload標(biāo)簽的action屬性是圖片上傳接口地址,記得換成你們公司自己的穩(wěn)定接口,然后根據(jù)你們接口返回的數(shù)據(jù)格式修改onSuccessUpload方法里的處理。

7、vue3語(yǔ)法封裝

(1)前置條件

  • vue版本:v3.2.0以上(因?yàn)橛玫搅藄cript setup語(yǔ)法,該語(yǔ)法在v3.2.0才轉(zhuǎn)為正式api,script setup語(yǔ)法使用參考)
  • vuedraggable版本:v4.1.0以上
  • element-plus版本:v1.0.2-beta.70,因?yàn)閑lement-plus一直在不斷更新,最新版會(huì)有一些不兼容問(wèn)題,比如新版移除了自帶字體圖標(biāo),只能手動(dòng)導(dǎo)入。

(2)imgUpload.vue組件完整代碼:
傳送門

8、常見(jiàn)問(wèn)題

題外話:

  • 這個(gè)組件封裝已經(jīng)在實(shí)際項(xiàng)目中經(jīng)受過(guò)考驗(yàn),不要懷疑。
  • 對(duì)于評(píng)論區(qū)和私信的問(wèn)題,基本都是vue的使用問(wèn)題,對(duì)vue的雙向數(shù)據(jù)綁定理解不到位,或者使用經(jīng)驗(yàn)不足導(dǎo)致的,而非本文組件的封裝問(wèn)題。

(1)刪除或拖拽操作后數(shù)據(jù)沒(méi)有變化

這種大多是數(shù)據(jù)響應(yīng)式的問(wèn)題,常見(jiàn)于vue2.x版本,vue2.x里數(shù)據(jù)字段需要在data里提前定義好初始值或者后面通過(guò)this.$set手動(dòng)設(shè)置,才能有數(shù)據(jù)響應(yīng)式,vue3.x里得益于proxy api的優(yōu)勢(shì)不會(huì)有這個(gè)問(wèn)題。

特別是數(shù)據(jù)回顯的時(shí)候,容易出現(xiàn)問(wèn)題,列舉以下幾個(gè)場(chǎng)景解決方式:

直接在一個(gè)頁(yè)面里:

方式1:先在data里定義好字段,獲取詳情接口拿到回顯數(shù)據(jù)后再賦值數(shù)據(jù)。

data () {
  return {
    formData: {
      imgList: [],
    }
  }
},
methods: {
  getDetail () {
    setTimeout(() => {
      const res = {
        imgList: ['https://abc.png']
      }
      this.formData = res
    }, 1000)
  }
}

方式2:data里未定義字段,獲取詳情接口拿到回顯數(shù)據(jù)后通過(guò)this.$set賦值。

data () {
  return {
    formData: {}
  }
},
methods: {
  getDetail () {
    setTimeout(() => {
      const res = {
        imgList: ['https://abc.png']
      }
      this.$set(this.formData, 'imgList', res.imgList)
    }, 1000)
  }
}

組件里props接收回顯數(shù)據(jù):

方式1:先在data里定義好字段,watch監(jiān)聽(tīng)props接收的回顯數(shù)據(jù)再賦值。

props: {
  detailData: {
	type: Object,
    default () {
	  return {}
	}
  }
},
data () {
  return {
    formData: {
      imgList: [],
    }
  }
},
watch: {
  detailData: {
	deep: true,
	handler (val) {
	  this.formData = val
	}
  }
},

方式2:通過(guò)computed get set 配合 this.$set 添加響應(yīng)式

props: {
? detailData: {
?? ?type: Object,
? ? default () {
?? ? ?return {}
?? ?}
? }
},
computed: {
? formData: {
? ? get () {
? ? ? const obj = this.detailData
? ? ? !obj.imgList && this.$set(obj, 'imgList', [])
? ? ? return obj
? ? },
? ? set (val) {
? ? ? this.$emit('update:formData', val)
? ? }
? },
}

9、完整源碼

為了更方便閱讀以及代碼示例,已經(jīng)把源碼和使用示例上傳到了github(傳送門),歡迎star。

到此這篇關(guān)于vue elementui 實(shí)現(xiàn)圖片上傳后拖拽排序功能的文章就介紹到這了,更多相關(guān)vue elementui拖拽排序內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue3?中使用?jsx?開(kāi)發(fā)的詳細(xì)過(guò)程

    vue3?中使用?jsx?開(kāi)發(fā)的詳細(xì)過(guò)程

    這篇文章主要介紹了vue3?中使用?jsx?開(kāi)發(fā),本文著重說(shuō)一下在使用 .vue 文件和 .jsx 文件在使用語(yǔ)法上的差異,需要的朋友可以參考下
    2022-09-09
  • Vue導(dǎo)入Echarts實(shí)現(xiàn)散點(diǎn)圖

    Vue導(dǎo)入Echarts實(shí)現(xiàn)散點(diǎn)圖

    這篇文章主要為大家詳細(xì)介紹了Vue導(dǎo)入Echarts實(shí)現(xiàn)散點(diǎn)圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-12-12
  • vue自定義樹(shù)狀結(jié)構(gòu)圖的實(shí)現(xiàn)方法

    vue自定義樹(shù)狀結(jié)構(gòu)圖的實(shí)現(xiàn)方法

    這篇文章主要給大家介紹了關(guān)于vue自定義樹(shù)狀結(jié)構(gòu)圖的實(shí)現(xiàn)方法,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • vue父組件異步傳遞props值,子組件接收不到解決方案

    vue父組件異步傳遞props值,子組件接收不到解決方案

    這篇文章主要介紹了vue父組件異步傳遞props值,子組件接收不到解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • vue監(jiān)聽(tīng)dom大小改變案例

    vue監(jiān)聽(tīng)dom大小改變案例

    這篇文章主要介紹了vue監(jiān)聽(tīng)dom大小改變案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-07-07
  • vue3中vue-meta的使用方法解析

    vue3中vue-meta的使用方法解析

    這篇文章主要介紹了vue3中vue-meta的使用方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Vue報(bào)錯(cuò)Module build failed: Error: Node Sass version 7.0.1 is incompatible with 4.0.0.解決方案

    Vue報(bào)錯(cuò)Module build failed: Error: Node&nb

    這篇文章主要介紹了Vue報(bào)錯(cuò)Module build failed: Error: Node Sass version 7.0.1 is incompatible with 4.0.0.解決方案,需要的朋友可以參考下
    2023-06-06
  • Vue中失去焦點(diǎn)時(shí)所觸發(fā)的事件問(wèn)題

    Vue中失去焦點(diǎn)時(shí)所觸發(fā)的事件問(wèn)題

    這篇文章主要介紹了Vue中失去焦點(diǎn)時(shí)所觸發(fā)的事件問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Vue 3.0自定義指令的使用入門

    Vue 3.0自定義指令的使用入門

    在 Vue 的項(xiàng)目中,我們經(jīng)常會(huì)遇到 v-if、v-show、v-for 或 v-model 這些內(nèi)置指令,它們?yōu)槲覀兲峁┝瞬煌墓δ?。除了使用這些內(nèi)置指令之外,Vue 也允許注冊(cè)自定義指令。接下來(lái),將使用Vue 3官方文檔自定義指令章節(jié)中使用的示例,來(lái)一步步揭開(kāi)自定義指令背后的秘密。
    2021-05-05
  • 利用Vue Router實(shí)現(xiàn)單頁(yè)面應(yīng)用(SPA)的代碼示例

    利用Vue Router實(shí)現(xiàn)單頁(yè)面應(yīng)用(SPA)的代碼示例

    在當(dāng)今前端開(kāi)發(fā)中,單頁(yè)面應(yīng)用(SPA)已成為一種主流的開(kāi)發(fā)模式,它通過(guò)在用戶與網(wǎng)頁(yè)之間提供更流暢的交互體驗(yàn),來(lái)改變傳統(tǒng)多頁(yè)面應(yīng)用的思維,本文將詳細(xì)介紹如何利用 Vue.js 中的 Vue Router 來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的單頁(yè)面應(yīng)用,需要的朋友可以參考下
    2025-01-01

最新評(píng)論

南丹县| 建德市| 惠水县| 扬中市| 安化县| 许昌县| 江北区| 康定县| 凭祥市| 蒙阴县| 玉环县| 武义县| 津南区| 岐山县| 广州市| 女性| 蓝田县| 和静县| 武清区| 江油市| 商河县| 民和| 白水县| 新郑市| 前郭尔| 新宁县| 寿阳县| 盐边县| 平定县| 冕宁县| 杭锦后旗| 武山县| 井冈山市| 嘉定区| 大新县| 定陶县| 商洛市| 石楼县| 南开区| 彩票| 苏尼特左旗|