国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

我是如何設(shè)計(jì) Upload 上傳組件的

malakashi / 1789人閱讀

摘要:組件設(shè)計(jì)的目標(biāo)是解決用戶上傳文件的便利性,但是中后臺組件的場景是多種多樣的,所以可擴(kuò)展能力是組件不可忽視的另一方面。我們可能的期望是在任何瀏覽器下交互和都一致的組件。由此我們做出了兩個通用的組件文件選擇器。

Upload 組件設(shè)計(jì)的目標(biāo)是解決用戶上傳文件的便利性,但是中后臺 Upload 組件的場景是多種多樣的,所以可擴(kuò)展能力是 Upload 組件不可忽視的另一方面。

同樣為了大家能夠更加容易的理解,我會從最原始的 input 標(biāo)簽開始說起

這段代碼功能: 先選擇一個文件,再點(diǎn)提交 POST 一個文件到一個接口。代碼雖然不多,但是在實(shí)際使用中值得吐槽的點(diǎn)卻不少,這里重點(diǎn)說兩個點(diǎn)。

在每個瀏覽器上面的表現(xiàn)是各不一樣的。

先不說UI不美觀,在每個主流瀏覽器上面的文案基本都不一樣,另外在IE下面變化似乎有點(diǎn)大。我們可能的期望是在任何瀏覽器下交互和UI都一致的組件。

文件上傳完后頁面會刷新帶來的體驗(yàn)問題

原生的文件上傳都是通過form post 上傳,上傳完成后整個頁面會重定向到 action 的地址?,F(xiàn)在大家已經(jīng)習(xí)慣了 ajax 做數(shù)據(jù)提交,因?yàn)榭梢圆恍枰猺eload頁面就可以帶來整個頁面的數(shù)據(jù)更新,無刷新更新的體驗(yàn)會提升很多。

我打算整片拆兩個段來講這個問題,拆分點(diǎn)大約從2012年附近開始,因?yàn)?html5 差不多在這個時間段開始被現(xiàn)代瀏覽器逐步支持。兩個段分別叫傳統(tǒng)解決方案和現(xiàn)代解決方案

傳統(tǒng)解決方案

UI 一致性問題

我們期望在任何瀏覽器下都是一個樣式,比如一種樣式的按鈕

通過把 input 設(shè)置為透明覆蓋在 button 按鈕上面,讓用戶以為自己點(diǎn)擊的是 button,其實(shí)點(diǎn)擊的是 button 上面的 input。這樣就可以做成用戶點(diǎn)擊button就能選擇文件的“假象”。

查找 button 其實(shí)定位到了 input。詳細(xì)代碼可以看這里: https://github.com/alibaba-fu...

無刷新上傳

我們期望選擇完文件立刻執(zhí)行上傳,上傳完成后直接在頁面上展現(xiàn)上傳狀態(tài)


在提交的時候 form 通過 target 指定到對應(yīng)的 iframe 去上傳數(shù)據(jù),讓form 的數(shù)據(jù)通過隱藏的 iframe 來提交。

const doc = this.refs.iframe.contentDocument; // 取 iframe
const script = doc.getElementsByTagName("script")[0]; // 清除 iframe 內(nèi)無用 script
if (script && script.parentNode === doc.body) {
  doc.body.removeChild(script);
}
const response = JSON.parse(doc.body.innerHTML); // 取返回內(nèi)容解析成 JSON

因?yàn)?iframe 完成上傳后頁面會整體刷新,再通過監(jiān)聽 iframe 的 onLoad 事件獲取返回的結(jié)果。關(guān)于獲取返回內(nèi)容如何再給主頁面做反饋展示的代碼可以看這里: https://github.com/alibaba-fu...

現(xiàn)代上傳方案

html5 出來后,可以通過 input 可以直接拿到 File 文件對象,再把 File 封裝到 FormData,通過 ajax 的形式提交到后端接口實(shí)現(xiàn)文件上傳。

UI 一致性問題

不需要再把 input 蓋在 button 上面,而是通過監(jiān)聽父節(jié)點(diǎn)的點(diǎn)擊事件,在事件里面觸發(fā) input 的 click 方法。


我其實(shí)可以在 div 里面放的不僅僅是 button 了,可以是任何元素,這樣我們就能做出任何形狀的上傳按鈕。 下面列舉幾個例子

卡片狀態(tài)

Upload File

上傳面板

點(diǎn)擊或者拖動文件到虛線框內(nèi)上傳 支持 docx, xls, PDF, rar, zip, PNG, JPG 等類型文件

無刷新上傳

原理是把 File 對象封裝到 FormData,再通過 ajax 的形式提交到后端接口。直接上代碼:

function upload(file) {
    const xhr = new XMLHttpRequest();

    // 上傳進(jìn)度
    xhr.upload.onprogress = function progress(e) {
    };
    // 上傳狀態(tài)
    xhr.onload = function onload() {
    };
  
    const formData = new FormData();
    // 往 formData 里面增加要上傳的文件對象
    formData.append("filename", file);

    // 指定 api 接口和上傳方式
    xhr.open("POST", "/api/upload", true);
    // 開始發(fā)送數(shù)據(jù)
    xhr.send(formData);
}

以上是把一個 file 對象加到 formData 中,再通過 XMLHttpRequest 把 formData 發(fā)送到指定的接口 /api/upload 的一個大致過程。詳細(xì)代碼可以查看這里 https://github.com/alibaba-fu...

