一、Object.defineProperty()
Object.defineProperty()
静态方法会直接在一个对象上定义一个新属性,或修改其现有属性。允许精确地添加或修改对象上的属性。默认情况下,使用 Object.defineProperty()
添加的属性是不可写、不可枚举和不可配置的。
语法:Object.defineProperty(obj, prop, descriptor)
参数:
● obj
:要定义属性的对象。
● prop
:一个字符串或 Symbol,指定了要定义或修改的属性键。
● descriptor
:要定义或修改的属性描述符
const obj = {};
// 1. 使用 null 原型:没有继承的属性
const descriptor = Object.create(null);
descriptor.value = "static";
// 默认情况下,它们不可枚举、不可配置、不可写
Object.defineProperty(obj, "key", descriptor);
// 2. 使用一个包含所有属性的临时对象字面量来明确其属性
Object.defineProperty(obj, "key2", {
enumerable: false,
configurable: false,
writable: false,
value: "static",
});
对象中存在的属性描述符有两种主要类型:数据描述符
和访问器描述符
。描述符只能是这两种类型之一,不能同时为两者。
getter/setter
函数对描述的属性。数据描述符
和访问器描述符
都是对象。它们共享以下可选属性。
控制属性是否可以被删除,默认值为 false
。
控制属性是否可以枚举。默认值为false
与属性相关联的值。可以是任何有效的 JavaScript
值(数字、对象、函数等)。默认值为undefined
控制属性是否可以被修改,默认值为 false
。
用作属性 getter
的函数,如果没有 getter
则为 undefined
。当访问该属性时,将不带参地调用此函数,并将 this 设置为通过该属性访问的对象(因为可能存在继承关系,这可能不是定义该属性的对象)。返回值将被用作该属性的值。默认值为 undefined
。
用作属性 setter
的函数,如果没有 setter
则为 undefined
。当该属性被赋值时,将调用此函数,并带有一个参数(要赋给该属性的值),并将 this 设置为通过该属性分配的对象。默认值为 undefined
。
如果描述符没有 value
、writable
、get
和 set
键中的任何一个,它将被视为数据描述符
。如果描述符同时具有 [value
或 writable
] 和 [get
或 set
] 键,则会抛出异常。
这些属性不一定是描述符本身的属性。继承的属性也会被考虑在内。为了确保这些默认值得到保留,你可以预先冻结描述符对象原型链中的现有对象,明确指定所有选项,或使用 Object.create(null)
指向 null
。
let person = {
name:'Vue',
sex:'男',
// age:18
}
// 1. 数据描述符
Object.defineProperty(person,'age',{
value:20,
enumerable:true,
writable:true,
configurable:true
})
// ['name', 'sex', 'age']
console.log(Object.keys(person));
let person = {
name:'Vue',
sex:'男',
// age:18
}
// 1. 数据描述符
Object.defineProperty(person,'age',{
value:20,
enumerable:true,
writable:true,
configurable:true
})
// ['name', 'sex', 'age']
console.log(Object.keys(person));
// 2. 访问器描述符
let address = "默认地址"
Object.defineProperty(person,'address',{
get() {
return address;
},
set(value) {
address = value
}
})
console.log(person)
console.log(person.address)
person.address = "新地址"
console.log(address);
二、Vue 模板语法
Vue模板语法分为2类:插值语法、指令语法
插值语法功能:用于解析标签体内容
语法格式:{{xxx}}
双大括号形式,其中 xxx
为JavaScript
表达式 ,可以直接读取到data
中的属性。
<div id="app">
<p>{{ message }}</p>
</div>
指令是带有 v-
前缀的特殊属性。用于解析标签(包括:标签属性、标签内容、绑定事件)。
Vue
中的大部分指令,形式都是:v-xxx
形式。例如:v-bind
v-bind:href="xxx"
或 简写为 :href="xxx"
,xxx
同样要写js
表达式,且可以直接读取到Vue
实例中的data
中的所有属性。<div id="root">
<h1>{{name}}模板语法</h1>
<a v-bind:href="vueobj.url">{{vueobj.name}}的博客</a>
<a v-bind:href="vueobj.url.toUpperCase()" :code="name">{{vueobj.name}}的博客</a>
</div>
<script>
Vue.config.productionTip = false;
new Vue({
el: '#root',
data: {
name:'Vue',
vueobj :{
name:'秋堂主',
url:'https://blog.csdn.net/DUQGQG'
}
}
})
</script>
三、数据绑定
Vue
中有2种数据绑定方式:
v-bind
):数据只能从data
流向页面v-model
):数据不仅能从data
流向页面,还可以从页面流向data
。注意点
input
、select
等)v-model:value
可以简写为 v-model
,因为v-model
默认收集的就是value
值。<div id="root">
<h1>数据绑定</h1>
<h2>1. 普通写法</h2>
单向数据绑定(v-bind):<input type="text" v-bind:value="name">
双向数据绑定(v-model:value):<input type="text" v-model:value="name">
<h2>2. 简写</h2>
单向数据绑定(:):<input type="text" :value="name">
双向数据绑定(v-model):<input type="text" v-model="name">
</div>
<script>
Vue.config.productionTip = false;
new Vue({
el: '#root',
data: {
name:'Vue'
}
})
</script>
四、data与el的2种写法
new Vue
的时候配置el
属性Vue
实例,随后再通过vm.$mount('#root')
指定el
的值// 一、el的2种写法
const vm = new Vue({
// el: '#root',
data: {
name:'Vue'
}
})
// 通过$mount指定挂载的容器
vm.$mount("#root")
注意:
Vue
管理的函数,不要写箭头函数,因为箭头函数没有this
值,所以一旦写了箭头函数,this
就不再是Vue
实例了。new Vue({
el: '#root2',
/* data: {
name:'Vue'
} */
// 函数式:该函数必须返回一个对象,不能写成箭头函数
data: function () {
// 此处的this是Vue实例对象
console.log(this);
return {
name:'Vue2'
}
},
// 在对象里写函数,可以简写为
data() {
return {
name:'Vue2'
}
}
})
五、MVVM模型
每个 Vue
应用都是通过用 Vue
函数创建一个新的 Vue
实例开始的。虽然没有完全遵循 MVVM
模型,但是 Vue
的设计也受到了它的启发。因此在文档中经常会使用 vm
(ViewModel
的缩写) 这个变量名表示 Vue
实例。
MVVM模型
Model
):data
中的数据View
):模板代码ViewModel
):Vue
实例注意
data
中所有的属性,最后都出现在了vm
身上vm
身上所有的属性及Vue
原型上所有属性,在Vue
模板中都可以直接使用六、数据代理
数据代理
:通过一个对象代理另一个对象中属性的操作(读/写)
let obj = {x:10},
obj2 = {y:20};
Object.defineProperty(obj2,'x',{
get() {
return obj.x;
},
set(value) {
obj.x = value;
}
})
obj2.x = 30;
// 30
console.log(obj.x)
Vue
中的数据代理:通过vm
实例对象来代理data
对象中属性的操作(读/写),这样可以更方便的操作data
中的数据。其基本原理大概如下:
Object.defineProperty()
把data
对象中所有属性添加到vm._data
和vm
上。vm
上的属性,都指定一个getter/setter
getter/setter
内部去操作(读/写)data
中对应的属性