Rumah  >  Artikel  >  hujung hadapan web  >  Bagaimana untuk mendapatkan sumber yang berbeza dan menukar gambar mengikut tema dalam Vue

Bagaimana untuk mendapatkan sumber yang berbeza dan menukar gambar mengikut tema dalam Vue

青灯夜游
青灯夜游ke hadapan
2021-12-02 19:12:012037semak imbas

Bagaimana untuk mendapatkan sumber yang berbeza dan menukar imej mengikut tema dalam Vue? Artikel berikut akan memperkenalkan kepada anda kaedah elegan Vue untuk merealisasikan keperluan kulit berbilang imej saya harap ia akan membantu anda.

Bagaimana untuk mendapatkan sumber yang berbeza dan menukar gambar mengikut tema dalam Vue

[Syor berkaitan: "tutorial vue.js"]

Baru-baru ini, permainan kecil Y syarikat perlu dilaksanakan tema setempat , iaitu, kawasan yang berbeza perlu memaparkan tema yang berbeza, dan terdapat banyak gambar dalam permainan Bagaimana untuk memuatkan gambar kulit yang betul secara elegan dan cepat menjadi sangat penting.

Sudah ada banyak penyelesaian dalam komuniti pensuisan gaya css, anda boleh merujuk kepada mereka sendiri Artikel itu telah diterangkan dengan terperinci, jadi saya tidak akan membincangkan secara terperinci di sini bagaimana untuk mendapatkan sumber yang berbeza untuk menukar imej mengikut tema.

Pelan awal

Pemutihan semula imej, berdasarkan pengalaman lalu, terima kasih kepada pengurusan pergantungan pek web, biasanya kami menggunakan keperluan untuk memperkenalkan imej. Sebagai contoh, jika anda menulis (require(`@assets/img/${theme}/bg.png`)) dengan cara ini, webpack akan menambah semua fail dalam @assets/img pada berkas, supaya imej yang sepadan boleh ditemui semasa dijalankan. Pelaksanaan khusus adalah seperti berikut:

<template>
  <!-- 这里需要判断图片是否存在,如果不存在需要指定为auto,不然会引起404,导致系统告警 -->
  <div class="y-content" :style="{backgroundImage: contentBg ? `url(${contentBg})` : &#39;auto&#39;}">
    <img class="y-content__reward" :src="rewardImg" />
  </div>
</template>

<script>
  data: () => ({
    theme: &#39;blcak&#39;
  }),
  computed: {
    contentBg() {
      try {
        // this.theme是文件夹,将不同的皮肤放到不同的文件夹,用同样的命名
        return require(`@assets/img/${this.theme}/contentBg.png`)
      } catch (err) {
        return &#39;&#39;;
      }
    },
    rewardImg() {
      try {
        return require(`@assets/img/${this.theme}/rewardImg.png`)
      } catch (err) {
        return &#39;&#39;;
      }
    }
  }
</script>

Kod di atas pada asasnya boleh menyelesaikan kebanyakan keperluan perubahan kulit, tetapi untuk projek yang memerlukan pra-pemuatan imej, kami juga perlu membezakan imej tema yang berbeza untuk memudahkan pengoptimuman dan pemuatan awal Disebabkan oleh penyusunan Pautan imej yang dikompilasi adalah berbeza daripada pautan yang dikompilasi, jadi kami mendapat pautan imej yang dikompilasi. Dalam projek umum, seperti projek yang dibina menggunakan perancah rasmi vue-cli, semua imej akan url-loader diproses dan diletakkan dalam imej folder yang sama, supaya sebelum penyusunan imej dengan nama yang sama dalam folder yang berbeza Selepas penyusunan, hash adalah berbeza, jadi kami tidak dapat membezakan gambar tema yang berbeza.

Jadi, mula-mula kita perlu meletakkan gambar tema yang berbeza ke dalam folder yang berbeza Perkara yang sama berlaku untuk menggunakan url-loader

