v-show 如何根据一个list是否为空控制显隐
示例代码如下:
<xxxtemp v-show="pictableData.data!=''"></xxxtemp>
<script>
export default {
data() {
return {
pictableData: {
...
data: [],
}
}
}
}
</script>
常量如何根据环境变量自动切换赋值
const debug_tools = {
xxx: xx,
xxxx: xx
}
...
const TOOLIDS = DEBUG ? debug_tools : release_tools;
如何实现table的动态数据驱动
需求是table不确定有多少列,希望可以动态适配,一般的文本表格写法很简单(element-ui):
<el-table :data="tableData">
<el-table-column v-for="(col,key) in cols" :key="key" :prop="col.prop" :label="col.label"></el-table-column>
</el-table>
<script>
export default {
data() {
return {
tableData: [{}],
cols: [{prop: 'xx', label: '列1'},...]
}
}
}
</script>
现在有个需求,cols中图片列的渲染希望用图片组件展示缩略图,当列都固定的时候自然可以直接定制:
<el-table-column prop="xxx" label="列1"></el-table-column>
...
<el-table-column prop="img" label="图片">
<template scope="scope"><img src="scope.row.url" @click="open(scope.row)"></template>
</el-table-column>
但如果图片这一列前面不确定有多少列就麻烦了,曾经尝试在template层使用v-if v-else 判定当前单元格是否是图片,然后去渲染图片标签,但发现总是提示else和if没有配对出现,导致该方案流产且渲染效率会下降很多。
另一种方法是依赖vue的rander进行动态渲染,但网上表格中用rander的示例,都是依赖iview组件中的i-table,而本项目使用的是element-ui,而后者是没有在表格中封装支持rander的,网上有人指导了如何向iview一样封装该能力,但这样的成本不如替换iview组件:https://juejin.im/post/5a2f73a3f265da432718320c
iview的用法:
cols: [..., {
prop: 'xxx',
label: 'xxxxxx',
rander: (h,params) => {
return h('img', {
domProps: {
'src': this.tableData.data[params].path,
'alt': ''
}
}
}
}]
最终思考,依然不是table的完全动态渲染,因为这种写法是从cols层写死了处理,既然怎么都不能完全动态适配,那本着最小修改的策略,用了最偷懒的一种写法:
<el-table-column v-for="(col,key) in cols.slice(0,-1)" :key="key" :prop="col.prop" :label="col.label"></el-table-column>
<el-table-column prop="img" label="图片">
<template scope="scope"><img src="scope.row.url" @click="open(scope.row)"></template>
</el-table-column>
scope和slot-scope
像上一个问题中的代码一样,一直习惯使用scope,而上面代码在编译过程中就会收到一个warning:
很明显,在vue2.5版本后,官方改了这个接口的名称(不稳定的工具就是这么随意),这里只要把scope替换成slot-scope就可以消除这个警告了。
VUE mounted 与 updated的执行顺序
最近开发vue界面遇到这样一种报错:Error in updated hook:"TypeError:undefined is not an object(evaluating 'this.$refs.child.doSomething')"
因为我们在父组件中通过cgi返回数据来动态加载不同的子组件:
<component :is="item" ... ref="child"></component>
mounted(){ cgi请求,回填data数据,判定返回结果,动态改变item组件 }
updated(){ this.$refs.child.doSomething(){} }
通过埋点日志我们发现对我们的当前使用场景,执行顺序是:mounted-》updated-》mounted-》updated,写到这里楼主已经在代码中发现问题所在了。之前楼主在mounted中进入后直接cgi请求获取数据,然后更新data数据(会触发updated)-但是item的判定也紧跟着更新数据几乎部分先后,因此执行到updated时组件已经初始化完,因此没遇到过问题。但是为了给cgi添加一个请求日期参数,楼主在cgi请求前对data中的日期字段做了取本地时间的动作,导致数据更新从而在cgi前触发了updated,cgi又返回比较慢,就导致item还没有确认要加载哪个组件,从而找不到doSomething。
优化:cgi使用的日期字段先用代码块区域内的临时变量,在cgi请求到数据成功返回后,回填cgi返回数据到data中时同步回填日期字段。理论上在数据回填前做item判定,但是目前看性能还好,暂不调整。
注:这里验证了vue生命周期图,updated在data被更新的任何时候立即执行,不管mounted是否完成。
el-dialog不居中问题
element-ui示例中的dialog弹出都是默认居中的,但在实际项目中使用时却发现向左偏了很多,未居中。仔细分析后发现,相比较例子,只是因为觉得默认弹出的dialog太宽,单独设置了width限制在了一个较小的宽度,一旦去掉这个设置就居中。
通过chrome调试css才发现是css作用域的问题,两种改法:不论哪种为了避免影响其他弹框,现在需要的弹框外添加一层<div>
1)如果样式放在<style scope>中,那么补充如下样式:
.div-dialog >>> .el-dialog {
width:500px;
}
2)如果样式放在<style>中,那么补充如下样式:
.div-dialog .el-dialog {
width:500px;
}
如何去掉VUE Router的锚点
默认情况下访问url,会发现在域名后面默认带上了 #,例如:http://xxx.xx.xxx/#/
一般场景应用没什么问题,但是如果你想在用户通过子页面url直接访问页面时(可能因为无登录态跳转登录后再回来),此时通过window.location.href来记录登录跳转前的url时,#号后面的部分都被截断了,因此这种场景目前需要去掉锚点。方法如下:
在 router-》index.js 中,添加made:'history'
el-tag绑定click事件无效问题
这里的问题是按照原来的习惯添加@click="xxx"时,发现怎么点击都无效,这个问题在官方的FAQ中已经说明:
https://github.com/ElemeFE/element/blob/dev/FAQ.md
同时可以修改下鼠标样式:http://www.w3school.com.cn/tiy/t.asp?f=csse_cursor, 比如手型cursor: pointer
vue week-range-picker实现
网上看起来靠谱的几个探索:
(1)掘金,但git仓库已删除:https://juejin.im/post/5c948acae51d4572d1055380
(2)CSDN,修改了底层源码,猥琐实现:https://blog.csdn.net/qq_39019765/article/details/103805773 ,不过代码补全,其中第几周计算的代码可以参考:https://blog.csdn.net/qq_34815027/article/details/78575261
(3)羡慕antdesign+react:https://ant.design/components/date-picker-cn/ 超简单的实现
最终,使用了两个week组件 + 自己写联动校验实现基本需求,不完美
vue el-date-picker 两个week完成周range选择能力时,第二个picker的样式异常且会影响其他pikcer
追踪样式发现,前端默认添加了系统样式
前端代码实现:
问题解决:把两个el-date-picker组件放到一个div中控制v-if,记得设置div display: inline