Vue
1. Vue概述
Vue(读音 /vjuː/,类似于 view)是一套用于构建用户界面的渐进式JavaScript框架。与其它框架不同的是,Vue被设计为可以自底向上逐层应用。Vue的核心库只关注视图层,方便与第三方库或既有项目整合。
-
遵循SOC原则:关注点分离原则
-
视图层:HTML+CSS+JS
-
视图:给用户看,刷新后台给的数据
-
网络通信:axios
-
页面跳转:vue-router
-
状态管理:vuex
-
Vue-UI:ICE(飞冰:https://ice.work), Element UI(https://element.eleme.cn/)
2. 第一个Vue程序
2.1 什么是MVVM
在之前的学习中,我们学过了MVC
M:模型
V:视图
C:控制器
MVVM(Model-View-ViewModel)是一种软件设计模式,由微软WPF(用于替代WinForm,以前就是用这个技术开发桌面应用程序的)和Silverlight(类似于Java Applet,简单点说就是在浏览器上运行WPF)的架构师Ken Cooper和Ted Peters开发,是一种简化用户界面的事件驱动编程方式。由John Gossman(同样也是WPF和Sliverlight的架构师)与2005年在他的博客上发表。
MVVM源自于经典的MVC(Model-View-Controller)模式。MVVM的核心是ViewModel层,负责转换Model中的数据对象来让数据变得更容易管理和使用。其作用如下:
- 该层向上与视图层进行双向数据绑定
- 向下与Model层通过接口请求进行数据交互
当下流行的MVVM框架有Vue.js,Anfular JS
通信流程:
- View 接收用户交互请求
- View 将请求转交给ViewModel
- ViewModel 操作Model数据更新
- Model 更新完数据,通知ViewModel数据发生变化
- ViewModel 更新View数据
在Vue中:
- model:对应的data中的数据
- v:模板、UI界面
- VM:Vue实例对象
2.2 为什么要送MVVC
- 低耦合:视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的View上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
- 可复用:你可以把一些视图逻辑放在一个ViewModel里面,让很多View重用这段视图逻辑。
- 独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewMode),设计人员可以专注于页面设计。
- 可测试:界面素来是比较难以测试的,而现在测试可以针对ViewModel来写。
MVVM组成部分
View层展现的不是Model
层的数据, 而是ViewModel
的数据, 由ViewModel
负责与Model
层交互, 这就完全解耦了View
层和Model
层, 这个解耦是至关重要的, 它是前后端分离方案实施的重要一环。
2.3 第一个Vue程序
哪些开发工具可以进行Vue程序的编写?
IDEA,VScode,HBuilder,Sublime,WebStorm
先用IDEA创建一个空文件,然后Settings–>Plugins 中搜索Vue 插件中下载Vue
下载地址:
- 官方网站
https://cn.vuejs.org/
- CDN
1. <script src="https://cdn.jsdelivr.net/nmp/vue@2.5.21/dist/vue.js"></script>
2. <script src="https://cdn.jsdelivr.net/nmp/vue@2.5.21/dist/vue.min.js"></script>
第一个程序
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>第一个Vue程序</title>
</head>
<body>
<div id="app">
{{message}}
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var vm = new Vue({
//元素绑定app
el: "#app",
data:{
message: "hello Vue!"
}
});
</script>
</body>
</html>
3. 基础语法指令
3.1 v-bind:绑定元素特性
简写:冒号 :
title绑定message元素使得鼠标悬停可以显示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>第一个Vue程序</title>
</head>
<body>
<div id="app">
<h1>{{message}}</h1>
<span v-bind:title="message">鼠标悬停几秒看提示信息</span>
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var vm = new Vue({
//元素绑定app
el: "#app",
data:{
message: "hello Vue!"
}
});
</script>
</body>
</html>
上面用到的v-bind等被称为指令。指令带有前缀v-,以表示他们是Vue提供的特殊特性。可能你已经猜到了,它们会在渲染的DOM上应用特殊的响应式行为。在这里,该指令的意思是:“将这个元素节点的title特性和Vue实例的message属性保持一致”。
如果再次打开浏览器的JavaScript控制台,输入vm.message = ‘XXX’,就会再一次看到这个绑定了title特性的HTML已经进行了更新。
3.2 v-if,v-else,v-else-if
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1 v-if="success">Yes</h1>
<h1 v-else>No</h1>
<h1 v-if="type==='A'">A</h1>
<h1 v-else-if="type==='B'">B</h1>
<h1 v-else>C</h1>
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
success: true,
type: 'A'
}
});
</script>
</body>
</html>
3.3 v-if 和 v-show的区别
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1 v-show="success">111</h1>
<h1 v-if="success">222</h1>
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
success: false
}
});
</script>
</body>
</html>
1.原理
v-show指令:元素始终被渲染到HTML,它只是简单的伪元素设置css的style属性,当不满足条件的元素被设置style=“display:none”的样,是通过修改元素的CSS属性(display)来决定实现显示还是隐藏
v-if指令:满足条件是会渲染到html中,不满足条件时是不会渲染到html中的,是通过操纵dom元素来进行切换显示
2.应用场景
v-if需要操作dom元素,有更高的切换消耗,v-show只是修改元素的的CSS属性有更高的初始渲染消耗,如果需要非常频繁的切换,建议使用v-show较好,如果在运行时条件很少改变,则使用v-if较好
3.4 v-for
我们可以使用 v-for
指令基于一个数组来渲染一个列表。v-for
指令的值需要使用 array in items
形式的特殊语法,其中 items
是源数据的数组,而 array
是迭代项的别名
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<li v-for="array in items">
{{array.message}}
</li>
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
items: [{message: '华清远见'},
{message: 'Java开发'},
{message: 'Vue'},
{message: 'SpringBoot'}]
}
});
</script>
</body>
</html>
在 v-for
块中可以完整地访问父作用域内的属性和变量。v-for
也支持使用可选的第二个参数表示当前项的位置索引。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<li v-for="(array,index) in items">
{{array.message}}----{{index}}
</li>
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
items: [{message: '华清远见'},
{message: 'Java开发'},
{message: 'Vue'},
{message: 'SpringBoot'}]
}
});
</script>
</body>
</html>
3.5 v-on:监听事件
缩写:@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<button v-on:click="sayHi">点击我</button>
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
message: "你好啊"
},
methods: {
//方法必须定义在Vue中的 Methods对象中
sayHi: function () {
alert(this.message);
}
}
});
</script>
</body>
</html>
4. Vue双向绑定
4.1 什么是双向绑定
- Vue.js是一个MVVM框架,即数据双向绑定,即当数据发生变化的时候,视图也就发生变化,当视图发生变化的时候,数据也会跟着同步变化。
- 值得注意的是,我们所说的数据双向绑定,一定是对于UI控件来说的,非UI控件不会涉及到数据双向绑定。
4.2 在表单中使用双向数据绑定
在前端处理表单时,我们常常需要将表单输入框的内容同步给 JavaScript 中相应的变量。手动连接值绑定和更改事件监听器可能会很麻烦,v-model 指令帮我们简化了这一步骤。
v-model还可以用于各种不同类型的输入,textarea、select 元素。
它会根据所使用的元素自动使用对应的 DOM 属性和事件组合:
- 文本类型的
<input>
和<textarea>
元素会绑定value
property 并侦听input
事件; <input type="checkbox">
和<input type="radio">
会绑定checked
property 并侦听change
事件;<select>
会绑定value
property 并侦听change
事件。
注意:v-model
会忽略任何表单元素上初始的 value
、checked
或 selected
attribute。它将始终将当前绑定的 JavaScript 状态视为数据的正确来源。你应该在 JavaScript 中使用data
选项来声明该初始值。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
输入的文本:<input type="text" v-model="message">-----------{{message}} <br>
多行文本:<textarea name="" id="" cols="30" rows="10" v-model="message"></textarea>--------{{message}} <br>
性别:
<input type="radio" name="sex" value="男" v-model="checked">男
<input type="radio" name="sex" value="女" v-model="checked">女
<p>
选中了谁:{{checked}}
</p>
下拉框:
<select v-model="alphabet">
<option value="" disabled>---请选择---</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<span>你选中了:{{alphabet}}</span>
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
message: "123",
checked: '',
alphabet: ''
}
});
</script>
</body>
</html>
5. Vue组件
5.1 什么是组件
组件是可复用的 Vue 实例,说白了就是一组可以重复使用的模板,跟JSTL的自定义标签等框架有着异曲同工之妙。通常一个应用会以一颗嵌套的组件树的形式来组成:
例如:页面会有页头、侧边栏、内容区等组件,每个组件又包含了其它像导航链接、博文之类的组件。
5.2 第一个组件
- Vue.component():注册组件
- he:自定义组件的名字
- template:组件的模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--组件:传递给组件中的值:props-->
<he v-for="array in items" v-bind:zhao="array"></he>
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
//定义一个Vue组件component
Vue.component("he",{
props: ['zhao'],
template: '<li>{{zhao}}</li>'
});
var vm = new Vue({
el: "#app",
data: {
items: ["Java","Linux","Web"]
}
});
</script>
</body>
</html>
使用props属性传递参数:
像上面那样用组件没有任何意义,所以我们是需要传递参数到组件的,此时就需要使用props属性来!
说明:
- v-for=“array in items” 遍历Vue实例中定义的名为items的数组,并创建同等数量的组件
- v-bind:zhao=“array” 将遍历的array项绑定到组件中props定义为zhao属性上;=号左边的zhao为props定义的属性名,右边的array为 array in items 中遍历的array项的值
6. Axios
6.1 什么是Axios
Axios是一个开源的key用在浏览器端和NodeJS的异步通信框架,它的主要作用就是实现AJAX异步通信,其功能特点如下:
-
从浏览器发出XMLHttpRequest
-
从node.js发出http请求
-
支持Promise API
-
拦截请求和响应
-
转换请求和响应数据
-
取消请求
-
JSON数据的自动转换
-
客户端支持防止XSRF(跨站请求伪造)
GitHub:https://github.com/axios/axios
中文文档:http://axios-js.com/
6.2 为什么要使用Axios
由于Vue.js是一个视图层框架并且作者(尤雨溪)严格遵守SOC(关注度分离原则),所以Vue.js并不包含AJAX的通信功能,为了解决通信问题,作者单独开发了一名为 vue-resource 的插件,不过在进入2.0版本后停止了对该插件的维护并推荐了Axios框架。少用jQuery,因为它操作Dom太频繁!
(先加载模板,再展示数据)
6.3 第一个Axios程序
创建data.json
{
"name": "赵赫",
"age": "24",
"address": {
"street": "光华路",
"city": "陕西西安",
"country": "中国"
},
"url": "https://www.baidu.com"
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<div>{{info.name}}</div>
<div>{{info.age}}</div>
<div>{{info.address}}</div>
<a v-bind:href="info.url">点我</a>
</div>
<!--导入js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
var vm = new Vue({
el: "#app",
data() {
return {
//请求的返回参数格式,必须和json字符串一样
info: {
name: null,
age: null,
address: {
street: null,
city: null,
country: null
},
url: null
}
}
},
mounted() {
//钩子函数 链式编程
axios.get('../data.json').then(res=>(this.info=res.data));
}
});
</script>
</body>
</html>
7. Vue生命周期
第一阶段(创建阶段):
beforeCreate:在实例初始化之后,数据观测 (Data Observer) 和 event/watcher 事件配置之前被调用。
created:在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer)、属性和方法的运算,watch/event 事件回调;然而,挂载阶段还没开始,$el 属性目前不可见。
第二阶段(挂载阶段):
beforeMount:在挂载开始之前被调用,相关的 render 函数首次被调用。
mounted:el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。
第三阶段(更新阶段):
beforeUpdate:数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。
updated:由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,所以现在可以执行依赖DOM 的操作,然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之(PS:计算属性与 watcher 会在后面的篇幅中进行介绍)。
第四阶段(销毁阶段):
beforeDestroy:实例销毁之前调用,在这一步,实例仍然完全可用。
destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1>{{message}}</h1>
<button @click="changeMsg">变变变</button>
</div>
<!--导入js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
message: 'hello world'
},
methods: {
changeMsg() {
this.message = 'goodbye world'
}
},
//生命周期函数,会自动调用
beforeCreate() {
console.log('----初始化前----')
console.log(this.message)
console.log(this.$el)
},
created() {
console.log('----初始化完成----')
console.log(this.message)
console.log(this.$el)
},
beforeMount() {
console.log('----挂载前----')
console.log(this.message)
console.log(this.$el)
},
mounted() {
console.log('----挂载完成----')
console.log(this.message)
console.log(this.$el)
},
beforeUpdate() {
console.log('----更新前---')
console.log(this.message)
console.log(this.$el)
},
updated() {
console.log('----更新完成----')
console.log(this.message)
console.log(this.$el)
}
});
</script>
</body>
</html>
8. Vue脚手架
8.1 先安裝node.js 文件
8.2 需要安裝npm镜像
我们可以把npm的镜像指定为淘宝镜像
npm confifig set registry https://registry.npm.taobao.org
同时,还可以安装一个cnpm指令来代替npm指令下载插件源文件,运行命令安装cnpm:
npm install -g cnpm --registry=https://registry.npm.taobao.org
设置cnpm的镜像:后续可以通过cnpm来代替npm的下载指令。
cnpm confifig set registry https://registry.npm.taobao.org
8.3 安装vue-cil
vue脚手架也分版本,早期的版本是2.0默认安装完nodejs自带的,现在的版本是vue-cli4版本
1:先卸载脚手架vue-cli2(如果有)输入命令:
npm uninstall vue-cli -g
2、装脚手架vue-cli3+,输入命令
npm install -g @vue/cli
安装成功之后可以通过命令查看:
注意: vue -V 这里的V是大写V
8.4 创建项目
vue create 项目名
先进入D盘,再进入项目文件夹里,然后vue create 项目名
控制键盘↑↓键,进行Vue版本的选择,按回车确定。
如果是选择Vue3快速安装或者,Vue2快速安装,直接等待就行,自动会安装成功,
如果选择自动安装:之后按回车确定
遇见选择题,选N,然后等待创建。
这就是创建完成。然后先 cd vue_study 再 npm run serve 是vue启动的命令,启动成功如下图
然后访问:http://localhost:8080,成功如下图