UNI-APP 实际问题记录
最近须要将一个原来 vuejs 技术栈的 挪动端业务革新小程序,基于老本和工夫的思考,抉择了 uni-app
,一开始间接将旧代码迁入到新的工程里。在逐渐开发过程中,遇到了一些问题,整顿记录一下,当然这些问题可能只是在咱们我的项目特定场景、特定状况下呈现的,仅供参考,提供一个思路。
语法问题
- 编译后,WXML 提醒
bad attrs
在于 template 中写了个短路运算,
v-if="false && item.count > 1"
(之前次要是为了避免产品又要改回来,加了短路运算)。解决方案:删除短路运算相干代码
- v-show 判断问题
v-show 在数据表达式条件成立后,体现后果谬误。
v-show="count > 0"
, 当 count > 0 的时候,v-show 对应的 el 仍旧没有显示进去。解决方案:v-show 改为 v-if
自定义配置
- 自定义构建配置
咱们须要将小程序中用到的图片、字体构建到 cdn 服务中,而不是打包在小程序代码中,所以须要批改构建工作流。
在官网文档中,反对
vue.config.js
来配置一些 webpack 工作流。对于图片、字体等默认是会对小于 40KB 进行 base64。
因为
vue-cli
中,字体、图片等用的是url-loader
,所以为了将图片、字体构建到 cdn 种,须要在vue.config.js
中配置url-loader
,url-loader
fallback 到file-loader
。先看下残缺配置
// vue.config.js
'use strict'
const path = require('path')
const isWin = /^win/.test(process.platform)
const isProd = process.env.NODE_ENV === 'production'
const normalizePath = (path) => (isWin ? path.replace(/\\/g, '/') : path)
const extConfig = require('./src/ext.json')
function resolve(dir) {return path.join(__dirname, dir)
}
// 配置 H5 跨域
const devServer = {
target: 'your.domain.com',
// 重要
changeOrigin: true,
pathRewrite: {'^/': ''},
// 重要
secure: false,
prependPath: true,
onProxyReq: function (proxyReq, req, res) {},}
module.exports = {
// 门路别名
chainWebpack: (config) => {
/* .resolve.alias
.set('@', resolve('src'))
.set('@p', resolve('src/pages'))
.set('@c', resolve('src/components'))
.set('@a', resolve('src/assets'))
.set('@utils', resolve('src/utils'))
.end()
.extensions.add('.js')
.add('.vue')
.add('.scss')
.end()
.end() */
config.module
.rule('vue')
.test([/\.vue$/, /\.nvue$/])
.use('vue-loader')
.tap((options) =>
Object.assign({}, options, {
// 配置 小程序 image 标签的 src 也进行资源门路转换
transformAssetUrls: {image: 'src',},
}),
)
.end()
if (isProd) {
config.module
.rule('images') //.test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
.use('url-loader')
.tap((args) => {const newArgs = Object.assign({}, args, {
// 配置转换规则,-1 示意任何大小的资源都不进行 base64 转换
limit: -1,
// 这里重要,publicPath 配置给 url-loader 会不失效,必须配置到 fallback 里传递给 file-loader
fallback: {
loader: 'file-loader',
options: {publicPath(url, resourcePath, context) {
return (
extConfig.ext.publicPath +
normalizePath(path.relative(process.env.UNI_INPUT_DIR, resourcePath))
)
},
emitFile: false,
},
},
})
return newArgs
})
.end()
.end()
.rule('fonts')
.use('url-loader')
.tap((args) => {const newArgs = Object.assign({}, args, {
limit: -1,
fallback: {
loader: 'file-loader',
options: {publicPath(url, resourcePath, context) {
return (
extConfig.ext.publicPath +
normalizePath(path.relative(process.env.UNI_INPUT_DIR, resourcePath))
)
},
emitFile: false,
},
},
})
return newArgs
})
}
},
devServer: {
disableHostCheck: true,
proxy: {'/api': devServer,},
},
}
另外,uni-app 中 门路别名默认 @
指向 src
目录,如果配置了其余自定义别名,比方下面配置中的 @c
会导致编译的时候无奈正确辨认 @c
援用的资源。
性能优化相干
uni-app 会将 component
的 data
属性转化为小程序的 data
,vue 中任何批改 data 的
操作都会最终触发小程序的 setData
,家喻户晓,setData
是小程序性能优化一个重点。
- 与 template 无关的数据尽量不要放到
data
里,否则任何批改的操作都会导致setData
,从而影响性能。 -
尽量不要频繁的触发 setData
<script> data() { return {name: ['YoRoling'] } }, methods: {getName() {if (a) { // 触发 setData this.name.push('a') } if (b) { // 触发 setData this.name.push('b') } } } </script>
下面的代码,a 和 b 都会导致最终触发
setData
,而且是触发两次,对于这种简略的数据可能还好,如果是一个简单的 JSON 对象,setData 可能就会引起性能问题。应用长期变量存储数据,最初再一次性批改
data
。