1. input自定义实现v-model时,数据更新后,视图不会更新
<input type="number" class="m-answer-score-input" :value="questionList.answer[subQuestion.index]"
@input="inputChange($event, questionIndex, subQuestion)">/{{subQuestion.score}}
// ...
inputChange (e, questionNum, subQuestion) {
let subIndex = subQuestion.index
// hideSubmit定义在data里了
if (this.hideSubmit) { return false }
let answer = this.questionData[questionNum].answer || []
answer.length = this.questionData[questionNum].childrenNum
let inputValue = e.target.value
if (inputValue && !this.isValideNumber(inputValue)) {
Tips.alert('分数不在给定范围内~')
inputValue = parseInt(inputValue)
} else if (inputValue > subQuestion.score) {
// 提示不能大于总分
Tips.alert('分数不能大于小题满分')
inputValue = parseInt(subQuestion.score)
this.update = false
this.update = true
}
// 先赋值为空
e.target.value = ''
answer[subIndex] = answer[subIndex] || ''
answer[subIndex] = ''
this.questionData[questionNum]['answer'] = answer
// update要赋值,以保证不符合输入规则的值正确替换,比如4.6替换成4,大于满分时替换成满分
this.update = false
this.update = true
// 再赋值为处理过的值
setTimeout(() => {
e.target.value = inputValue
answer[subIndex] = inputValue
this.questionData[questionNum]['answer'] = answer
this.update = false
this.update = true
}, 100)
}
2. 要拿数据循环的时候,改变其某个属性上的值时,数据改变了,但是视图没有更新
解决方案:
定义一个布尔类型的变量放到页面上去,改变循环的数据的某个属性时,给该变量赋值成false,然后再设置成true
choiceAnswer (questionNum, subIndex, optionName ) {
// 超过14天后无法修改
if (this.hideSubmit) { return false }
let answer = this.questionData[questionNum].answer || []
answer.length = this.questionData[questionNum].childrenNum
answer[subIndex] = answer[subIndex] || ''
if (answer[subIndex].indexOf(optionName)>-1) {
answer[subIndex] = answer[subIndex].replace(optionName, '')
} else {
answer[subIndex] = answer[subIndex].length > 0 ? answer[subIndex].concat(optionName) : optionName
}
this.questionData[questionNum]['answer'] = answer
// 保证页面上用到数据的该属性时页面显示正常
this.update = false
this.update = true
}
3. renderjs视图层与逻辑层通信
官方文档里说了renderjs是一个运行在视图层的js。
非H5端js运行在jscore下而不是浏览器里,没有浏览器专用的js对象,比如document、xmlhttp、cookie、window、location、navigator、localstorage、websql、indexdb、webgl等对象。所以使用到renderjs去解决这些问题。
我的需求是,公式渲染后的html里有图片,点击图片可以调用uni.priviewImage方法进行预览。
但是打包成app后访问不到window, document, uni对象。
解决方案是在renderjs中监听元素点击,获取到所点击的图片的src,然后与逻辑层通信,在逻辑层调用uni.priviewImage方法(公式解析的代码没有放进来),核心代码如下:
<template>
<section class="m-wrong-topic-equipment" id="knowledgeDetail">
<div class="m-content" v-html="knowledgeData.content"></div>
</section>
</template>
<script>
export default {
data () {
return {
knowledgeData: {}
}
},
methods: {
// 省略部分代码...
// 从renderjs中接收到的数据
acceptFromRenderjs (data) {
// console.log('从renderjs中接收到的数据', data)
uni.previewImage({urls: [data]})
}
}
}
</script>
<script module="MathJax" lang="renderjs">
export default {
mounted() {
// 监听dom点击,题目内有图片可点击预览
setTimeout(() => {
let parentDom = window.document.getElementById('knowledgeDetail')
parentDom.addEventListener('click', (e) => {
if (e.target.src) {
this.messageData(e.target.src)
}
})
}, 1000)
},
methods: {
// 与逻辑层通信
messageData (data) {
this.$ownerInstance.callMethod('acceptFromRenderjs', data)
}
}
}
</script>
文档里有说明:视图层和逻辑层通讯方式与 WXS 一致,另外可以通过 this.$ownerInstance 获取当前组件的 ComponentDescriptor 实例。
4. 使用renderjs加载第三方js——实现MathJax公式解析
<template>
<view class="content" :prop="content" :change:prop="MathJax.updateMathJax">
{{content}}
<button @click="changeHandler">change</button>
</view>
</template>
<script>
export default {
data() {
return {
content: "9999"
}
},
methods: {
changeHandler () {
this.content = '$y=\\frac{1}{5}(3-2x)$'
}
}
}
</script>
<script module="MathJax" lang="renderjs">
export default {
mounted() {
if (window && window.MathJax) {
this.initMathJax()
} else {
const script = document.createElement('script')
script.src = 'https://www.stuspy.com/mathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML'
script.onload = this.initMathJax.bind(this)
document.head.appendChild(script)
}
},
methods: {
initMathJax () {
MathJax.Hub.Config({
"HTML-CSS": {
availableFonts: ["STIX-Web"],
preferredFont: "STIX-Web",
linebreaks: { automatic: false },
undefinedFamily: "STIXGeneral,'Arial Unicode MS',serif",
EqnChunk: (MathJax.Hub.Browser.isMobile ? 10 : 50),
webFont: "STIX-Web",
imageFont: "",
showMathMenu: false,
scale: 90
},
jax: ["input/TeX", "input/MathML", "output/HTML-CSS", "output/NativeMML", "output/CommonHTML"],
tex2jax: {
inlineMath: [
["$", "$"],
["\\(", "\\)"]
],
displayMath: [
["$$", "$$"],
["\\[", "\\]"]
],
processEscapes: true,
ignoreClass: "tex2jax_ignore|dno"
},
TeX: {
extensions: ["AMSmath.js", "AMSsymbols.js", "noErrors.js", "noUndefined.js"],
noUndefined: {
attributes: { mathcolor: "red", mathbackground: "#FFEEEE", mathsize: "100%" }
}
},
messageStyle: "none",
extensions: ["tex2jax.js", "mml2jax.js", "MathMenu.js", "MathZoom.js", "CHTML-preview.js"],
errorSettings: { message: ["parse..."] },
SVG: { linebreaks: { automatic: true }, width: "100% container" },
menuSettings: { CHTMLpreview: true }
})
MathJax.Hub.Queue(['Typeset', MathJax.Hub, ''])
},
updateMathJax () {
if (!MathJax) { return false }
MathJax.Hub.Queue(['Typeset', MathJax.Hub, ''])
}
}
}
</script>
<style lang="scss">
.content{font-size: 18px;margin-top: 150px;}
</style>
5. 子组件里的生命周期无法触发
只能使用create生命周期去构造了,如果不能满足的话就另想其他办法了
6. input的placeholder样式无法直接覆盖
使用placeholder-class属性设置一个类名,再用该类名写样式去覆盖掉原有的样式
<input type="text" v-model="searchName" placeholder="请输入名字"
placeholder-class="search-placeholder"/>
7. v-html渲染的图片宽度过大
使用js给img标签添加行内样式以达到目的
<view class="m-card-content" v-html="equipmentData.equipmentContentHtml"></view>
...
async onLoad (options) {
// 获取 equipmentData
let res = await this.$collectorApi.fetchEquipment(options.id)
this.equipmentData = res.result
// 获取 equipmentContentHtml里img标签添加行内样式
this.equipmentData.equipmentContentHtml= this.equipmentData.equipmentContentHtml
.replace(/\<img/gi, '<img style="max-width:100%;" ')
}
8. HbuilderX升级到2.9.0+版本后,旧的代码样式适配整体被缩小了
经过顽强的询问,搜索,才知道HBuilderX 2.9.0+ 相关更新:调整根字体大小为系统默认大小与微信小程序平台一致,调整后 rem 默认大小不再为 窗口宽度/20,改为了浏览器(webview)默认的字体大小,一般为 16px
这是社区给的解决方案: 更新 HBuilderX 2.9.0+ 后 rpx(upx)、rem 样式变形的处理办法
我做的项目主要是使用 rpx 的部分变形,使用的解决方案为 宽屏适配指南
在里面找到的解决方案如下:
在 pages.json 的 globeStyle 里配置 rpx 的如下参数
"globalStyle": {
// 省略部分代码...
"navigationStyle": "custom",
// rpx 计算特殊处理的值,始终按实际的设备宽度计算,单位 rpx,默认值为 750
"rpxCalcIncludeWidth": 750 ,
// rpx 计算所支持的最大设备宽度,单位 px,默认值为 960,我要适配的屏幕宽度为1280,
// 所以这里的值调整为1280
"rpxCalcMaxDeviceWidth": 1280
}
9. 引入vant微信小程序组件 1.10.17,运行到H5报错
引入vant
报错信息:
Module build failed (from ./node_modules/postcss-loader/src/index.js):
SyntaxError
Unclosed bracket...
解决方案:
找到wxcomponents/dist/icon/index.wxss文件,搜索url,在后两个url前增加空格

10. vue.config.js 中设置代理无效
解决方案:去manifest.json中设置,
后台请求地址形如:http://xxx.com.cn/store-front/api/user
设置代理后请求地址形如:localhost:3333/store-front/api/user
"h5" : {
"devServer" : {
"https" : false,
"disableHostCheck" : true,
"proxy" : {
// 使用代理
"/store-front" : {
"target" : "http://xxx.com.cn", // 目标地址
"changeOrigin" : true,
"secure" : false,
// 设置地址重定向
"pathRewrite" : {
"^/store-front" : "/store-front" // 设置路径重定向
}
}
}
},
...
},