我們現(xiàn)實(shí)中為了可能為了兼容 ie9 , 所以還需要封裝一個 uploader,優(yōu)先支持 html5 但是在 ie9 下自動切換為 iframe 方案。

一個通用的 React 上傳組件解決方案

上面我們講了一個文件上傳一定是至少有兩步:1. 選擇文件 2. 上傳文件。并且我們已經(jīng)有能力根據(jù)瀏覽器自動判斷用什么兼容方案。

由此我們做出了兩個通用的組件:

Selecter 文件選擇器??梢宰屓魏谓M件變成一個文件選擇器,并且返回選擇后的 File 對象

Uploader 文件上傳器。可以像掉 api 一樣隨心所欲的上傳選擇的文件,并且可監(jiān)控進(jìn)度。

Selecter 文件選擇器

封裝后的 Selecter 把 input 和相關(guān)事件已經(jīng)處理好了,你只需要關(guān)心往里面丟什么

import {Upload, Button} from "@alifd/next";
const Selecter = Upload.Selecter;

class App extends React.Comonent {
  handleSelect = (files) => {
    // get files
  }
  render() {
    return 
      
    
  }
}

如果要換成卡片樣式,只要把 children 換掉即可,如下


  
   Upload File 

Uploader 文件上傳器

把 Selecter 選擇后的File 給 Uploader ,可以很方便的把文件上傳到指定接口。

import {Upload, Button} from "@alifd/next";
const Selecter = Upload.Selecter; // 文件選擇器
const Uploader = Upload.Uploader; // 文件上傳器

class App extends React.Comonent {
  uploader = new Uploader({
    action: "/api/upload",
  //onProgress: this.onProgress // 進(jìn)度監(jiān)控
  });

  handleSelect = (files) => {
    // 上傳文件
    this.uploader.startUpload(files);
  }
  render() {
    return 
      
    
  }
}

因?yàn)镾electer的UI可定制,Uploader 的文件上傳時機(jī)可以隨便控制。是的 Selecter 和 Uploader 的組合得以適配任何場景和交互。調(diào)試demo 見: https://codepen.io/frankqian/...

比如我們可以通過 Uploader 自定義各種功能,比如做一個 粘貼上傳組件

去除用來裝飾的進(jìn)度條,不到20行代碼就寫完了整個組件:

import { Upload, Input } from "@alifd/next";

const Uploader = Upload.Uploader; // 文件上傳器

class App extends React.Component {
  uploader = new Uploader({
    action: "/api/upload",
  });
  // 處理粘貼事件
  onPaste = e => {
    const files = e.clipboardData.files; // 獲取粘貼的文件數(shù)據(jù)
    this.uploader.startUpload(files); // 上傳文件
  };
  render() {
    return ;
  }
}

可以在這里調(diào)試代碼:https://codepen.io/frankqian/...

進(jìn)一步提取更通用的使用方式
解決易用性的問題

Selecter 和 Uploader 使用起來雖然非常靈活,但是還是要自己寫一些邏輯,把取到的 File 對象和 Uploader 做上傳關(guān)聯(lián)。而我們在文件上傳最常用的交互方式是選擇完就開始上傳、上傳完成后給反饋。所以我們把常見的交互進(jìn)一步做提取,單按鈕、卡片、拖拽面板 等,主要把常用UI和上傳交互沉淀下來,方便大多的場景使用。

import {Upload, Button} from "@alifd/next";

class App extends React.Comonent {
  handleChange = (file) => {
    console.log(file.url); // 直接獲取圖片 url
  }
  render() {
    return 
Upload File
} }

以上就結(jié)合業(yè)務(wù)線常用的上傳方案和交互提取的上傳方式,我們把 Selecter 和 Uploader 進(jìn)行進(jìn)一步封裝,得到一個UI和交互相對固定的組件,使用起來更便捷。

阿里內(nèi)部各個業(yè)務(wù)線上傳的需求是多種多樣的,F(xiàn)usion Next 的 Upload 組件要考慮效率和能力之前的平衡。一個好的組件應(yīng)該通過固定組件去解決 80% 的通用問題;剩下的 20% 可能各業(yè)務(wù)線不一樣,可以通過擴(kuò)展能力讓各業(yè)務(wù)線去支持。

相關(guān)鏈接
Fusion Upload: https://fusion.design/compone...
github: https://github.com/alibaba-fu...

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/101865.html

相關(guān)文章

  • 聊聊畢業(yè)設(shè)計(jì)系列 --- 系統(tǒng)實(shí)現(xiàn)

    摘要:七牛云接入本系統(tǒng)的圖片,音視頻是放在七牛云,所以需要接入七牛云。在服務(wù)端通過接口請求來獲取七牛云上傳,客戶端獲取到七牛云,通過不同方案將帶上。 效果展示 showImg(https://user-gold-cdn.xitu.io/2018/8/26/16576a709bd02f5f?w=1409&h=521&f=gif&s=30128195); showImg(https://user...

    null1145 評論0 收藏0
  • 聊聊畢業(yè)設(shè)計(jì)系列 --- 系統(tǒng)實(shí)現(xiàn)

    摘要:七牛云接入本系統(tǒng)的圖片,音視頻是放在七牛云,所以需要接入七牛云。在服務(wù)端通過接口請求來獲取七牛云上傳,客戶端獲取到七牛云,通過不同方案將帶上。 效果展示 showImg(https://user-gold-cdn.xitu.io/2018/8/26/16576a709bd02f5f?w=1409&h=521&f=gif&s=30128195); showImg(https://user...

    qpal 評論0 收藏0

發(fā)表評論

0條評論

malakashi

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<