Maison > interface Web > js tutoriel > le corps du texte

vue-simplemde implémente la fonction glisser-coller d'image (code joint)

php中世界最好的语言
Libérer: 2018-04-28 13:59:50
original
2680 Les gens l'ont consulté

Cette fois, je vais vous présenter vue-simplemde pour implémenter la fonction glisser-coller d'image (avec code). Quelles sont les précautions pour que vue-simplemde implémente la fonction glisser-coller d'image. est un cas pratique. Levez-vous et jetez un œil.

Le projet utilise le framework vue et a besoin d'une boîte d'édition markdown. Je l'ai recherché sur npm et j'ai trouvé que simplemde est plutôt bon, j'ai cherché à nouveau sur npm et je l'ai trouvé. Ce package, puis commencez à l'utiliser. vue-simplemde

Mais ceci

ne prend pas en charge le téléchargement par glisser-déposer ou le téléchargement par collage d'images, et on ne peut pas dire que cela soit dû à vue-simplemde, car vue-simplemde n'est encapsulé que dans un plug Vue. -in basé sur simplemde. Donc au final, c'est parce que simplemde ne fournit pas de fonctions pertinentes, mais pour le bien de l'expérience utilisateur, cette fonction est nécessaire à moins que l'éditeur de démarques ne soit pas utilisé. Utilisez plutôt un éditeur de texte enrichi. Dans ce cas, une grande partie du code du projet devra être modifiée. J'ai donc vérifié des articles en ligne et quelques codes sur github. Ce qui suit sera analysé vue-simplemde

Glisser-déposer

Le cœur de l'API glisser est l'événement de dépôt, c'est-à-dire lorsque nous faisons glisser un fichier du bureau au nom de l'événement déclenché lors de la sortie du navigateur.

Nous savons tous que si vous faites glisser une image dans le navigateur, l'image sera ouverte directement car le navigateur ouvre par défaut le fichier lorsque vous faites glisser le fichier dans le navigateur. empêcher les opérations natives.

Écrivons maintenant un morceau de code pour bloquer l'événement par défaut

window.addEventListener("drop", e => {
 e = e || event
 if (e.target.className === 'CodeMirror-scroll') { // 如果进入到编辑器的话,将阻止默认事件
 e.preventDefault()
 }
}, false)
Copier après la connexion
CodeMirror-scroll Cette classe est le nom de classe de la zone d'édition simple.

Maintenant, nous faisons glisser le fichier dans cette zone d'édition, puis nous le relâchons. Rien ne se passera. S'il se trouve en dehors de la zone d'édition, l'événement par défaut sera toujours déclenché.

Ce qui suit consiste à obtenir la méthode simplemde et à lui donner la méthode drop

gestion des événements.

