记录一些Vue使用的小细节
1、number类型的input标签
value值取到的是string类型,输入可以是数字,也可以是数字的字符串形式, 但注意返回的是string类型,必要时要注意转换。
或者利用vue修饰符将用户的输入值转为数值类型,给 v-model 添加 number 修饰符:
<input v-model.number="age" type="number">
2、v-model 还是 value/input
父组件:不要为了简写而简写,当要对数据进行进一步处理时,用第二种方式
1、 v-modle="value"
2、:styleForm="vlaue" @input="handleChange"
子组件:
export default {
model: {
prop: 'styleForm',
event: 'input',
},
props: {
styleForm: {
type: Object,
default: () => {
return {}
},
},
},
watch: {
// 监听数据变化,有变化就向上传
styleForm: {
handler() {
this.$emit('input', this.styleForm)
},
deep: true,
immediate: true,
},
},
}
3、监听按键+点击事件
<!-- Ctrl + Click 按下Ctrl + alt/shift + Click 也会执行-->
<div @click.ctrl="doSomething">测试点击事件</div>
<!-- Ctrl + Click 只有Ctrl + Click 才会执行,再多加其他按键就不执行了-->
<div @click.ctrl.exact="doSomething">测试点击事件</div>
纯粹的按键事件一般只有在input标签中才有,因为这个时候才知道焦点在哪里。
<!-- 按下Ctrl + C 时触发 -->
<input @keydown.ctrl.67="copy">
<!-- 按下Enter 时提交 -->
<input @keyup.enter="submit">
4、elementui 的样式修改
比如:一般menu的展开菜单点击是不会有变蓝效果的,但我们项目需要,然后发现展开项多了一个is-opened
的class
然后根据div层级,就有如下代码
// .el-submenu.is-opened 中间没有空格,有空格表示的是后代选择器,注意一下!不要手贱打空格
::v-deep .el-submenu.is-opened >.el-submenu__title{
color:#409EFF;
}
::v-deep .el-submenu.is-opened >.el-submenu__title i{
color:#409EFF;
}
5、当用vuex出现死循环的时候,你一定watch了非固定的对象
一般是watch了某个vuex中的state或者getter中的值,而每次返回的值也是一个新对象,这样watch将无法判断这个对象中的值是否变化,对于它来说每次都是两个新的object,所以每次都执行变化后的处理。
比如下面这个例子:
对于图片中的类型1的返回:
这种返回的是cmpList里面某个对象的属性值(这里style也是个对象),这个对象的改变可以被watch监听到,因为这个返回对象的指向一直指向style。有改变也是属性值的改变。
对于图片中的类型2的返回:
这里每次返回都是生成的新对象,所以对于watch而言,每次都是都是两个对象的比较,在js中,任意两个对象都是不相等的,即使属性值一模一样,所以这里需要我们自己处理判断:
computed:{
...mapGetters('wall/component', ['getDiffStyleConfig']),
},
watch:{
getDiffStyleConfig:{
handler(newV, oldV){
// 利用lodash的isEqual函数来判断是否内部的属性值相等
if(!_.isEqual(newV, oldV)){
// .... 检测到变化后的处理
}
},
deep:true,
immediate:true
}
}
疑惑问题:
当v-model监听的对象是对象或者数组的时候,
1、直接改对象或数组中的内容,其引用并不改变,这样其实用不用@input都没所谓,实质上改的是值,但这种操作是否符合常规操作??2、如果不改变原有的对象,那么通过watch,那么将导致死循环。因为引用一直是改变的,将视作不同的数据,即使他们的内容一模一样,相互触发watch导致死循环
6、watch 表单时,新旧值一样
因为这里watch的form对象,指向一直没有变,每次改动都是内部的值变化,所以newV和oldV一直一样。
<el-form ref="form" :model="form">
form: {
handler(newV, oldV) {
this.$emit('input', newV)
},
deep: true,
immediate: true,
},
7、vuex 中的getter - 待完善
作为state的计算属性,不管这个getter中的函数你有没有用到,只要state中的某个数据改变,那么getter中的所有跟这个数据有关的函数都将执行一遍。
8、如何实现配置化表单 - 待完善
通过配置信息来生成表单,这个主要用于动态生成表单的情况,如:同时设置两个及以上组件的共同属性。
在这里插入代码片
9、关于图片的引用
1、 普通引入
<img src="@/assets/svg/dupont_type.svg"/>
2、当src是函数或者是响应式数据时
<img :src="require(`@/assets/svg/dupont_type${index}.svg`)"/>
10、v-show 和 v-loading 冲突问题
当用v-show控制页面显示,v-show 和组件内部的v-loading 处于同一层级会导致,切换的时候,loading不显示
<div v-show="isTableShow">
<custom-comp></custom-comp> 这个组件的最外层
</div>
11、this.$emit 无效的问题
子组件进行emit , 父组件进行接收事件,如果父组件没有接收到,那么一般是在emit之前,子组件就被销毁了。
比如: 在弹窗中发emit事件,emit是在一个异步请求中的,这个时候, 关闭弹窗的事件也要放在异步请求中,否则就出现上述情况。