Vue入门
简述
? Vue (读音 /vju?/,类似于 view) 是一套用于构建用户界面的渐进式JavaScript框架。 [5] 与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用(SPA)提供驱动。
MVVM模式的实现者
- Model:模型层,在这里表现 JavaScript 对象
- View:视图层,在这里表示 DOM(HTML操作的元素)
- ViewModel:连接驶入和数据的中间件,Vue.js 就是 MVVM 中的 ViewModel 层的实现者
- 在MVVM 架构中,是不允许数据和视图直接通信的,只能通过 ViewModel 来通信,而ViewModel 就是定义了一个Observer观察者
- ViewModel 能够观察到数据的变化,并对试图对应的内容进行更新
- ViewModel 能够监听到试图的变化,并能够通知数据发生改变
- Vue.js 就是一个MVVM的实现者,他的核心就是实现了 DOM 监听 与 数据绑定
为什么要使用Vue.js
- 轻量级,体积小是一个重要指标,它压缩之后只有20多kb(Angular压缩后56kb+,React压缩后44kb+)
- 移动优先,更适合移动端,比如移动端的Touch时间
- 易上手,学习曲线平稳,文档齐全
- 吸取了Angular(模块化)和React(虚拟DOM)的长处,并拥有自己独特的功能,如计算属性
- 开源,社区活跃度高
第一个Vue程序
? IDEA可以安装 Vue 的插件
? 注意:Vue 不支持 IE8 及以下的版本,因为 Vue 使用了 IE8 无法模拟的 ECMAScript 5 特性,但它支持所有兼容ECMAScript 5的浏览器。
下载
? 地址:https://vuejs.org/v2/guide/installation.html
? 开发版本:

CDN:
? 出于原型设计或学习目的,可以使用最新版本:
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
? 对于生产,建议链接到特定版本号并构建以避免较新版本意外损坏:
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
? 如果使用原生 ES 模块,还有一个 ES 模块兼容构建:
<script type="module">
import Vue from 'https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.esm.browser.js'
</script>
示例:
hello vue
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hello vue</title>
</head>
<body>
<div id="app">
{{message}} <br/>
</div>
</body>
</html>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el: "#app",
data:{
message : "hello vue"
}
});
</script>
动态绑定:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>动态绑定</title>
</head>
<body>
<div id="app">
{{message}} <br/>
<span v-bind:title="msg">
鼠标悬停几秒查看此处动态绑定的信息
</span>
</div>
</body>
</html>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el: "#app",
data:{
message : "hello vue",
msg: "hello world"
}
});
</script>
效果:

基本语法:
if-else if-else:
? 修改type值,展示不同内容
? 示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>if判断</title>
</head>
<body>
<div id="app">
<p v-if="type==='A'">A</p>
<p v-else-if="type==='B'">B</p>
<p v-else-if="type==='C'">C</p>
<p v-else>D</p>
</div>
</body>
</html>
<script>
var vm = new Vue({
el: "#app",
data:{
type: 'e'
}
});
</script>
for
循环打印内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>for循环</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="(item,index) in items">
{{item.msg}} -- {{index}}
</li>
</ul>
</div>
</body>
</html>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el: "#app",
data:{
items: [
{msg: "Sakura"},
{msg: "World"},
{msg: "筑梦师"}
]
}
});
</script>
绑定事件:
点击按钮弹出窗口展示msg内容
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>绑定事件</title>
</head>
<body>
<div id="app">
<button v-on:click="sayHi">Click Me</button>
</div>
</body>
</html>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el: "#app",
data:{
msg: "world"
},
methods: {
sayHi: function (event){
alert(this.msg);
}
}
});
</script>
双向数据绑定
什么是双向数据绑定
? Vue.js 是一个 MVVM 框架,即数据双向绑定,即当数据发生变化的时候,试图也就发生滨化,当视图发生变化的时候,数据也会跟着同步变化,也算是Vue.js 的精髓之处。
? 需要注意的是,我们所说的数据双向绑定,一定是对于UI控件来说的,非UI控件不会涉及到数据双向绑定,单向数据绑定是使用状态管理工具的前提,如果我们使用 vuex,那么数据流也是单项的,这是就会何双向数据绑定有冲突。
为什么要实现数据的双向绑定
? 在Vue.js 中,如果使用 vuex,实际上数据还是单向的,之所以说是数据双向绑定,这是用的UI控件来说,对于我们处理表单,Vue.js 的双向数据绑定用起来就特别舒服了,及两者并不互斥,在全局性数据流使用单项,方便跟踪;局部性数据流使用双星,简单易操作。
在表单中使用双向数据绑定
? 可以用 v-model 指令在表单 、、及 元素上创建双向数据绑定,它会根据控件类型自动选取正确的方法来更新元素,尽管有些什么,但 v-model 本质上不过是语法糖,它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
? 注意:v-model 会忽略所有表单的 value、cheked、selected特性的初始值二总是将 Vue 实例的数据作为数据来源,应该在 JavaScript 在组件的 data 选项中声明初始值。
示例:
文本双向绑定:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文本双向绑定</title>
</head>
<body>
<div id="app">
文本:<input type="text" v-model="msg" />
<br/>
<textarea rows="3" v-model="msg"></textarea>
<br/>
{{msg}}
</div>
</body>
</html>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
msg: ""
}
});
</script>
单选按钮双向绑定:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>单选按钮双向绑定</title>
</head>
<body>
<div id="app">
性别:<input type="radio" name="sex" value="男" v-model="msg"/> 男
<input type="radio" name="sex" value="女" v-model="msg" /> 女
<br/>
选择了:{{msg}}
</div>
</body>
</html>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
msg: ''
}
});
</script>
下拉框双向绑定:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>下拉框双向绑定</title>
</head>
<body>
<div id="app">
下拉框:
<select v-model="msg">
<option value="" disabled>---请选择---</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<br/>
选择了:{{msg}}
</div>
</body>
</html>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
msg: ''
}
});
</script>
Vue组件
什么是组件
? 组件时可复用的 vue 实例,说白了就是一组可以重复使用的膜拜你,跟 JSTL 的自定义标签、Thymeleaf的 th: fragment 等框架有着异曲同工之妙,通常一个应用会以一棵嵌套的组件树的形式来组织。

