目录
(2)、Object.defineProperty() -数据代理
一、Vue基础
1、Vue初识
(1)、介绍
Vue是一款用于构建用户界面的渐进式 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。
- 构建用户界面:使用 vue 构建用户界面,解决了 jQuery + 模板引擎 的诸多痛点,极大的提高了前端开发的效率和体验。
编写结构:
基于vue中提供的指令,可以方便快捷的渲染页面的结构。数据驱动视图(只要页面依赖的数据源变化,则页面自动重新渲染) 指令是vue为开发者提供的模板语法,用来辅助开发者渲染页面的结构。
而以往的操作,当业务复杂时、数据变化频繁时,前端程开发者需要把大量的时间和精力浪费在DOM 的操作上,而不是核心业务的处理上。
处理交互:
基于vue中提供的事件绑定,可以轻松处理用户和页面之间的交互行为。开发者把工作的重心放在核心业务的实现上。
- 渐进式:可以从vue的使用方式上面来进行的定义:
声明式渲染 -> 组件化应用 -> 客户端路由 -> 集中式状态管理 -> 项目构建
自底向上逐层应用,随着业务功能需求复杂程度的逐渐加深,为应对逐渐复杂的功能需要,可对vue应用进行扩容( 引入各式各样的vue插件、以及复杂的vue工程化应用vuex等)。
(2)、特点
- 采用组件化模式,提高代码复用率,便于后期进行维护;
- 声明式编码(依赖于Vue指令),让前端开发者无需直接操作dom,提高开发效率;
- 使用Virtual DOM + Diff算法,尽量复用DOM节点。
Virtual DOM(虚拟DOM)。
利用在内存中生成与真实DOM与之对应的数据结构,这个在内存中生成的结构称之为虚拟DOM 。
所谓的 Virtual DOM 算法。包括几个步骤:
1.用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中;
2.当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异;
3.把步骤2所记录的差异应用到步骤1所构建的真正的DOM树上,视图就更新了。
Virtual DOM 本质上就是在 JS 和 DOM 之间做了一个缓存。可以类比 CPU 和硬盘,既然硬盘这么慢,我们就在它们之间加个缓存。
既然 DOM 这么慢,我们就在它们 JS 和 DOM 之间加个缓存。CPU(JS)只操作内存(Virtual DOM),最后的时候再把变更写入硬盘(DOM)。
(3)、创建Vue实例
- 一个Vue实例只能对应一个容器去进行使用,属于一对一的关系,通过el属性指定容器;
<body>
<!-- 准备一个容器 -->
<div id="root">
<span>hello.{{name}}</span>
</div>
</body>
<script type="text/javascript">
// 创建一个vue实例
new Vue({
el : "#root", // el用于指定当前的Vue实例为 '#root' 容器服务
// data 属性用于存储数据,提供给 '#root' 容器使用
data:{
name: "word"
}
})
</script>
1)、el的两种使用方式
- 创建Vue实例时挂载指定容器。
// 创建一个vue实例
new Vue({
el : "#root", // 挂载容器
data:{
urlName: "Vue2官网地址",
url: "https://v2.cn.vuejs.org/v2/guide/index.html",
type: "_blank",
value: "双向数据绑定"
}
})
- 通过Vue原型实例方法$mount()方法进行挂载。
// 创建一个vue实例
const vm = new Vue({
// el : "#root",
data:{
urlName: "Vue2官网地址",
url: "https://v2.cn.vuejs.org/v2/guide/index.html",
type: "_blank",
value: "双向数据绑定"
}
})
vm.$mount("#root"); // 将dom节点挂载在vue实例上
2)、data的两种使用方式
- 对象式
// 创建一个vue实例
const vm = new Vue({
el : "#root",
data:{
urlName: "Vue2官网地址",
url: "https://v2.cn.vuejs.org/v2/guide/index.html",
type: "_blank",
value: "双向数据绑定"
}
})
- 函数式
// 创建一个vue实例
const vm = new Vue({
el : "#root",
data(){
return{
urlName: "Vue2官网地址",
url: "https://v2.cn.vuejs.org/v2/guide/index.html",
type: "_blank",
value: "双向数据绑定"
}
}
})
2、模板语法
(1)、插值语法
①、文本插值 {{ value }}
<span>hello.{{mag}}</span> <!-- mag对应Vue实例中data属性的mag值 -->
②、v-once指令
<span v-once>这个将不会改变: {{ msg }}</span>
③、{{ }}中使用Js表达式
<span>hello.{{name.toUpperCase()}}</span><br> // hello.VUE
<span>{{num+1}}</span><br> // 19
<span>{{arr[1]}}</span> // 13
// 创建一个vue实例
new Vue({
el : "#root", // el用于指定当前的Vue实例为 '#root' 容器服务
// data 属性用于存储数据,提供给 '#root' 容器使用
data:{
name: "vue",
num: 18,
arr: [12,13,14]
}
})
(2)、指令语法
HTML标签的每一个属性都有自己独特的功能,但Vue认为HTML标签原生的属性不能满足实际开发需求,所以Vue为HTML标签新增很多自定义属性,每一个属性v-(指令)都可以实现一个强大的功能。
①、v-bind
v-bind指令用于绑定HTML标签标准属性的值。
语法:v-bind:href = "url",url值可为Js表达式。
<body>
<!-- 准备一个容器 -->
<div id="root">
<a v-bind:href = "url" :target="type">{{urlName}}</a>
</div>
</body>
<script type="text/javascript">
// 创建一个vue实例
new Vue({
el : "#root", // el用于指定当前的Vue实例为 '#root' 容器服务
// data 属性用于存储数据,提供给 '#root' 容器使用
data:{
urlName: "Vue2官网地址",
url: "https://v2.cn.vuejs.org/v2/guide/index.html",
type: "_blank"
}
})
</script>
②、v-model
v-model指令用于实现表单类元素的value属性值的双向数据绑定(当页面中的value发生改变,同时会影响到Vue实例中data属性中的值)。
<!-- 准备一个容器 -->
<div id="root">
输入框:<input v-model= "value">data中value的值:{{value}}
</div>
// 创建一个vue实例
new Vue({
el : "#root", // el用于指定当前的Vue实例为 '#root' 容器服务
// data 属性用于存储数据,提供给 '#root' 容器使用
data:{
value: "双向数据绑定"
}
})
Vue中的两种数据绑定的方式
- 单向绑定(v-bind):数据只能从data流向页面;
- 双向绑定(v-model):数据的流向是双向的,数据既可以从data流向页面,又可以从页面流向data。
注:
双向数据绑定一般用于在表单类元素上(如input、select等);
v-model:value 可简写为v-model。
3、MVVM
(1)、介绍
- M模型(Model):对应vue中data属性中的数据;
- V视图(View):对应vue中的模板/页面;
- VM视图对象模型(ViewModel):对应vue实例对象
- DOM Listeners(Dom监听):用于监听Dom结构中的数据;
- Data Bindings(数据绑定);将Model中的数据绑定到View中。
(2)、Object.defineProperty() -数据代理
Object.defineProperty()方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
<script type="text/javascript">
let propName = "你好";
// 创建对象
const obj = {
value: "1",
text: "one"
}
// 通过Object.defineProperty给obj对象添加属性,该方法添加的属性默认是不可枚举的
Object.defineProperty(obj, "name",{
/* 配置项
enumerable: true, // 可枚举
value: "vue", // 属性值
writable: true, // 属性值可修改
*/
// 获取属性值时执行
get(){
return propName;
},
// 设置属性值时执行--val是属性被赋予的新值
set(val){
propName = val;
}
})
</script>
配置项属性(描述符)方法说明:
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。
数据描述符是一个具有值的属性,该值可以是可写的,也可以是不可写的。
存取描述符是由 getter 函数和 setter 函数所描述的属性。一个描述符只能是这两者其中之一;不能同时是两者。
1)、数据描述符:
1、configurable:当且仅当该属性的 configurable 键值为 true 时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。 默认为 false;
2、enumerable:当且仅当该属性的 enumerable 键值为 true 时,该属性才会出现在对象的枚举属性中。 默认为 false;
3、value:该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。 默认为 undefined;
4、writable:当且仅当该属性的 writable 键值为 true 时,属性的值,也就是上面的 value,才能被赋值运算符 (en-US)改变。 默认为 false。
2)、存取描述符:
1、get:属性的 getter 函数,如果没有 getter,则为 undefined。
当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。 默认为 undefined。
2、set:属性的 setter 函数,如果没有 setter,则为 undefined。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。 默认为 undefined。