本文已参与「新人创作礼」活动,一起开启掘金创作之路。
碰到的问题
1.引入开发板vue.js和引入生产板vue.min.js区别?
区别: 开发版提供便于后端开发者读明白的词条,比如 创建vue实例缺少new关键字时,开发版报错如图1,生产版报错如图2。
图1
图2
2.vue实例中的data属性配置只针对el所指定的容器使用有效,超出范围无效
3.插值语法{{}}和v-bind指令语法都可以修改值,区别是啥?
插值语法{{}}作用于标签体,指的是标签中间的值
执行语法作用于标签中的属性
4.数据代理中defineProperty()方法定义get()和set(),那么属性value和writable:true必须注释掉,不然报错
5.数据代理中defineProperty()方法就是为了实现动态给let中变量赋新值,其中必须设置属性value、enumerable:true、writable:true、configurable:true等,这样效果等价于直接在let变量中新增属性,既可增删改
let person = {
name:"张三",
sex:"男"
}
Object.defineProperty(person, "age", {
value:18,
enumerable:true, //控制属性是否可以枚举(也就是是否可以遍历访问到),默认值是false
writable:true, //控制属性是否可以被修改,默认值是false
configurable:true, //控制属性是否可以被删除,默认值是false
}
6.使用数据代理问题:为什么不在let变量中直接新增k,v,而是绕了一圈使用Object.defineProperty()方法?
答案:因为数据代理方法用Object.defineProperty()可扩展性更好。
7.如果defineProperty中只定义value属性,那么控制台赋值无效,即必须设置writable:true才能对person属性实现更新
let number = 18
let person = {
name:"张三",
sex:"男"
}
Object.defineProperty(person, "age", {
value:18,
}
8.使用路由问题:html项目使用路由报错
原因:我项目是html的去练习vue使用,所以我引入项目内的vue-router.js就无效
解决方案:
第一种:引入cdh的,不引入项目内的vue-router.js,比如
第二种:按照官网文档用npm安装一下路由
9.使用列表渲染发现问题1:更新数据时发现的一个问题
场景说明:有一个“个人信息”的列表,现在有一个按钮,点击实现只更新马冬梅信息,并实现页面响应时更新
下面介绍4种操作方式,以及可能会遇到的问题
注意点1:方式1可以实现功能,但是太复杂
注意点2:
问题:为啥整个更新{}对象无效?
答案:因为我们知道所谓的页面响应式更新(也就是上面导航知识点2.10.8),其实就是内部实现了set方法调用,从而实现页面更新DOM操作,而方式2无效,则说明,内部没有实现set方法,也就无法实现更新DOM。
注意点3:为啥使用splice()方法和就可以响应式更新DOM?因为Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新(详情请看上面导航知识点2.10.8)。
注意点4:使用Vue.set()或者vm.$set()也可以实现响应式更新DOM(详情请看上面导航知识点2.10.7)。
方式1:定义方法,只修改部分属性值,也奏效。
<div id="root">
<h2>人员列表</h2>
<button @click="updateMei">更新马冬梅的信息</button>
<ul>
<li v-for="(p,index) of persons" :key="p.id">
{{p.name}}-{{p.age}}-{{p.sex}}
</li>
</ul>
</div>
const vm = new Vue({
el:'#root',
data:{
persons:[
{id:'001',name:'马冬梅',age:30,sex:'女'},
{id:'002',name:'周冬雨',age:31,sex:'女'},
{id:'003',name:'周杰伦',age:18,sex:'男'},
{id:'004',name:'温兆伦',age:19,sex:'男'}
]
},
methods: {
updateMei(){
this.persons[0].name = '马老师' //奏效
/this.persons[0].age = 50 //奏效
/this.persons[0].sex = '男' //奏效
}
}
})
-------------------------------------------------------------------------------------------------
方式2:由于部分修改觉得太费事,所以准备整个{}进行更新,但是不奏效(不奏效指的是data数据确实更新了,但是vue没监听到数据改变)。
updateMei(){
this.persons[0] = {id:'001',name:'马老师',age:50,sex:'男'} //不奏效
}
-------------------------------------------------------------------------------------------------
方式3:由于方式2,没效果,所以采用数组内部方法实现更新,调用splice()方法。
updateMei(){
this.persons.splice(0,1,{id:'001',name:'马老师',age:50,sex:'男'}) //奏效
}
-------------------------------------------------------------------------------------------------
方式4:使用Vue.set()或者vm.$set()方法实现更新数据,也奏效
Vue.set(vm.student.hobby,0,"抽烟1")
splice使用方式如下:
10.使用列表渲染发现问题2:在数组前插入标签时显示结构发生问题
举例说明:默认存在3个标签且有值,有一个按钮效果是在最上面新增一行标签,此时会容易发生问题 点击按钮前:
点击按钮后:
结果:顺序乱了?详细原因如下图,对比相同就复用,对比不同就重新生成DOM
发生错误原因:默认数组中张三索引为0,新增一行老刘后,老刘在第一行索引变为0,而原来的第一行张三索引变为1,而虚拟DOM对比算法比较的是小标签的内容,也就是在对比下面两个图片时,由于key=0,就会把相同复用,而不同的内容(也就是“张三-18”或者“老刘-30”)会重新渲染生成DOM,这样就会导致整个页面结构混乱了。
解决方案:使用数据库中唯一标识作为:key值,比如表中唯一ID、身份证号、手机号等等
注意: 注意点1:默认不写:key时,解析DOM会自动加上数组index 注意点2::key最好绑定数据唯一标识,身份证、手机号、库表id等,这样无论在数组什么位置插入,哪怕是数组开头或者数组结尾,都不会影响结构。 注意点3:虚拟DOM存在于内存中,而用户操作的页面标签属于真实DOM
11.使用表单提交发现的问题
问题1:使用radio标签,想实现二选一?只需设置相同name属性值即可
问题2:使用checkbox标签,定义data属性值的默认值时,配置”input的value属性”和不配置”input的value属性”,效果完全不一样。
<input type="checkbox"/>
1.没有配置input的value属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)
2.配置input的value属性:
(1)v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)
(2)v-model的初始值是数组,那么收集的的就是value组成的数组
问题3:针对radio或者checked等无法输入值的标签,建议一定要配置value属性值
12.使用条件渲染发现问题
问题1:v-if可能无效
使用v-if和v-else-if和v-else时中间不可以中断,否则无效,比如:
问题2:使用