初识vue
# 初识Vue
Vue是一套用于构建用户界面的渐进式JavaScript框架
vue就是一个js库,并且无依赖别的js库,直接引入一个js文件就可以使用,与传统JS和JQuery (opens new window)框架不同,Vue的渐进式框架表示开发者可以由简单组件写起,渐渐搭建出一个复杂的前端平台。
形成Vue渐进式框架的核心概念为:组件化,MVVM,响应式,和生命周期。
Vue一切是数据为核心,使用数据来驱动视图刷新,我们不建议去操作dom
# 环境搭建
# 安装Vue
直接引入vue.js文件
Vue.js的官网上直接下载vue.js (opens new window),并在.html中通过script标签中引用。
<script src = ../vue.js> </script>
开发环境不要使用最小压缩版,不然会没有错误提示和警告!(页面中直接使用)
- 使用cdn的方法引入
从网络中引入对应的vue.js文件
<script src = "https://unpkg.com/vue@2.6.14/dist/vue.min.js"> </script>
- NPM方式安装(推荐)
# 最新稳定版
$ cnpm install vue
2
由于 npm 安装速度慢,建议使用了淘宝的镜像及其命令 cnpm,安装使用介绍参照:使用淘宝 NPM 镜像 (opens new window)
推荐理由:
- 方便管理依赖:通过使用npm,您可以轻松管理Vue.js的依赖,并安装其他第三方库和工具,如Babel和Webpack。等到应用需要越来越多的前端库和前端框架的时候,一个一个在HTML文件中引入会很不方便。
- 易于更新:通过使用npm,您可以方便地更新Vue.js到最新版本,以获取新的功能和改进。
- 便于组织项目结构:使用npm安装Vue.js可以帮助您组织项目结构,并使您的项目更加模块化
- 更好的开发体验:使用npm安装Vue.js可以帮助您更好地使用Vue.js的开发工具,如Vue CLI和Vue Devtools。
# Vue2使用npm安装教程
https://www.runoob.com/vue2/vue-install.html
# Vue3使用npm安装教程
https://www.runoob.com/vue3/vue3-install.html
2
3
4
# 搭建一个简单的项目
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.14">
// 引入vue文件
....
// 这就是容器
<div id="root">
<h1>{{name}}</h1>
</div>
....
<script type="text/javascript">
new Vue({
el:'#root',
data:{
name: 'Vue从0到1'
}
})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
实现vue工作的前提,创建vue实例,提供对应的容器,并把实例跟容器对应起来,让实例为容器服务
容器里的代码被成为【Vue模板】
# 进一步探究
一个实例不能接管多个容器
<div class="part">
<h1>{{name}} 111</h1>
</div>
<div class="part">
<h1>{{name}}222</h1>
</div>
<script type="text/javascript">
// 这是实例
new Vue({
el:'.part',
data:{
name: 'Vue从0到1'
}
})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
此时只有第一个容器能够被渲染。
一个容器不能被多个实例接管
<!-- 这就是容器 -->
<div id="root">
<h1>{{name}} ,{{adress}}</h1>
</div>
<script type="text/javascript">
// 这是实例
new Vue({
el:'#root',
data:{
name: 'Vue从0到1'
}
});
new Vue({
el:'#root',
data:{
adress: 'Vue 开始'
}
})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
此时,adress的值 是无法被渲染出来的,且页面报错整个为空
总结:容器跟实例之间的关系是一对一
思考:如果容器中的属性越来越多,我们vue实例中的data的属性该怎么办?也跟着加,一个实例中有一大堆属性吗?是否方便管理
'{ {xx} }'中的{{}}是什么,这样用是为了起什么作用,它有什么特性,会影响我们编程?
- 开发中只有一个vue实例,配合着组件一起使用
- 双花括号 ’{ { } }‘ 被称为插值表达式,用于将JavaScript表达式的结果动态地渲染到HTML文本中。{ {xx} } 中的xx只能是单个值 或者 单个js表达式
# 模板语法
容器中的代码被成为Vue模板
,那么模板语法也就是容器中代码的语法
Vue模板语法有2大类:
- 插值语法:
功能:解析标签体内的内容
<!-- 这就是容器 -->
<div id="root">
<!-- 写在标签中的 -->
<h1>{{name}} ,{{adress}}</h1>
</div>
2
3
4
5
- 指令语法
功能:用来解析标签(解析标签属性、内容、绑定事件等等)
<!-- 这就是容器 -->
<div id="root">
<h1>{{name}} ,{{adress}}</h1>
<a :href="name" ></a>
<a :x="name.toUpperCase()"></a>
</div>
<script type="text/javascript">
// 这是实例
new Vue({
el:'#root',
data:{
name: 'http://locahost:8086'
}
});}
})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
上面的:href,是 v-bind:href的简写形式,意思是将实例的某个值或者某个表达式赋值给标签对应的属性
关于指令,vue中还有很多,此处只是用其中一个来举例
# 数据绑定
# 单向绑定与双向绑定
前面介绍的v-bind就是“单项绑定”
单项绑定:数据只能从data流向页面。就是说你在页面中输入框改变数值的时候,对应标签的值是不会动的
只有data-->DOM
双向绑定:数据不仅能从data流向页面,还能从页面流向data。 就是说你在页面中输入框改变数值的时候,对应标签的值也会跟着一起变化。
不仅有data-->DOM,还有DOM-->data。
其中v-model就是一个双向绑定标签。
<div id="root">
<h1>{{name}} </h1>
<!-- 双向绑定 -->
<input type="text" v-model:value="name"/>
</div>
<script type="text/javascript">
// 这是实例
new Vue({
el:'#root',
data:{
name: 'Vue从0到1'
}
});
// 双向绑定;在页面中改变值时,data中的数据也会改变
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
既然双向绑定也拥有单项绑定的能力,为什么还需要单项绑定呢?
因为双向绑定对有些标签是不起作用的,比如H标签,系统会报错,v-model只能用在输入类元素上(比如input),作用只是展示信息的标签是无法使用v-model的,比如H标签,a标签等。你也可以简单的理解成只有——有value属性的标签可以使用它。
v-model的简写方式:v-model
<div id="root">
<h1>{{name}} </h1>
<!-- 双向绑定 -->
<input type="text" v-model:value="name"/>
<a v-model:value="name">qwe</a>
<!-- 简写方式 不加 :value -->
<input type="text" v-model="name"/>
</div>
2
3
4
5
6
7
8
# 各自的优缺点
单向绑定:数据流也是单向的,对于复杂应用来说是实施统一状态管理(如redux)的前提。
双向绑定:在一些需要实时
反应用户输入的场合会非常方便(如多级联动菜单)。但常认为复杂应用中这种便利比不上引入状态管理带来的优势。因为不知道状态什么时候发生改变,是谁造成的改变,数据变更也不会通知。
# 实例跟容器的绑定
在前面的例子中,容器跟实例的绑定是在创建之初就完成的,万一我在创建的时候,没想好要和谁绑定,或者说开发中途想更换绑定对象(因为之前说的一对一的绑定关系)岂不是很麻烦。
el的2种绑定写法:
<script type="text/javascript">
//第一种写法
const v =new Vue({
el:'#root',
data:{
name:'stu'
}
})
//第二种写法
const a = new Vue({
//对象式
data:{
name: 'Vue从0到1'
}
});
a.$mount('#root'); //创建实例后 再绑定
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
上面就实现了:先创建Vue实例,再通过a.$mount('标签')来绑定
扩展:
实例中data的写法:
- 对象式————直接定义一个对象
- 函数式————通过函数返回对应的值
<script type="text/javascript">
const a = new Vue({
el:'#root'
// 第一种写法 直接定义一个对象
data:{
name:'stuName'
}
//第二种方式 函数式
// data:function(){
// return{
// name: '所有的努力都不会白费的'
// }
// }
// 简写方式
data(){
return{
name: '每天学一点'
}
},
});
a.$mount('#root');
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 唯一的实例
在Vue中,每个应用程序只有一个Vue实例(或者说只有一个根实例)。因为只有这样——通过指定了唯一的 el 根元素,Vue 实例才能在内部通过 createElement 方法生成一个对应的虚拟 DOM 结构映射真实的 DOM 元素进行操作渲染成真正的 HTML。
在基本的 HTML 结构中,顶级标签是 < html >< /html >,只能有一个这样的标签存在。对应到 Vue 中也是这样,如果你给它两个顶级标签,那么对应的 DOM 结构就无法生成了。因为实例不清楚它该渲染哪一个
每个vue文件都是一个vue实例,但不是根实例,而是组件实例,< template > 标签中的内容就是 Vue 实例接管形成虚拟 DOM 的那部分内容。 根实例作为组件树的根,负责将所有组件连接起来,并提供了一些全局方法、指令、过滤器等可以在整个应用程序中使用的特性。
使用一个Vue实例来管理整个应用程序,有以下几个好处:
- 全局状态共享:在一个Vue实例中定义的数据和方法可以在所有组件中共享。这意味着一个组件的修改会自动更新到其他组件中,避免了数据同步的麻烦。
- 更高的效率:由于所有组件都共享同一个Vue实例,因此Vue可以更好地优化DOM的操作,从而提高应用程序的渲染效率。
- 更高的可维护性:使用一个Vue实例来管理整个应用程序,可以将代码分解为更小、更易于维护的组件,从而提高代码的可读性和可维护性。
# MVVM模式
概念:
MVVM分为三个部分:分别是M(Model,模型层 ),V(View,视图层),VM(ViewModel,V与M连接的桥梁,也可以看作为控制器)
- M:模型(Model):相当于Vue中data中的数据
- V:视图(View):模板代码,展示给用户的DOM页面
- VM:视图模型(ViewModel):也就是Vue实例
MVVM的核心思想:
是关注Model的V变化。让MVVM框架利用自己的机制自动更新DOM(即所说的View视图),也就是所谓的数据-视图分离。
# MVVM采用:双向数据绑定。
View中数据变化将自动反映到Model上,反之,Model中数据变化也将会自动展示在页面上。
ViewModel就是View和Model的桥梁。
ViewModel负责把Model的数据同步到View显示出来,还负责把View的修改同步回到Model。
2
3
4
5
扩展
我们(开发者)在data中定义的所有属性,最后都会出现在实例中
实例身上所有的属性,以及Vue原型上所有属性,在Vue模板中都可以直接使用
且实现了双向绑定(用到了数据代理)
# 表单收集数据
上面说了这么多,下面介绍一些在收集表单数据时需要注意的点:
- 若 input type="text" 则v-model收集的是value的值,用户输入的就是value值
- 若input type="radio" 则v-model收集的是value值,要给标签配置value值
- input 若type是 “checked”
- 没配置value,则收集的是 checked,布尔值(勾选 为true,未勾选为 false)
- 配置了value属性:但对应值若是非数组,则收集的数据仍是checked。如果初始值为数组,那收集的数据就是value组成的数组(这就是所谓的初始值会影响回收值)
备注:v-model的一些修饰符:
- V-model.trim:输入首位空格过滤
- V-model.number:输入字符转为有效数字
- V-model.lazy:失去焦点再收集数据
# 扩展
Vue 数据双向绑定原理是通过 数据劫持
+ 发布者-订阅者模式
的方式来实现的,首先是通过 ES5
提供的 Object.defineProperty()
方法来劫持(监听)各属性的 getter、setter,并在当监听的属性发生变动时通知订阅者,是否需要更新,若更新就会执行对应的更新函数。
Vue中的数据绑定原理可以分为三个步骤:模板解析、模板编译和数据监听。
首先,Vue会对模板进行解析,将其转化为一个抽象语法树(AST),然后对抽象语法树进行编译,将其转化为渲染函数(render function),渲染函数是一个返回虚拟DOM的函数,用于更新视图。
其次,在编译的过程中,Vue会对模板中的指令、表达式进行解析,将其转化为对应的render函数。同时,Vue也会通过数据劫持(Object.defineProperty或Proxy)的方式,对数据进行监听,如果数据发生变化,则会触发对应的视图更新。
最后,当数据发生变化时,Vue会先更新数据,然后通知组件进行重新渲染,重新渲染时,调用之前编译生成的渲染函数,生成一个新的虚拟DOM树,与旧的虚拟DOM树进行比较,找出差异,并将差异应用到视图上,完成视图的更新。
这就是Vue实现数据绑定的原理,通过模板解析、模板编译和数据监听三个步骤,将模板和数据进行高效的绑定,实现了视图的响应式更新。