VUE中 给元素绑定key值作用
key的作用主要是为了更高效的渲染DOM,另外当你使用同名标签元素过渡切换时,也会用到key值,使用的目的也是为了让VUE可以区分它们,不然VUE只会替换其内容并不会触发过渡效果。
注意:尽量别用index去代替key值,因为key的主要作用是为了高效的渲染DOM,当一个页面有多个循环,这个时候如果用index做为key,index值就会存在重复,同时也违背了key高效渲染的初衷
<template>
<div>
// 1.
<span v-for="(item, index) in arr" :key="index" class="span">{{item}}</span>
//2.
<span v-for="(item, index) in arr2" :key="index" class="span">{{item}}</span>
//像这样的一种情况,一个页面出现了多个循环,这个时候如果使用index来代替key值的话
//第一个<span>标签中循环渲染出来1的index是0,而第二个<span>标签中渲染出来a的index也是0
//这种情况下就会把key值的作用降低,同时也违背了key高效渲染的初衷
</div>
</template>
export default {
data () {
return {
arr: [1,2,3]
arr2: [a,b,c]
}
},
}
VUE组件中data为什么必须是函数
在new Vue()中,data可以做为一个对象进行操作,然而在component中,data只能以函数形式存在,不能直接将对象赋值给它。
var app=new Vue({ //在new Vue中 data可以做为一个对象
el:'#app'
data:{
msg:'Holl Vue!'
}
})
data(){ //但是在Component 中只能以函数形式存在,这样写可以做到数据独立,返回数据之间互不受影响
return{
msg:'Holl Vue!'
}
}
- 当data是一个函数时,每一个实例都可以维护一份被返回对象的独立的拷贝,这样各个实例中的data不会互相影响,都是独立存在的。
VUE中 $route和 $router的区别有哪些
$route,
$route它是路由信息对象或者说是跳转的路由对象,每一个路由都会有一个route对象,route是一个局部对象,包含了路由的信息,比如:path params hash query pullpath等等路由信息参数,route主要用this. $route.params或this. $route.query来接收参数
$router
$router 它是VueRouter的实例,是一个全局路由对象,包含了跳转路由的方法,钩子函数等等,主要用 this. $router.push()来跳转页面 和router-link跳转一样
vue实现双向数据绑定的原理(mvvm实现的原理)
众所周知,在vue2.0中vue 双向数据绑定的实现是通过Object.defineporperty的setter的getter属性当数据发生改变时发送消息给订阅者触发监听,来更新数据。那在这其中都做了些什么,或者说Object.definepropoty是怎样监听到数据的改变,订阅者的作用又是什么。都实现了那些功能,这里用几行代码简单记述一下
Object.defineProperty()的作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性
Object.defineProperty(obj, prop, desc)
1.obj 需要定义属性的当前对象
2.prop 当前需要定义的属性名
3.desc 属性描述符 //通过描述符的设置可以进行更精准的控制对象属性
javacript 的三种类型的属性
命名数据属性:拥有一个确定的值的属性。这也是最常见的属性
命名访问器属性:通过getter和setter进行读取和赋值的属性
内部属性:由JavaScript引擎内部使用的属性,不能通过JavaScript代码直接访问到,不过可以通过一些方法间接的读取和设置。比如,每个对象都有一个内部属性[[Prototype]],你不能直接访问这个属性,但可以通过Object.getPrototypeOf()方法间接的读取到它的值。虽然内部属性通常用一个双吕括号包围的名称来表示,但实际上这并不是它们的名字,它们是一种抽象操作,是不可见的,根本没有上面两种属性有的那种字符串类型的属性
第三个参数 属性描述符又分为两种 数据描述符和存取描述符
1.数据描述符中特有两个属性 value 和 writable
value 代表要设置的值,writable的值是Boolean类型默认为false,表式属性的值不能改变,设置为true可以改变
let Person = {}
Object.defineProperty(Person, 'name', {
value:"xiaoming",
// writable:true 默认为false
})
Person.name = 'xiaohong'
console.log(Person.name) //打印值为xiaoming
let Person = {}
Object.defineProperty(Person, 'name', {
value:"xiaoming",
writable:true //设置为true
})
Person.name = 'xiaohong'
console.log(Person.name) //打印值为xiaohong,代表可以更改
注意: 当以下属性值被省略,会使用一下默认规则
属性值 | 默认值 |
---|---|
value | undefined |
get | undefined |
set | undefined |
writable | false |
enumerable | false |
configuralbe | false |
2.存取描述符 --是由一对geter、seter函数功能来描述的属性
get:一个给属性提供getter的方法,该方法返回值被用作属性值。
set:一个给属性提供setter的方法,该方法将接受唯一参数,并将该参数的新值分配给该属性。
let Person = {}
let str = '123'
Object.defineProperty(Person, 'name', {
get: function(){ //设置值的过程 取
console.log(2,'设置参数');
return str // 这时str的值已经改变为set函数中的val
},
set: function(val){ //获取值的过程 存
console.log(1,'接受参数',val);
str = val // 将ser 赋值接受回来的参数
},
})
Person.name = 'xiaohong'
console.log(Person.name)
//打印的结果为 1,'接受参数',val
// 2,'设置参数'
// xiaohong
数据描述符和存取描述符 都具有一下描述符
configurable 描述属性是否配置,以及可否删除
enumerable 描述属性是否会出现在for in 或者 Object.keys()的遍历中
let Person = {}
Object.defineProperty(Person, 'name', {
value : '123',
configurable:true //能否使用delete、能否需改属性特性、或能否修改访问器属性、,false为不可重新定义,默认值为true
})
delete Person.name
console.log(Person.name); //configurable值为true时可以被delete删除 打印的值为undefined
let Person = {}
Object.defineProperty(Person, 'name', {
value : '123',
configurable:false
})
delete Person.name
console.log(Person.name); //configurable值为flase时不可以被delete删除 打印的值为123
Object.defineProperty(person,'name',{
configurable:true //不可修改,将抛出错误
});
enumerable 描述属性是否会出现在for in 或者 Object.keys()的遍历中
let Person = {}
Object.defineProperty(Person, 'name', {
value: '123',
enumerable: true
})
Object.defineProperty(Person, 'eag', {
value: '456',
enumerable: true
})
const person = Person
for(let item in person){
console.log(item) // 值为name,
}