uni-app封装image组件的onLoad事件或者使用computed属性来动态修改src属性的方式实现整个项目自适应 DPR 加载图片,要求兼容小程序、H5和App三个平台。另外给定的资源图里有@2x、@3x,有的图片没有@1x图,请给出兼容有效写法
时间: 2024-03-09 19:50:35 浏览: 14
针对给定的需求和资源,可以通过以下两种方式实现整个项目的自适应DPR加载图片:
1. 封装image组件的onLoad事件
在uni-app中,我们可以通过封装image组件的onLoad事件来实现自适应DPR加载图片。具体步骤如下:
1. 在项目中创建一个名为`DpiImage`的组件,并在组件内部封装image组件的onLoad事件。例如:
```vue
<template>
<img :src="src" @load="onLoad" />
</template>
<script>
export default {
props: {
src: String,
width: String,
height: String
},
methods: {
onLoad(event) {
const { width, height } = event.target;
const dpr = window.devicePixelRatio || 1;
if (dpr === 1) {
return;
}
const src = this.src.replace(/(@2x|@3x)/, `@${dpr}x`);
if (src !== this.src) {
this.$emit('update:src', src);
}
if (this.width && this.height) {
event.target.style.width = `${this.width * dpr}px`;
event.target.style.height = `${this.height * dpr}px`;
}
}
}
};
</script>
```
在上面的代码中,我们定义了一个名为`DpiImage`的组件,并将`src`、`width`和`height`三个属性作为其props接收。在组件内部,我们通过封装image组件的onLoad事件来实现自适应DPR加载图片。具体地,我们在onLoad事件中获取图片的实际宽高和设备像素比,然后根据设备像素比修改图片的src属性。如果修改了src属性,我们将通过`$emit`方法将修改后的src属性传递给父组件。此外,如果父组件传递了`width`和`height`属性,我们还会在onLoad事件中将图片的样式属性动态修改为实际宽高的dpr倍。
2. 在需要使用自适应DPR加载图片的组件中,使用刚刚封装的`DpiImage`组件,并将需要加载的图片作为其`src`属性传递。例如:
```vue
<template>
<DpiImage :src="require('@/assets/my-image.png')" width="100" height="100" />
</template>
<script>
import DpiImage from '@/components/DpiImage';
export default {
components: {
DpiImage
}
};
</script>
```
在上面的代码中,我们使用刚刚封装的`DpiImage`组件,并将`@/assets/my-image.png`图片作为其`src`属性传递。此外,我们还传递了`width="100"`和`height="100"`两个属性,以便在图片加载完成后动态修改图片的样式属性。
3. 如果需要兼容小程序平台,我们还需要在`pages.json`文件中,将需要自适应DPR加载图片的页面的`usingComponents`属性设置为:
```json
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页",
"usingComponents": {
"DpiImage": "@/components/DpiImage"
}
}
}
```
这样,在小程序中也能够使用自适应DPR加载图片了。
2. 使用computed属性来动态修改src属性
另一种实现自适应DPR加载图片的方式是,通过computed属性来动态修改image组件的src属性。具体步骤如下:
1. 在项目中创建一个名为`DpiImage`的组件,并在组件内部定义一个名为`dpiSrc`的computed属性。例如:
```vue
<template>
<img :src="dpiSrc" :style="{ width: width + 'px', height: height + 'px' }" />
</template>
<script>
export default {
props: {
src: String,
width: Number,
height: Number
},
computed: {
dpiSrc() {
const dpr = window.devicePixelRatio || 1;
const src = this.src.replace(/(@2x|@3x)/, `@${dpr}x`);
return src;
}
}
};
</script>
```
在上面的代码中,我们定义了一个名为`DpiImage`的组件,并将`src`、`width`和`height`三个属性作为其props接收。在组件内部,我们定义了一个名为`dpiSrc`的computed属性,通过修改`this.src`属性来实现自适应DPR加载图片。如果设备像素比为1,我们不需要修改`src`属性。否则,我们将`@2x`或`@3x`替换为`@${dpr}x`,从而实现自适应DPR加载图片。
2. 在需要使用自适应DPR加载图片的组件中,使用刚刚封装的`DpiImage`组件,并将需要加载的图片作为其`src`属性传递。例如:
```vue
<template>
<DpiImage :src="require('@/assets/my-image.png')" width="100" height="100" />
</template>
<script>
import DpiImage from '@/components/DpiImage';
export default {
components: {
DpiImage
}
};
</script>
```
在上面的代码中,我们使用刚刚封装的`DpiImage`组件,并将`@/assets/my-image.png`图片作为其`src`属性传递。此外,我们还传递了`width="100"`和`height="100"`两个属性,以便在图片加载完成后动态修改图片的样式属性。
3. 如果需要兼容小程序平台,我们还需要在`pages.json`文件中,将需要自适应DPR加载图片的页面的`usingComponents`属性设置为:
```json
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页",
"usingComponents": {
"DpiImage": "@/components/DpiImage"
}
}
}
```
这样,在小程序中也能够使用自适应DPR加载图片了。
需要注意的是,在以上两种方法中,如果给定的资源图中没有@1x图,可以直接使用@2x或@3x图,因为我们在代码中都使用了正则表达式将@2x或@3x替换为@${dpr}x。