// 假设页面一共有三个编辑窗口,所以需要循环监听事件
[ this.$refs.simplemde1,
 this.$refs.simplemde2,
 this.$refs.simplemde3
].map(({simplemde}) => {
 simplemde.codemirror.on('drop', (editor, e) => {
 if (!(e.dataTransfer && e.dataTransfer.files)) {
  // 弹窗说明,此浏览器不支持此操作
  return
 }
 let dataList = e.dataTransfer.files
 let imageFiles = [] // 要上传的文件实例数组
 // 循环,是因为可能会同时拖动几个图片文件
 for (let i = 0; i < dataList.length; i++) {
 // 如果不是图片,则弹窗警告 仅支持拖拽图片文件
  if (dataList[i].type.indexOf(&#39;image&#39;) === -1) {
  // 下面的continue,作用是,如果用户同时拖动2个图片和一个文档,那么文档不给于上传,图片照常上传。
  continue
  }
  imageFiles.push(dataList[i]) // 先把当前的文件push进数组里,等for循环结束之后,统一上传。
 }
 // uploadImagesFile方法是上传图片的方法
 // simplemde.codemirror的作用是用于区分当前的图片上传是处于哪个编辑框
 this.uploadImagesFile(simplemde.codemirror, imageFiles)
 // 因为已经有了下面这段代码,所以上面的屏蔽默认事件代码就不用写了
 e.preventDefault()
 })
})
Copier après la connexion
À première vue, le code semble un peu trop gros à cause des commentaires. Ce qui suit est le code sans commentaires. Vous pouvez avoir vos propres opinions et compréhension sur la base du code suivant :

[ this.$refs.simplemde1,
 this.$refs.simplemde2,
 this.$refs.simplemde3
].map(({simplemde}) => {
 simplemde.codemirror.on('drop', (editor, e) => {
 if (!(e.dataTransfer && e.dataTransfer.files)) {
  return
 }
 let dataList = e.dataTransfer.files
 let imageFiles = []
 for (let i = 0; i < dataList.length; i++) {
  if (dataList[i].type.indexOf(&#39;image&#39;) === -1) {
  continue
  }
  imageFiles.push(dataList[i])
 }
 this.uploadImagesFile(simplemde.codemirror, imageFiles)
 e.preventDefault()
 })
})
Copier après la connexion

Coller

L'API de collage est la méthode de collage, Ceci Contrairement à ce qui précède, il n'est pas nécessaire de désactiver l'événement par défaut pour le coller, car nous pouvons voir que lorsque vous copiez une image et appuyez sur ctrl+v dans le navigateur, rien ne changera, il n'est donc pas nécessaire de désactiver l'événement par défaut. .

Voici le code :

simplemde.codemirror.on(&#39;paste&#39;, (editor, e) => { // 粘贴图片的触发函数
 if (!(e.clipboardData && e.clipboardData.items)) {
 // 弹窗说明,此浏览器不支持此操作
 return
 }
 try {
 let dataList = e.clipboardData.items
 if (dataList[0].kind === 'file' && dataList[0].getAsFile().type.indexOf('image') !== -1) {
  this.uploadImagesFile(simplemde.codemirror, [dataList[0].getAsFile()])
 }
 } catch (e) {
 // 弹窗说明,只能粘贴图片
 }
})
Copier après la connexion
La raison pour laquelle la méthode try...catch est écrite ici est que si vous la collez, s'il s'agit d'un fichier, les éléments seront vide. Dans la boucle if ci-dessous, utilisez dataList[0].kind. C'est e.clipboardData.items[0].kind. Lorsque l'élément est vide et que vous accédez à un attribut kind inexistant, une erreur sera signalée. Donc ici, vous devez utiliser la méthode try...catch pour juger.

Cette phrase est un jugement. Il est confirmé que l'objet collé est une image et non autre chose. dataList[0].getAsFile().type.indexOf('image') !== -1

La différence entre les images téléchargées dans if est [dataList[0].getAsFile()], car afin d'unifier le format et de faciliter le traitement par la fonction uploadImagesFile, j'ai ajouté [] pour en faire un tableau . dataList[0].getAsFile() consiste à obtenir l'instance de fichier.

Téléchargement

Le téléchargement est un peu gênant :

uploadImagesFile (simplemde, files) {
 // 把每个文件实例使用FormData进行包装一下,然后返回一个数组
 let params = files.map(file => {
 let param = new FormData()
 param.append('file', file, file.name)
 return param
 })
 let makeRequest = params => {
 return this.$http.post('/Api/upload', params)
 }
 let requests = params.map(makeRequest)
 this.$http.spread = callback => {
 return arr => {
  return callback.apply(null, arr)
 }
 }
 // 服务端返回的格式是{state: Boolean, data: String}
 // state为false时,data就是返回的错误信息
 // state为true时,data是图片上传后url地址,这个地址是针对网站的绝对路径。如下:
 // /static/upload/2cfd6a50-3d30-11e8-b351-0d25ce9162a3.png
 Promise.all(requests)
 .then(this.$http.spread((...resps) => {
  for (let i = 0; i < resps.length; i++) {
  let {state, data} = resps[i].data
  if (!state) {
   // 弹窗显示data的错误信息
   continue
  }
  let url = `![](${location.origin + data})` // 拼接成markdown语法
  let content = simplemde.getValue()
  simplemde.setValue(content + url + &#39;\n&#39;) // 和编辑框之前的内容进行拼接
  }
 }))
}
Copier après la connexion
Parce que j'ai encapsulé axiox en tant que plug-in vue Pour l'utiliser, cela entraînera l'instanciation de this.$http, pas lui-même. La solution suggérée par le responsable d'axios est de réintroduire le package axios et de l'utiliser. Mais je ne pense pas que ce soit nécessaire. En interne, axios.all est Promise.all . Le code d'implémentation d'axios.spread est relativement petit, alors prenez-le simplement et réaffectez-le à axios

Donc le code ci-dessus est

Promise.all(requests)
 .then(this.$http.spread((...resps) => {
 // code
 })
Copier après la connexion
Traduisez ce code et ce sera

axios.all(requests)
 .then(axios.spread((...resps) => {
 // code
 })
Copier après la connexion
Concernant ce problème, veuillez consulter l'explication officielle : axios-all-is-not-a-function-inside-vue-component. Vous pouvez également jeter un oeil au code d'axios : axios.js#L45-L48

Nous n'aborderons pas cette question pour le moment. Revenons sur le sujet tout à l'heure.

J'ai mentionné ci-dessus que lorsque l'état est vrai, les données sont le chemin absolu du fichier par rapport au site Web, tel que : /static/upload/2cfd6a50-3d30-11e8-b351-0d25ce9162a3.png

Je pense que vous maîtrisez la méthode après avoir lu le cas dans cet article. Pour des informations plus intéressantes, veuillez prêter attention aux autres articles connexes sur le site Web chinois de php !

Lecture recommandée :

Téléchargement de la conversion d'encodage jQuery en base64 via AJAX

Spécification d'écriture du composant Vue

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal