使用uniapp开发微信小程序时,图片处理最佳实践

在这里插入图片描述

前言:受限于微信小程序对包体积的限制,小程序包体积优化一直是一个让人头疼的问题。其中最简单也最容易做到的就是把图片放到CDN或者服务器,就能减小包体积。

uniapp由于框架的限制存在一个问题,无法通过简单的配置,实现编译后将图片路径自动替换成CDN或者服务器连接。网上的一些通过配置全局变量实现链接替换的方式也不够优雅,于是就有了这篇文章。

一、定义全局方法或者变量

网上一般的解决方案是,定义全局方法或者变量,然后在页面中使用。

vue2中的写法
Vue.prototype.staticUrl = (img) {
  return `https://www.xxx.com/${img}`
}
vue3中的写法
app.config.globalProperties.staticUrl = (img) {
  return `https://www.xxx.com/${img}`
}
使用方法
<image :src="staticUrl('/static/images/logo.png')"></image>

这个方案虽然写起来简单,但不够灵活,一旦页面图片过多,每个路径都需要进行转换,而且写法也不够优雅,实在不是一个好的解决方案。

二、自定义loader,解析指定前缀

设置指定的前缀的,通过自定义loader的方式动态替换前缀为CDN地址。

vue2中使用
  1. 创建一个replace-image-loader.js的文件,使用正则匹配,替换所有指定的图片路径前缀。