? 例如,你可能会有页头、侧边栏、内容区等组件,每个组件又包含了其它的像导航链接、博文之类的组件。
? 注意:在实际开发中,我们并不会用以下方式开发组件,而是采用 vue-cli 创建 .vue 模板文件的方式挨罚,以下方法只是为了让大家理解什么是组件
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>组件示例</title>
</head>
<body>
<div id="app">
<world v-for="item in items" v-bind:sak="item"></world>
</div>
</body>
</html>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
Vue.component("world",{
props: ['sak'],
template: '<li>{{sak}}</li>'
});
var vm = new Vue({
el: "#app",
data: {
items: ['Java','Linux','Vue.js']
}
});
</script>
Axios异步通信
什么是Axios
? Axios 是一个开源的可以用在浏览器端何 NodeJS 的异步通信框架,它的主要作用就是实现AJAX异步通信,其功能特点如下:
- 从浏览器中创建 XMLHttpRequests
- 从 node.js 创建 http 请求
- 支持 Promise API [JS中链式编程]
- 拦截请求何响应数据
- 转换请求数据何响应数据
- 取消请求
- 自动转换 JSON 数据
- 客户端支持防御 XSRF(跨站请求伪造)
文档:http://axios-js.com/zh-cn/docs/
? https://cn.vuejs.org/v2/cookbook/using-axios-to-consume-apis.html
为什么要使用 Axios
? 由于 Vue.js 是一个 视图层 框架 并且作者(尤雨溪)严格准守SoC(关注度分离原则),所以 Vue.js 并不包含 Ajax 的通信功能,为了解决通信问题,作者单独开发了一个名为 vue-resource 的插件,不过在进入2.0版本以后停止了对该插件的维护并推荐了 Axios 框架,少用 jQuery ,因为它的操作Dom太频繁。
第一个 Axios 应用程序
CDN:
<script src="https://cdn.jsdelivr.net/npm/axios@0.21.1/dist/axios.js"></script>
? 开发的接口大部分都是采用JSON格式,可以先在项目里模拟一段JSON数据,数据内容如下:
{
"name": "World",
"url": "https://baidu.com",
"page": 1,
"isNonProfit":true,
"address": {
"street": "含光门",
"city": "陕西西安",
"country": "中国"
},
"links": [
{
"name": "B站",
"url": "https://www.bilibili.com/"
},
{
"name": 4399,
"url": "https://www.4399.com/"
},
{
"name": "百度",
"url": "https://www.baidu.com/"
}
]
}
Vue 的生命周期
? Vue 实例有一个完整的生命周期,也就是从开始创建。初始化数据、编译模板、挂载DOM、渲染–>更新–> 渲染、卸载等一系列过程,我们称这是 Vue 的生命周期,通俗说就是 Vue 实例从创建到销毁的过程,就是生命周期。
? 在 Vue 的整个生命周期中,它提供了一系列的事件,可以让我们字事件触发时注册 JS 方法,可以让我们用自己注册的 JS 方法控制整个大局,在这些事件响应方法中的 this 直接指向的是 Vue 的实例。
 

