preface
The author previously implemented a PC personal web disk function, including breakpoint continuation, file second file management system, please refer to the article “How to Implement a lightweight Breakpoint Continuation personal Web disk System”
So the idea of personal network disk function to extend to small programs, followed before the back end (interface basically does not need to change), only need to complete the mobile UI. And since the PC is based on Vue, in order to facilitate development, I want to directly use the cross-platform framework and convert the Vue code into small programs, and in this way, I can also consider the subsequent transfer out of H5 or native mobile client.
Due to functional reasons, this mini program cannot be approved in principle, so it will only be a personal training project. In addition, the project was developed long before this article was written, so there is no guarantee that the API of the relevant framework has been updated
Cross-platform framework selection
As for the selection of cross-platform framework, three main frameworks are compared
- Mpvue is an open source front-end framework that uses vue. js to develop small applications, but it seems that no one has maintained it for a long time
- Uniapp: Uni-App is a unified front-end framework for developing applets, H5 and apps using vue. js
- Taro: An open source multi-terminal development framework for JD.com. The 2.x version requires React. The current 3.x version supports VUe2 and VUe3.
Installation and Startup
Install (Taro) scaffolding globally, and then initialize a project to install dependencies.
Use NPM Run Dev: Retry p to start the development environment, and then use wechat developer tools to import projects for preview. (It is best to apply for a mini program Id so that you can do further preview.)
Introducing the VUant-repep UI framework
You can download the generated packages of Vant-pervasive P and store them in a directory. You can then introduce custom components under the configuration of the page, and Taro will automatically synchronize these to the packaged folder. Wechat mini program will also automatically remove unused packages when packaging.
// index.config.js
export default {
usingComponents: {
"van-icon": ".. /.. /components/vant/icon/index".'van-action-sheet': '.. /.. /components/vant/action-sheet/index'.'van-notify': '.. /.. /components/vant/notify/index'.'van-dialog': '.. /.. /components/vant/dialog/index'.'van-field': '.. /.. /components/vant/field/index'."van-checkbox": ".. /.. /components/vant/checkbox/index"."van-checkbox-group": ".. /.. /components/vant/checkbox-group/index"."van-progress": ".. /.. /components/vant/progress/index"."van-toast": ".. /.. /components/vant/toast/index"}}Copy the code
Please refer to:
- Taro- Native third party components and plug-ins using applets
- “Appellate P” official documentation
In addition, some of Vant’s global components can be mounted to Vue instances for easy use.
// app.js
import Vue from 'vue'
// ...
import Notify from './components/vant/notify/notify'
import Dialog from './components/vant/dialog/dialog'
import Toast from './components/vant/toast/toast'
// ...
Vue.prototype.$notify = Notify
Vue.prototype.$dialog = Dialog
Vue.prototype.$toast = Toast
// ...
const App = new Vue({
store,
onShow (options) {
},
render (h) {
return h('block'.this.$slots.default)
}
})
export default App
Copy the code
Note that the default node is defined for the three components of Vant, and the following node code is added to a global VUE
<van-notify id="van-notify" />
<van-dialog id="van-dialog" />
<van-toast id="van-toast" />
Copy the code
It can then be used in VUE
// Notify
this.$notify({ type: 'danger'.message: e || 'Login failed'.duration: 1000 })
// Dialog
this.$dialog.confirm({
message: 'This action will move the file to the recycle bin, you can restore it within a month, after a month it will be permanently deleted',
}).then(() = > {
// do something
}).catch(() = > {
// on cancel
})
// Toast
this.$toast.loading({
mask: true.message: '上传中...'
})
Copy the code
Request to packaging
Request interception and response interception can be added for requests, based on taro.request
- Encapsulate some request headers, such as
content-type: application/json
- extract
baseURL
To extract the request prefix from the configuration for easy modification Request interceptor
: injects the sessionId into the request headerResponse interceptor
: Only the requests with errCode 200 pass. The other requests are error requests. If the Notify component is used, an error message is automatically displayed
The reference code is as follows:
// fetch.js
import Taro from '@tarojs/taro'
import Notify from '.. /components/vant/notify/notify';
const interceptor = function (chain) {
const requestParams = chain.requestParams
const sessionId = Taro.getStorageSync('sessionId')
if (sessionId) requestParams.header.sessionId = sessionId
return chain.proceed(requestParams).then(res= > {
const data = res.data
if (data.errCode === 200) {
return Promise.resolve(data.data)
} else {
Notify({
type: 'danger'.selector: '#van-notify'.message: data.errMsg,
duration: 1000,})return Promise.reject(data.errMsg)
}
}, err= > {
Notify({
type: 'danger'.selector: '#van-notify'.message: 'Server exception'.duration: 1000,})return err.toString()
})
}
Taro.addInterceptor(interceptor)
export const baseURL = 'http://localhost:5001/storage'
export const instance = (method, url, data, options) = > {
return Taro.request({
dataType: 'json'.header: {
'content-type': 'application/json'
},
method,
url: baseURL + url, data, ... options }) }Copy the code
Mount the encapsulated instance to the Vue instance as a global component for easy use.
// app.js
import Vue from 'vue'
// ...
import { instance, baseURL } from './utils/fetch'
// ...
Vue.prototype.$get = (url, data, options) = > instance('get', url, data, options)
Vue.prototype.$post = (url, data, options) = > instance('post', url, data, options)
Vue.prototype.$baseURL = baseURL
// ...
const App = new Vue({
store,
onShow (options) {
},
render (h) {
return h('block'.this.$slots.default)
}
})
export default App
Copy the code
Then use it in vue:
// get
this.$get('/getFileList', {
currentPath: this.currentPathParams
}).then(data= > {
this.fileList = data
})
//post
this.$post('/delete', {
deleteList
}).then(data= > {
this.$notify({ type: 'success'.message: 'Operation successful'.duration: 1000 })
this.$emit('onNeedRefresh')})Copy the code
About File Uploading
Wechat file upload can not get the file instance, checked a lot of information, and did not find the function of file sharding, so can not realize the resumable breakpoint. This time, simple single-file uploads were used directly, and a simpleUpload interface was added to the back end to receive them. The rest of the operations are not covered here.
Wechat does not provide direct call system file manager API (may not have permissions), this time using wechat to provide the following ways to replace
- Wx. ChooseImage: Select images from your local album or take photos with your camera
- Wx. chooseVideo: Shoot videos or select videos from your phone’s album
- Wx. chooseMessageFile: Select files from client session
Each of these interfaces returns a success callback containing the selected path to retrieve the file path for upload
Upload the logic
handleUploadFile (type = 1) {
const callback = (res) = > {
this.$emit('update:actionVisible'.false)
this.$toast.loading({
mask: true.message: '上传中...'
})
const filePaths = type === 3 ? res.tempFiles.map(item= > item.path) : res.tempFilePaths
Promise.all(
filePaths.map(item= > {
return Taro.uploadFile({
url: this.$baseURL + '/simpleUpload'.filePath: item,
name: 'file'.formData: {
targetPath: this.currentPathArr.join('/')},header: {
sessionid: Taro.getStorageSync('sessionId')
}
}).then(data= > {
try {
const res = JSON.parse(data.data)
if (res.errCode === 200) {
const { fileName } = res.data
this.$notify({ type: 'success'.message: 'Upload successful, save the file as${fileName}`.duration: 2000 })
this.$emit('onNeedRefresh')}else {
this.$notify({ type: 'success'.message: 'Upload failed,${res.errMsg}`.duration: 2000}}})catch (e) {
this.$notify({ type: 'success'.message: 'Upload failed, server error'.duration: 2000 })
}
})
})
).then(() = > {
this.$toast.clear()
})
}
if (type === 1) {
wx.chooseImage({
count: 1.sizeType: ['original'.'compressed'].sourceType: ['album'.'camera'],
success (res) {
callback(res)
}
})
} else if (type === 2) {
wx.chooseVideo({
sourceType: ['album'.'camera'].maxDuration: 60.camera: 'back',
success (res) {
callback(res)
}
})
} else if (type === 3) {
wx.chooseMessageFile({
count: 1,
success (res) {
callback(res)
}
})
}
}
Copy the code
The file preview
Because the maximum storage capacity of wechat small program files is 10M, it is almost impossible to achieve the download function. The download function has been changed to an online preview function, which currently supports the following file types
- Office documents (DOC, DOCX, XLS, XLSX, PPT, PPTX, PDF) : These documents can be passed
Taro.openDocument
The API implements preview operations - Image (JPG, PNG, SVG, GIF) : Once you have the image’s temporary address, use the float layer and
image
Component displays - Video (MP4, MOV, M4V, 3GP, AVI, M3U8) : Directly put the video address on the floating layer
video
Component display
Wx. DownloadFile is used to download files to a local temporary path and then perform corresponding preview operations. At this time, you can add a download progress bar to optimize user experience. The video will not be downloaded directly. The video resource needs to be set to accept-range at the back end, so that the video can be downloaded and played at the same time.
Progress bar uses wechat native request eventsonProgressUpdate
implementation
The main code
handleActionPreview (el) {
const target = this.actionFileInfo
const targetPath = this.currentPathArr.join('/') + '/' + target.fileName
const realPath = targetPath.replace('$Root'.this.$baseURL)
const sessionId = Taro.getStorageSync('sessionId')
if (videoSuffixArr.includes(target.suffix)) {
// Display the video directly
this.handleActionCancel()
this.mediaPreviewVisible = 2
this.videoPreviewURL = realPath + '? sessionid=' + Taro.getStorageSync('sessionId')}else if (this.previewArr.includes(target.suffix)) {
// Other types are downloaded first
this.downloadTask = wx.downloadFile({
url: realPath,
header: {
'sessionid': sessionId
},
success: (data) = > {
const { tempFilePath } = data
if (imgSuffixArr.includes(target.suffix)) {
this.mediaPreviewVisible = 1
this.imgPreviewURL = tempFilePath
} else if (documentSuffixArr.includes(target.suffix)) {
Taro.openDocument({
filePath: tempFilePath
})
}
this.handleActionCancel()
},
fail: () = > {
this.$notify({ type: 'danger'.message: Download failed.duration: 2000})}})this.downloadTask.onProgressUpdate((res) = > {
this.isDownloading = true
const { progress, totalBytesWritten, totalBytesExpectedToWrite } = res
this.downloadingInfo = { progress, totalBytesWritten, totalBytesExpectedToWrite }
})
}
}
Copy the code
PS: the Koa service is used at the back endkoa-range
The video can be downloaded and played at the same time. In Chrome, you can drag the progress bar for a video. Otherwise, you cannot drag the progress bar.
The rest of the function
The batch operation
Van-checkgroup is used to directly replace the current file list, but try to keep the node position unchanged, which can prevent interface backflow from affecting performance.
Move files
This function corresponds to the move of files on the PC. You can choose to move files only or copy them. On the PC, a tree component is used to select folders. However, it is found that Vant and others do not have relevant tree components, so they may need to encapsulate one by themselves. After the user clicks to move, the selected file information is recorded, and then the user needs to enter the corresponding directory for paste operation.
About Packaged publishing
After the NPM run build: retry p command is run, other operations are the same as those of normal mini-programs.
Other recommended articles
- Personal JS plug-in library refactoring development record
- Front-end audio visualization using G renderer
- Vite + Vue3 develop a custom browser start page website
- Mock Codepen online code compiler project development record