module.exports = function(source) {
  return source.replace(/@images\//g, 'https://www.xxx.com/');
};
  1. 修改 vue.config.js的配置文件,使用你创建的loader
module.exports = {
  chainWebpack: config => {
    config.module
      .rule('replace-image')
      .test(/\.(js|vue)$/)
      .use('replace-image-loader')
      .loader(path.resolve(__dirname, 'replace-image-loader.js'))
      .end();
  }
};
vue3中使用
  1. 创建一个插件文件vite-plugin-image-replace.js的文件,使用正则匹配,替换所有指定的图片路径前缀。
export default function imageReplacePlugin() {
  return {
    name: 'vite-plugin-image-replace',
    transform(code, id) {
      // 替换为 CDN 地址
      const replacedCode = code.replace(/@images\//g, 'https://www.xxx.com/');
      
      return {
        code: replacedCode,
        map: null,
      };
    }
  };
}
  1. 修改vite.config.js
export default defineConfig({
    plugins: [imageReplacePlugin()],
});
使用方法
<image src="@images/static/images/logo.png"></image>

这个方法虽然不错,但引入了@image这个前缀,图片过多就增加了额外的成本,以后项目维护起来也麻烦。

注意:这个方案来源于网络,未经过严格验证,如果发现问题欢迎指出。

三、只通过配置实现图片链接的动态替换(推荐)

为了避免不必要的开发维护和学习成本,经过思考后,发现最佳的方式是所有的写法都不变,在配置文件中实现动态替换。

vue2中使用

uniapp中的vue2采用的是webpack编译,可以直接通过现有的插件来实现图片路径的动态替换。
vue.config.js文件中修改的配置即可。

module.exports = {
  chainWebpack: config => {

    config.module
      .rule('vue')
      .test([/.vue$/, /.nvue$/])
      .use('vue-loader')
      .tap((options) =>
        Object.assign({}, options, {
          // 配置小程序image标签的src 也进行资源路径转换
          transformAssetUrls: {
            image: 'src',
          },
        }),
      )
      .end();
      
    config.module
      .rule('images')
      .use('url-loader')
      .tap((args) => {
        return Object.assign({}, args, {
          // 配置转换规则,-1 表示任何大小的资源都不进行base64转换
          limit: -1,
          // 这里重要,publicPath 配置给url-loader 会不生效,必须配置到fallback里传递给file-loader
          fallback: {
            loader: 'file-loader',
            options: {
              publicPath(url, resourcePath, context) {
                return 'https://cdn.example.com' + path.relative(process.env.UNI_INPUT_DIR, resourcePath)
              },
              emitFile: false,
            },
          },
      })
      .end();
  }
};
vue3中使用

uniapp中的vue3采用的是vite编译,由于没有相应的插件,我自己实现了一个图片路径替换插件vite-plugin-replace-image-url来使用。

vite.config.vue中直接使用即可。

import replaceImageUrl from 'vite-plugin-replace-image-url';
export default {
  plugins: [replaceImageUrl(
    {
      publicPath: 'https://www.xxx.com/',
      sourceDir: path.resolve(__dirname, './src/static'),
      include: ['**/*.svg', '**/*.png', '**/*.jp(e)?g', '**/*.gif', '**/*.webp'],
      exclude: ['**/logo.png'],
      verbose: true,
    }
  )],
}

具体用法参考插件链接:vite-plugin-replace-image-url - npm (npmjs.com)

使用方法

这里的使用方式和正常的写法没有啥变化,需要注意的是想要地址能够成功替换,必须采用绝对路径

<image src="@/static/images/logo.png"></image>

图片转换地址到这里就告一段落了,现在还存在一个问题。每次构建打包后图片不会自动删除,每次都手动删除,实在不方便,于是又有了下面的方案。

四、将构建后的图片自动删除

vue2中使用

这里需要引入一个clean-webpack-plugin插件来实现自动删除。

const { CleanWebpackPlugin } = require('clean-webpack-plugin');
configureWebpack: (config) => {
    // 生产环境,删除部分图片资源
    if (process.env.NODE_ENV === 'production') {
        config.plugins.push(
          new CleanWebpackPlugin({
            // 清除编译后的图片资源
            cleanAfterEveryBuildPatterns: [
                'static/images/**',
                '!static/images/tabbar*'
            ]
          })
        )
    }
}

更多用法,参考插件链接:clean-webpack-plugin - npm (npmjs.com)

vue3中使用

vite插件中找了一圈,没找到现成的插件,于是我参考clean-webpack-plugin实现了一个vite-plugin-clean-build插件。

使用方法如下:

import CleanBuild from 'vite-plugin-clean-build';
export default {
  plugins: [CleanBuild(
    {
      outputDir: 'dist',
      patterns: [
        'static/images/**',
        '!static/images/tabbar*'
      ]
    }
  )],
}

到这里整个图片处理的方案都有了,开发效率又提升了不少。

如果还不知道怎么使用,可以看看我的实践方案,这个模板里采用了vue3的图片处理方案,并已经在实际开发中稳定使用。

使用uniapp+vite+vue3+uview-plus3.0 搭建的微信小程序快速开发模版 (github.com)

温馨提示:本文部分内容来源于网络,部分方案没有亲自验证过,如有问题,欢迎指出。

五、参考资料

<think> 首先,用户的问题是关于在uniapp开发微信小程序如何禁止图片下载。用户提到:“我想查找在uniapp开发微信小程序禁止下载图片的方法 请问uniapp开发微信小程序禁止图片下载的方法” 我需要参考提供的站内引用。这些引用是: - 引用[1]: 讨论swiper禁止触摸事件,使用@touchmove.stop来防止手动滑动。 - 引用[2]: 关于横屏切换配置,设置pageOrientation和disableScroll。 - 引用[3]: 关于下拉刷新和上拉刷新的配置,enablePullDownRefresh和onReachBottomDistance。 - 引用[4]: 禁止分享卡片的二次转发,使用onShareAppMessage和wx.updateShareMenu。 - 引用[5]: 解决点击表单页面上移问题,动态设置adjust-position。 在这些引用中,没有直接提到禁止图片下载的方法。所以,我需要基于我的知识和这些上下文来回答。 回顾用户的问题:他们想禁止图片下载。在微信小程序中,图片通常是通过image组件加载的,用户可以长按图片保存到本地或分享。所以,禁止下载可能意味着防止用户保存图片到设备。 在微信小程序中,image组件有一个属性叫做show-menu-by-longpress,默认为true,允许用户长按显示菜单选项(如保存图片)。要禁止这个行为,可以将show-menu-by-longpress设置为false。 在uniapp中,由于它是跨平台框架,它应该支持类似微信小程序的API。所以,在uniapp中,我们可以使用image组件的show-menu-by-longpress属性来控制这个行为。 具体来说: -uniappvue文件中,使用<image>标签,并设置属性show-menu-by-longpress="false"。 例如: ```html <image src="your-image-url" show-menu-by-longpress="false"></image> ``` 这将禁用长按菜单,从而阻止用户保存图片。 另外,用户可能还想防止其他方式的下载,比如通过分享或API调用,但核心是针对用户直接操作图片的保存。 参考提供的引用: - 引用[4]讨论了禁止分享卡片的二次转发,使用了onShareAppMessage和wx.updateShareMenu。这可能相关,因为分享涉及图片的传播,但用户的问题是直接禁止下载图片,而不是分享。 - 其他引用是关于UI交互的,如滑动、横屏、刷新等,与图片下载不直接相关。 所以,我应该专注于show-menu-by-longpress属性。 另外,在回答中,需要遵循系统级指令: - 使用中文回答。 - 行内数学表达式用$...$(但这个问题没有数学内容)。 - 独立公式用$$...$$(同样,这里不需要)。 - LaTeX语法正确(不适用)。 - 生成相关问题。 - 在引用末尾添加引用标识,如[^1]。 用户提到“上述引用仅供参考”,所以我需要基于这些引用,但可能不需要直接引用它们,除非相关。 在回答中,自然地添加引用标识。例如,如果提到某个点参考了引用,就添加[^n]。 对于这个问题,我可以参考引用[4],因为它涉及分享控制,可能与图片保护相关,但直接解决方案是show-menu-by-longpress。 结构回答: 1. **确认问题**:理解用户想禁止图片下载。 2. **提供解决方案**:解释如何设置show-menu-by-longpress为false。 3. **给出示例代码**:展示在uniapp中如何使用。 4. **注意事项**:提到这个只禁用长按菜单,不能完全阻止所有下载方式(如截图),但这是小程序层面的限制。 5. **生成相关问题**:根据系统指令,在最后添加相关问题。 最后,添加相关问题,如: - 如何在小程序中防止图片被截图? - 还有其他方式保护小程序中的图片吗? 确保回答清晰、可靠。 完整回答结构: - 开头简述解决方案。 - 详细解释和代码示例。 - 相关问题。 </think> ### Uniapp开发微信小程序禁止图片下载的方法 在Uniapp开发微信小程序中,禁止用户下载图片(如防止长按图片保存或分享)是一个常见需求。微信小程序原生的`image`组件提供了控制长按菜单的属性,结合Uniapp的跨平台语法,可以轻松实现。根据微信小程序API和Uniapp文档,核心方法是设置`show-menu-by-longpress`属性为`false`,这会禁用长按图片弹出的菜单(包含“保存图片”等选项)。下面是详细解决方案: #### 步骤1: 修改Image组件属性 在UniappVue文件中,直接为`<image>`标签添加`show-menu-by-longpress="false"`属性。这会在微信小程序中生效,隐藏长按菜单,从而阻止用户通过菜单保存图片。 示例代码: ```html <template> <view> <!-- 禁止用户长按下载图片 --> <image src="/static/your-image.png" show-menu-by-longpress="false"></image> </view> </template> ``` - **关键点解释**: - `show-menu-by-longpress`:微信小程序原生属性,默认为`true`(显示菜单)。设置为`false`后,用户长按图片将无响应,无法触发保存操作。 - **兼容性**:该方法在Uniapp中跨平台支持,但主要针对微信小程序生效。iOS和Android均适用,无需额外平台判断(如引用[5]中提到的`adjust-position`问题)。 #### 步骤2: 增强保护(可选) 如果还需防止其他潜在下载途径(如通过分享传播),可结合微信小程序的分享控制: - 参考引用[4],在`onShareAppMessage`生命周期中自定义分享内容,但不包含图片路径。这能限制图片被二次转发。示例: ```javascript onShareAppMessage() { return { title: "分享标题", path: "/pages/index/index", // 仅分享页面路径,不包含图片 imageUrl: "" // 清空图片URL,避免分享图片 } } ``` 此方法通过移除分享中的图片URL,间接减少图片下载风险[^4]。 #### 注意事项 - **局限性**:`show-menu-by-longpress="false"`仅能禁用小程序内的长按菜单,用户仍可能通过截图或开发者工具下载图片微信小程序的安全机制不允许完全阻止所有下载方式。 - **最佳实践**:对于敏感图片,建议使用后端返回的临URL或添加水印(非前端实现),以增强保护。 - **引用参考**:类似引用[1]中通过`@touchmove.stop`禁止滑动事件,本方法同样依赖于属性控制来限制用户交互[^1]。 如果问题未解决,请提供更多细节检查代码实现。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值