vue之响应式属性和数据双向绑定
程序员文章站
2022-05-15 17:38:55
...
响应式数据的原理
-
响应式属性:能监听到修改操作,并更新视图
-
如何设置一个属性为响应式属性(属性特性)
- 值属性:拥有值的属性
- configurable => 配置属性(一个控制开关)
- enumerable => 可枚举型
- writable => 可写性
- value => 属性的值
特别说明:
1. 传统方式添加的属性,所有属性特性默认为true
2. 通过Object.defineProperty()添加的属性,所有属性特性默认为false
* 参数:参数1:目标对象 参数2:目标对象的属性 参数3:对属性的修饰(可写啊,还是设置为不可枚举等!)- 存储器属性:本身没有值,一般用于代理其他数据
- configurable
- enumerable
- get
- set
属性特性之值属性
//1:值属性
let xzl = {
uname: "xzl",
pwd: 123
}
//传统方式修改值属性
xzl.pwd = 456 // => {uname: "xzl", pwd: 456} 这里面的属性都是可写的!
//通过Object.defineProperty()方法修改值属性
//需求:设置pwd为不可写!
Object.defineProperty(xzl, "pwd", {
writable: false //在浏览器控制台之中 使用xzl.pwd=123回车 表示不能修改! {uname: "xzl", pwd: 456}
})
//需求:设置pwd不可枚举性
Object.defineProperty(xzl, "pwd", {
enumerable: false
})
for (let key in xzl) {
console.log(key + "=" + xzl[key]); //遍历发现 只有这个 uname=xzl
}
//使用普通的方式和 Object.defineProperty() 给当前对象添加属性的区别
//普通方式
xzl.age = 111 //{uname: "xzl", age: 111, pwd: 456} => 通过普通方式添加的属性 都是可遍历的,可写的 也就是说值属性是为trye
//使用 Object.defineProperty()
Object.defineProperty(xzl, "gender", {
value: "男" //{uname: "xzl", age: 111, pwd: 456, gender: "男"}
})
for (let key in xzl) {
console.log(key + "=" + xzl[key]); //遍历发现 只有这个 uname=xzl age=111 因为Object....设置的值属性为false的不可遍历等!
}
输出特性之存储器属性
<div id="box">
</div>
//2:存储器属性
// + 原理:就是在一个对象内部有着get 和 set 方法
// * get 属性()方法 =>这是获取到当前的属性, set 属性()方法 => 设置新的属性
//注意点:存储器属性作用代理,也是就说使用当前的xll作为代理,然后修改ll的性别
const xll = {
uname: "xll",
get age() {
return 11
},
set age(newVal) {
console.log("set=", newVal); //在浏览器之中 xll.age=22 => 给当前对象设置了一个age属性,输出 set= 22
}
}
const ll = {
gender: "男"
}
Object.defineProperty(xll, "gender", {
get() {
console.log("get00");
return ll.gender
},
set(newVal) {
console.log("get00");
return ll.gender = newVal;
}
})
//输入:xll.gender="女" get00 "女"
//然后在输入: ll => {gender: "女"}
//3:响应式原理
// 响应式属性的原理:把值属性变成存储器属性(getter&setter)
const user = { //作为存储器:目的用于代理,但是不修改自身的数据,不然在循环遍历这个对象的时候,造成内存的溢出现象!
uname: "xll",
age: 20
}
//通过代理user这个对象 来实现数据的修改!
const xjj = {}
box.innerText = user.uname;
for (let key in user) {
Object.defineProperty(xjj, key, {
// Object.defineProperty(user, key, {
get() {
return user[key];
},
set(newVal) {
box.innerText = newVal;
user[key] = newVal;
}
})
}
Vue实例中的响应式数据的原理
- Vue.set(vm.score, “chinese”, 100);
const initDate = {
uname: "xll",
age: 13,
score: {
eng: 61,
math: 113
}
}
const vm = new Vue({
el: "#app",
data: initDate
})
//vm.score.che=100 这边的100不是存储器属性 直接在页面显示的 ,并非像存储器属性一样,最先是隐藏的!
//因此需要使用Vue.set()方式 去设置,才能为后添加的属性设置为存储器属性!
//参数:参数1:目标对象 参数2:目标对象的属性值 参数3:目标对象的属性值
Vue.set(vm.score, "chinese", 100);
// Vue.set(vm, "chinese", 100);
//注意点:就是这个目标对象 不能设置为vm实例对象 ,也不能设置为initDate对象
//也不能设置给当前的initDate对象的chinese设置为100 也不能 `Vue.set(vm, "chinese", 100);` 否则都会报错:
//只能设置为: Vue.set(vm.score, "chinese", 100);
v-model的原理:
-
双向数据绑定—需要添加v-model指令
v-model这个指令是由两个指令组成的,分别为v-bind(绑定表单的值),@input(绑定oninput事件) -
原理:
v-bind:attr — 就是给属性绑定数据(单项),用于显示数据
v-on:input=“事件处理函数” —就是给表单添加一个事件,并且处理数据
分析:数据双向绑定就是:表单value通过属性的绑定来拿到data的数据,然后通过对表单绑定oninput事件
来实现表单值的修改的时候,从而修改了data中的数据,也就是修改了显示页面的data!
/*数据的双向绑定: v-model的原理- 01:事件绑定:对表单绑定一个事件,检测表单的值发生变化的时候,就把数据传递到控制层,进而来影响数据层!
- 02:属性绑定:就是把data的值绑定到当前的标签之中,用于显示数据
<div id="app">
<p>姓名:{{username}}</p>
<p>年龄:{{age}}</p>
<input type="text" v-bind:value="age" v-on:input="changeAge">
</div>
<script src="../vue.js"></script>
<script>
let data = {
username: "pink",
age: 20
}
const vm = new Vue({
el: "#app",
data,
methods: {
changeAge: function (e) {
//e为事件对象,target-当前目标 ---也就是当前目标的值
data.age = e.target.value;
}
}
})