カテゴリー
コンピューター

Vue.js 3 で Dropzone をラップした SFC その2 。 HTML 要素 の `id` ではなく要素そのものを指定して Dropzone と紐付ける等

カスタマイズした内容

  • <template><div> 要素の id ではなく、 <div> 要素そのものを Dropzone を紐づくようにした。
  • Dropzone の options を渡せるようにした。

コード全体

Dropzone をラップした SFC 、 laravel/resources/js/components/BaseDropzone.vue 、です。これを利用するコンポーネントのコードは 以前 と同じです、割愛します。

<template>
  <div ref="root" class="dropzone" />
</template>

<script>
import { onMounted, ref } from "vue";
import Dropzone from "dropzone";
export default {
  name: "BaseDropzone",
  props: {
    options: {
      default: () => {},
      required: false,
      type: Object,
    },
    url: {
      type: String,
      require: true,
      default: "",
    },
  },
  emits: ["onSuccess"],
  setup(props, { emit }) {
    const root = ref(null);

    onMounted(() => {
      Dropzone.autoDiscover = false;
      //new Dropzone("div#myId", { url: "https://httpbin.org/post" });
      const myDropzone = new Dropzone(root.value, {
        url: props.url,
        addRemoveLinks: true,
        dictDefaultMessage:
          "画像ファイルをここにドロップするか、クリックしてアップロード",
        dictCancelUpload: "アップロードをキャンセル",
        dictRemoveFile: "操作エリアから除去",
        ...props.options,
      });

      myDropzone.on("success", (file, response) => {
        emit("onSuccess", file, response);
        setTimeout(() => myDropzone.removeFile(file), 10000);
      });
      myDropzone.on("error", function (file, errorMessage) {
        console.log("error", file, errorMessage); // TODO デバッグ用途。後で消すこと。
        // レスポンスの内容を使用するときは、エラーメッセージの後ろに付与すればよさそう。
        file.previewTemplate.getElementsByClassName(
          "dz-error-message"
        )[0].textContent = "アップロードに失敗しました。";
      });
    });

    return { root };
  },
};
</script>

<style>
.dz-success {
  transition: opacity 10s, visibility 0s ease 10s;
  opacity: 0;
  visibility: hidden;
}
</style>
<!--
ここでスタイルを読み込むことも可能
<style src="../../../node_modules/dropzone/dist/dropzone.css"></style>
-->

コードの変更点抜粋。 <template><div> 要素の id ではなく、 <div> 要素そのものを Dropzone を紐づくようにした。

Select2 や flatpickr のラッパー SFC でのやり方に合わせた形になります。変更点の抜粋です。

<template>
  <div ref="root" class="dropzone" />
</template>

<script>
import { onMounted, ref } from "vue";

... 略 ...

  setup(props, { emit }) {
    const root = ref(null);

... 略 ...

      const myDropzone = new Dropzone(root.value, {

... 略 ...

    return { root };
  },

コードの変更点抜粋。 Dropzone の options を渡せるようにした。

変更点の抜粋です。

  props: {
    options: {
      default: () => {},
      required: false,
      type: Object,
    },

... 略 ...

      const myDropzone = new Dropzone(root.value, {
        url: props.url,
        addRemoveLinks: true,
        dictDefaultMessage:
          "画像ファイルをここにドロップするか、クリックしてアップロード",
        dictCancelUpload: "アップロードをキャンセル",
        dictRemoveFile: "操作エリアから除去",
        ...props.options,
      });

おわりに

<template><div> 要素の id ではなく、 <div> 要素そのものを Dropzone を紐づくようにした。

今回のこの修正で何が嬉しいのか ? もしかしたら意味はないのかもしれません。が、 HTML 要素 の id を Dropzone に紐づけていた以前の状態の場合、ラッパー SFC を同じページに複数配置した時に id が複数存在することになるため予期せぬエラーが発生する可能性がありました。そのエラーを抑制できているのではないか ? と思います。

以上です。

コメントを残す