示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Axios</title>
<style>
[v-cloak]{
display: none;
}
</style>
</head>
<body>
<div id="vue" v-cloak>
<div>{{info.name}}</div>
<div>{{info.address.country}}</div>
<a v-bind:href="info.url">百度一下</a>
</div>
</body>
</html>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios@0.21.1/dist/axios.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: "#vue",
data(){
return {
info: {
name: null,
url: null,
address: {
street: null,
city: null,
country: null
}
}
}
},
mounted(){
axios.get("../data.json").then(response=>(this.info=response.data));
}
});
</script>
data.json位置如下:

计算机属性
? 计算机属性重点突出在 属性 两个字上(属性是名词),首先它是个 属性,其次这个属性有 计算 的能力(计算是动词),这里的 计算 就是个函数;简单说,它就是一个能够将计算结果缓存起来的属性(将行为转化成了静态的属性),仅此而已,可以想象为缓存。
? 计算机属性:计算出来的结果,保存在属性中,内存中运行:虚拟Dom
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>计算机属性</title>
<!-- 导入Vue.js -->
<script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<p>currentTime1 {{currentTime1()}}</p>
<p>currentTime2 {{currentTime2}}</p>
</div>
</body>
</html>
<script>
var vm = new Vue({
el: "#app",
data: {
msg: "hello vue"
},
methods: {
currentTime1: function () {
return Date.now();
}
},
computed: {
currentTime2: function () {
return Date.now();
}
}
});
</script>
- methods:定义方法,调用方法使用currentTime1(),需要带括号
- computed:定义计算属性,调用属性使用currentTime2,不需要带括号; this.message是为了能够让currentTime2观察到数据变化而变化心
- 如何在方法中的值发生了变化,则缓存就会刷新!可以在控制台使用vm.me s sage=“qinjiang” ,改变下数据的值,再次测试观察效果!
结论:
? 调用方法时,每次都需要进行计算,既然有计算过程则必定产生系统开销,那如果这个结果是不经常变化的呢?此时就可以考虑将这个结果缓存起来,采用计算属性可以很方便的做到这一点, **计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,以节约我们的系统开销 **;
内容分发
? 在 Vue.js 中我们使用 元素作为承载分发内容的出口,作者称其为 插槽,可以应用在组合组件的场景中。
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>插槽slot</title>
</head>
<body>
<div id="app">
<todo>
<todo-title slot="todo-title" :title="title"></todo-title>
<todo-items slot="todo-items" v-for="item in todoItems" :item="item"></todo-items>
</todo>
</div>
</body>
</html>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
Vue.component("todo",{
template: '<div>' +
'<slot name="todo-title"></slot>' +
'<ul>' +
'<slot name="todo-items"></slot>' +
'</ul>' +
'</div>'
});
Vue.component("todo-title",{
props: ['title'],
template: "<div>{{title}}</div>"
});
Vue.component("todo-items",{
props: ['item'],
template: "<li>{{item}}</li>"
});
var vm = new Vue({
el: "#app",
data:{
title: "World",
todoItems: ["Java","Vue.js","MySQL"]
}
});
</script>
自定义事件
? 通过以上代码不难发现,数据项在 Vue 的实例中,但删除操作要在组件中完成,那么组件如何才能删除 Vue 实例中的数据呢? 此时就设计到参数传递与事件分发了,Vue 为我们提供了自定义事件的共呢个很好的帮助我们解决了这个问题,使用 this.$emit(‘自定义事件名’, 参数),操作过程如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定义事件</title>
</head>
<body>
<div id="app">
<todo>
<todo-title slot="todo-title" :title="title"></todo-title>
<todo-items slot="todo-items" v-for="(item,index) in todoItems"
:item="item" :index="index" v-on:remove="removeItems(index)" :key="index"></todo-items>
</todo>
</div>
</body>
</html>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
Vue.component("todo",{
template: '<div>' +
'<slot name="todo-title"></slot>' +
'<ul>' +
'<slot name="todo-items"></slot>' +
'</ul>' +
'</div>'
});
Vue.component("todo-title",{
props: ['title'],
template: "<div>{{title}}</div>"
});
Vue.component("todo-items",{
props: ['item','index'],
template: "<li>{{index}}---{{item}} <button @click='remove'>删除</button></li>",
methods: {
remove: function (index) {
this.$emit('remove',index);
}
}
});
var vm = new Vue({
el: "#app",
data:{
title: "World",
todoItems: ["Java","Vue.js","MySQL"]
},
methods: {
removeItems: function (index) {
console.log(this.todoItems[index]);
this.todoItems.splice(index,1);
}
}
});
</script>
|