// vue-cli配置
const imagesRule = config.module.rule(&#39;images&#39;);
imagesRule.uses.clear()        //清除原本的images loader配置
imagesRule
  .test(/white/.+.(jpg|gif|png|svg)$/)
  .use(&#39;url-loader&#39;)
    .loader(&#39;url-loader&#39;)
    .options({ name:"img/white/[name].[hash:8].[ext]", limit: 8192 })

// 加多一个主题的配置
config.module
  .rule(&#39;image2&#39;)
  .test(/black/.+.(jpg|gif|png|svg)$/)
  .use(&#39;url-loader&#39;)
    .loader(&#39;url-loader&#39;)
    .options({name:"img/black/[name].[hash:8].[ext]", limit: 8192 })
    
// 自定义webpack配置
rules: [
  {
    test: /white/.+.(png|svg|jpg|gif)$/,
    use: [
      {
      loader: &#39;url-loader&#39;,
        options: {
          limit: 8192,
          name: &#39;img/white/[name].[hash:8].[ext]&#39;,
        }
      }
    ],
  },
  {
    test: /black/.+.(png|svg|jpg|gif)$/,
    use: [
      {
      loader: &#39;url-loader&#39;,
        options: {
          limit: 8192,
          name: &#39;img/black/[name].[hash:8].[ext]&#39;,
        }
      }
    ],
  },
]

Dengan cara ini, selepas menyusun, gambar-gambar tema yang berbeza akan. menjadi Letakkannya dalam folder yang berbeza, adakah itu penghujungnya? Belum lagi, kami masih perlu mendapatkan pautan imej yang disusun untuk memuatkan imej tema terlebih dahulu apabila memasuki halaman permainan Di sini kami boleh menulis pemalam webpack untuk membantu kami mengumpul imej yang sepadan dan menghasilkan fail json untuk setiap tema. Kod pemalam adalah seperti berikut:

// webpack版本为4.x
class WebPackSouceManifest {
  // 将 `apply` 定义为其原型方法,此方法以 compiler 作为参数
  constructor(option = {}) {
    // 黑色主题的文件名
    this.blackManifestName = option.blackManifestName || &#39;js/blackManifest.json&#39; 
    // 白色主题的文件名
    this.whiteManifestName = option.whiteManifestName || &#39;js/whiteManifest.json&#39;
    this.blackJsonData = {
      code: 0,
      data: []
    }
    this.whiteJsonData = {
      code: 0,
      data: []
    }
    this.addFileToSouceManifest.bind(this)
  }

  apply(compiler) {
    // 指定要附加到的事件钩子函数
    compiler.hooks.emit.tapAsync(
      &#39;HashServiceWorkerStartPlugin&#39;,
      (compilation, callback) => {
        const allBuildFiles = Object.keys(compilation.assets)
        allBuildFiles.forEach((file) => {
          if (file.indexOf(&#39;white&#39;) !== -1) {
            this.addFileToSouceManifest(&#39;white&#39;, file)
          } else {
            this.addFileToSouceManifest(&#39;black&#39;, file)
          }
        })


        const sourceBlack = JSON.stringify(this.blackJsonData)
        const sourceWhite = JSON.stringify(this.whiteJsonData)
        compilation.assets[this.blackManifestName] = {
          source: () => {
            return sourceBlack;
          },
          size: () => {
            return sourceBlack.length;
          }
        }

        compilation.assets[this.whiteManifestName] = {
          source: () => {
            return sourceWhite;
          },
          size: () => {
            return sourceWhite.length;
          }
        }
        callback()
      }
    );
  }

  addFileToSouceManifest(type, file) {
    let fileItem = {
      src: file,
    }
    if (/.js$/.test(file)) {
      fileItem.type = &#39;text&#39;
    } else if (/.js.map$/.test(file)) {
      fileItem.type = &#39;json&#39;
    }
    if (type === &#39;white&#39;) {
      this.whiteJsonData.data.push(fileItem)
    } else {
      this.blackJsonData.data.push(fileItem)
    }
  }
}

module.exports = WebPackSouceManifest;

Jadi kami mendapat senarai imej json tema yang berbeza Apabila memasuki halaman, kami mendapat senarai melalui ajax dan kemudian memuatkan imej dalam jadual lain. Walaupun pendekatan di atas boleh memenuhi keperluan, tetapi adakah ia terlalu rumit? Adakah terdapat cara mudah? Sudah tentu ada.

Pelan pengoptimuman

Setelah menganalisis kod di atas dengan teliti, apa yang akhirnya kita ingin dapatkan ialah hasil terkumpul imej, jadi jika kita boleh menjana objek gambar, name imej digunakan sebagai kunci, dan hasil kompilasi imej digunakan sebagai nilai Kemudian kod di atas boleh dipermudahkan seperti berikut:

<template>
  <!-- 这里需要判断图片是否存在,如果不存在需要指定为auto,不然会引起404,导致系统告警 -->
  <div class="y-content" :style="{backgroundImage: contentBg ? `url(${contentBg})` : &#39;auto&#39;}">
    <img class="y-content__reward" :src="rewardImg" />
  </div>
</template>

<script>
  data: () => ({
    theme: &#39;middleEast&#39;
  }),
  computed: {
    contentBg() {
      // skinImage是跟组件下的字段
      return this.$root.skinImage[&#39;contentBg&#39;] // contentBg为name
    },
    rewardImg() {
      return this.$root.skinImage[&#39;rewardImg&#39;]
    }
  }
</script>

Dengan cara ini, kod menjadi ringkas dan tidak memerlukan keseluruhan keperluan dan tindakan susulan, bagaimana kita melaksanakan objek skinImage ini? dapatkan konteks khusus dengan melaksanakan fungsi require.context, yang digunakan terutamanya untuk mencapai automasi dalam projek bahagian hadapan, jika anda menghadapi situasi mengimport banyak modul dari folder, anda boleh menggunakan API ini melintasi fail yang ditentukan dalam folder dan kemudian mengimportnya secara automatik, menghapuskan keperluan untuk memanggil import secara eksplisit setiap kali Import modul, penggunaan khusus tidak akan diterangkan di sini

Untuk butiran, sila semak dokumen rasmi memerlukankonteks

https://webpack.docschina.org/guides/dependency-management/#requirecontext

Jadi mari kita tulis fungsi yang mengimport imej secara automatik dan menjana objek skinImage

Dengan cara ini kita mendapat objek imej tema hitam, kerana pelaksanaan require.context adalah Dalam proses penyusunan dan bukannya masa jalan, jadi semua parameter hanya boleh statik Di sini kita juga perlu mendapatkan gambar tema putih terlebih dahulu, seperti berikut

const black = require.context(&#39;../black&#39;, true, /.(png|jpg|gif)$/);
const middleImageObj = {};
black.keys().forEach(path => {
  // 获取图片的key
  const key = path.slice(2, -4); 
  blackImageObj[key] = rawSkin(path);
});
Dengan cara ini kita mendapat dua tema Objek gambar, kemudian hanya menetapkan objek tertentu pada kulitImej komponen akar, dan anda sudah selesai dan lebih ringkas daripada di atas?

Untuk lebih banyak pengetahuan berkaitan pengaturcaraan, sila lawati:
const black = require.context(&#39;../black&#39;, true, /.(png|jpg|gif)$/);
const middleImageObj = {};
black.keys().forEach(path => {
  // 获取图片的key
  const key = path.slice(2, -4); 
  blackImageObj[key] = rawSkin(path);
});
Pengenalan kepada Pengaturcaraan

! !

Atas ialah kandungan terperinci Bagaimana untuk mendapatkan sumber yang berbeza dan menukar gambar mengikut tema dalam Vue. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:juejin.cn. Jika ada pelanggaran, sila hubungi admin@php.cn Padam