一、先看结论
|
需求 |
做法 |
|
从相册选图 / 拍照 |
wx.chooseMedia({ mediaType:['image'], sourceType:['album','camera'] }) |
|
从相册选视频 / 录像 |
wx.chooseMedia({ mediaType:['video'], maxDuration:60 }) |
|
拿到文件后显示 |
res.tempFiles[0].tempFilePath → setData → image/video 的 src |
|
作业扩展:预览图片 |
按钮 disabled="{{!imagePath}}" + wx.previewImage |
关键点:sourceType 里同时写 album 和 camera,点击按钮时微信才会从底部弹出"拍摄 / 从相册选择 / 取消"。只写一个,就直接进对应入口。
二、界面结构
一个 scroll-view 包一个 .box,里面五个组件,顺序是:标题 → 获取图片按钮 → 预览图片按钮(作业新增)→ image → 获取视频按钮 → video。
<scroll-view class="scrollarea" scroll-y type="list">
<view class="box">
<view class="title">照相和摄像</view>
<button type="primary" bind:tap="chooseImage">获取图片</button>
<button type="primary" bind:tap="previewImage" disabled="{{!imagePath}}">预览图片</button>
<image src="{{imagePath}}" mode="widthFix" />
<button type="primary" bind:tap="chooseVideo">获取视频</button>
<video src="{{videoPath}}" />
</view>
</scroll-view>
disabled="{{!imagePath}}" 是这次作业的全部精髓:imagePath 初始为空字符串,!'' 为 true,按钮置灰;选图成功后 imagePath 变成路径,!路径 为 false,按钮恢复可点。一行代码,不用再写 if 判断去手动改按钮状态。
三、逻辑层
两个函数调的是同一个 API,只是参数不同:
// 获取图片
chooseImage() {
wx.chooseMedia({
count: 9,
mediaType: ['image'],
sourceType: ['album', 'camera'],
success: res => {
this.setData({ imagePath: res.tempFiles[0].tempFilePath });
},
fail: err => console.log('获取图片失败' + err)
});
},
// 获取视频
chooseVideo() {
wx.chooseMedia({
mediaType: ['video'],
sourceType: ['album', 'camera'],
maxDuration: 60, // 3~60 秒,只对 camera 生效
camera: ['back', 'front'], // 只用 sourceType 含 camera 时才起作用
success: res => {
this.setData({ videoPath: res.tempFiles[0].tempFilePath });
},
fail: err => console.log('获取视频失败' + err)
});
}
预览功能:
previewImage() {
if (!this.data.imagePath) return;
wx.previewImage({
current: this.data.imagePath,
urls: [this.data.imagePath]
});
}
current 是打开预览时默认显示的那张,urls 是数组。只有一张图时写 urls: [路径] 就行;如果 chooseMedia 时 count 取了 9 张,就把整个 tempFiles 的路径拼成数组传进去,可以左右滑动切换。
四、样式上的小坑
image 组件在没图的时候默认是一片空白(或者显示一个破图占位)。课本里的做法是给 image 上底色:
image {
background-color: powderblue;
border: 2rpx solid black;
height: 400rpx;
width: 100%;
}
这样初始状态就是一块浅蓝的占位区域,和 video 组件的黑底在视觉上对称,界面不会"塌"下去。
另外 page { height: 100vh; display: flex; flex-direction: column; } 配 .scrollarea { flex: 1 },是为了让内容超出屏幕时能在 scroll-view 内部滚动,而不是整页拖动。
五、真机测试的注意事项
- 模拟器测不了"拍摄"。 开发者工具的模拟器没有真实相机,点"拍摄"只会提示不支持,必须用"预览"或"真机调试"扫码在手机上看。
- 首次调用会申请权限。 用户点拒绝,走的是 fail 回调,不会报错弹窗,所以要自己 console.log 或者给个 wx.showToast。
- 临时路径会失效。 tempFilePath 只在当前小程序生命周期内有效,重启后就没了。要留着得 wx.saveFile 存到本地,或者上传到自己的服务器。
- 导航栏。 课本截图用的是课程自带的 <navigation-bar> 组件(因为 app.json 里写了 "navigationStyle": "custom")。自己练手时不必跟着搞,直接用原生导航栏,在 window 里配 navigationBarTitleText 就行,效果一样,还少一个组件。
六、小结
这个案例本身不难,价值在于把"选媒体资源"这件事串起来了:一个 API、两种类型、两种来源、一个临时路径。真正要理解的只有两件事——sourceType 决定弹不弹选择器,tempFilePath 决定拿到的能不能直接用。
1万+



被折叠的 条评论
为什么被折叠?



