MVC模式(同步通信为主):Model、View、Controller
MVP模式(异步通信为主):Model、View、Presenter
MVVM模式(异步通信为主):Model、View、ViewModel(目前主要的模式)
MVVM是一种软件架构设计模式。MVVM的核心是ViewModel层,负责转换Model层中的数据对象来让数据变得更加容易管理和使用。
该层向上与视图层进行双向数据绑定
向下与Model层通过接口请求进行数据交互
视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的View上,当View变化时,Model可以不变,当Model变化时,View可以不变。
可以把视图逻辑放在一个ViewModel里面,让很多View重用这段视图逻辑。
开发人员可以专注于业务逻辑和数据的开发,设计人员可以专注于页面设计。
界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。
Vue是一套用于构建用户界面的渐进式框架。同时被设计为可以自底向上逐层应用。Vue的核心库只关注视图层,利于上手和第三方库进行整合。
其中ViewModel是连接视图和数据的中间件。能够观察到数据的变化,并对视图对应的内容进行更新,同时也能监听到视图的变化,并能够通知数据发生改变。
因此Vue.js就是MVVM中的ViewModel层的实现者,核心是实现了DOM监听与数据绑定。
轻量级、移动优先、易上手、开源
参考官网:Vue2学习网址
在使用Vue的页面中,vue会监听数据的变化,从而自动重新渲染页面的结构。
注意:数据驱动视图是单向的数据绑定。
在填写表单时,双向数据绑定可以辅助开发者在不操作DOM前提下,自动把用户填写的内容同步到数据源中
MVVM是vue实现数据驱动视图和双向数据绑定的核心原理。
将HTML页面拆分成Model层(数据源)、ViewModel层、View层(页面效果)
表示当前页面所渲染的DOM结构
表示当前页面渲染所依赖的数据源
表示vue的实例,它是MVVM的核心,将当前页面的数据源和页面结构连接在了一起。
(1) 导入vue.js的script脚本文件
(2)在页面中声明一个将要被vue所控制的DOM区域
(3)创建vm实例对象(vue实例对象)
DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<meta name = "viewport" content = "width = device - width, initial - scale = 1.0">
<meta http-equiv = "X-UA-Compatible" content = "ie-edge">
<title>Vue2基础模板title>
head>
<body>
<div id="app">
{{username}}
div>
<script src="./lib/vue-2.6.14.js">script>
<script>
//ViewModel区域
const vm = new Vue({
//3.1 使用el属性,指定vue要控制的区域(View视图区)
el: '#app',
//3.2 数据源(Model数据源)
data:{
username: 'xg',
age: 20
},
})
script>
body>
html>
结果

(1)在Mcrosoft Edge里安装

(2)在Chrome里安装

建议使用Chrome浏览器
指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。S
v-if
v-else
DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<meta name = "viewport" content = "width = device - width, initial - scale = 1.0">
<meta http-equiv = "X-UA-Compatible" content = "ie-edge">
<title>条件渲染title>
head>
<body>
<div id="app">
<h1>1、简单的if-else判断h1>
<h2 v-if="awesome">Vue is awesomeh2>
<h2 v-else>Oh noh2>
<h1>2、连续判断h1>
<h2 v-if="type === 'A'">Ah2>
<h2 v-else-if="type === 'B'">Bh2>
<h2 v-else-if="type === 'C'">Ch2>
<h2 v-else>Not A and B and Ch2>
div>
<script src="./lib/vue-2.6.14.js">script>
<script>
//ViewModel区域
const vm = new Vue({
//3.1 使用el属性,指定vue要控制的区域(View视图区)
el: '#app',
//3.2 数据源(Model数据源)
data:{
awesome: true,
type: 'A'
},
})
script>
body>
html>
结果

v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。
v-for
DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<meta name = "viewport" content = "width = device - width, initial - scale = 1.0">
<meta http-equiv = "X-UA-Compatible" content = "ie-edge">
<title>列表渲染title>
head>
<body>
<div id="example-1">
<li v-for="item in items">
{{item.message}}
li>
div>
<script src="./lib/vue-2.6.14.js">script>
<script>
//ViewModel区域
const vm = new Vue({
//3.1 使用el属性,指定vue要控制的区域(View视图区)
el: '#example-1',
//3.2 数据源(Model数据源)
data:{
items:[
{message:'Foo'},
{message:'Bar'}
]
},
})
script>
body>
html>
结果

用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。
v-on
DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<meta name = "viewport" content = "width = device - width, initial - scale = 1.0">
<meta http-equiv = "X-UA-Compatible" content = "ie-edge">
<title>事件处理title>
head>
<body>
<div id="example-1">
<button v-on:click="greet">Greetbutton>
<button v-on:click="greet2">Greet2button>
div>
<script src="./lib/vue-2.6.14.js">script>
<script>
//ViewModel区域
const vm = new Vue({
//3.1 使用el属性,指定vue要控制的区域(View视图区)
el:"#example-1",
//3.2 数据源(Model数据源)
data:{
message:"Wow Cool"
},
methods:{
greet:function(){
alert("Hello Vue")
},
greet2:function(){
alert(this.message)
}
}
})
script>
body>
html>
结果


Axios是一个开源的可以用在浏览器端和NodeJS的异步通信框架,主要作用是实现AJAX异步通信。
由于Vue.js是一个视图层框架,并且作者为了解决通信问题,推荐了Axios框架。
{
"name":"百度",
"url":"http://www.baidu.com",
"page":66,
"isNonProfit": true,
"address":{
"street":"江夏区",
"city":"武汉市",
"country":"中国"
},
"links":[
{
"name":"Google",
"url":"http://www.google.com"
},
{
"name":"Baidu",
"url":"http://www.baidu.com"
},
{
"name":"Sougou",
"url":"http://www.sougou.com"
}
]
}
DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<meta name = "viewport" content = "width = device - width, initial - scale = 1.0">
<meta http-equiv = "X-UA-Compatible" content = "ie-edge">
<title>Axios应用程序title>
head>
<body>
<div id="app">
<div>
名称: {{info.name}}
div>
<div>
url: <a v-bind:href="info.url" target="_blank">{{info.url}}a>
div>
<ul>
<li v-for="link in info.links">
{{link.name}}--->{{link.url}}
li>
ul>
div>
<script src="./lib/vue-2.6.14.js">script>
<script src="./lib/axios.min.js">script>
<script>
//ViewModel区域
var app = new Vue({
//3.1 使用el属性,指定vue要控制的区域(View视图区)
el: '#app',
//3.2 数据源(Model数据源)
data(){
return{
info:{
name:'',
url:''
}
}
},
mounted(){
axios
.get('data.json')
.then(response => this.info=response.data)
}
})
script>
body>
html>
结果

使用时,可能会出现跨域问题,我建议使用VScode的Live Server插件,打开网址。

Vue.js是一个MVVM框架,即数据双向绑定,即当数据发生变化的时候,视图也就发生变化,当视图发生变化的时候,数据也会跟着同步变化,同时对于UI控件来说,才有双向绑定,非UI控件不会涉及到数据的双向绑定。单向数据绑定是使用状态管理工具的前提,如果使用vuex,那么数据流也是单项的,就会和双向数据绑定有冲突。
如果使用vuex,实际上数据还是单向的,数据的双向绑定是对于UI控件来说的,即两者并不冲突,在全局性数据流使用单项,方便跟踪,局部性数据流使用双向。
v-model 指令在表单 、 及 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。同时它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
注意:v-model 会忽略所有表单元素的 value、checked、selected attribute 的初始值而总是将 Vue 实例的数据作为数据来源。所以应该通过 JavaScript 在组件的 data 选项中声明初始值。
DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<meta name = "viewport" content = "width = device - width, initial - scale = 1.0">
<meta http-equiv = "X-UA-Compatible" content = "ie-edge">
<title>表单输入绑定title>
head>
<body>
<div id="app">
<input type="text" v-model="message"/>
<p>Message is : {{message}}p>
<select v-model="selected">
<option disabled value="">请选择option>
<option>Aoption>
<option>Boption>
<option>Coption>
select>
<span>Selected: {{selected}}span>
div>
<script src="./lib/vue-2.6.14.js">script>
<script>
//ViewModel区域
const vm = new Vue({
//3.1 使用el属性,指定vue要控制的区域(View视图区)
el: '#app',
//3.2 数据源(Model数据源)
data:{
message:"",
selected:''
},
})
script>
body>
html>
结果

组件是可复用的Vue实例,就是一组可以重复使用的模板,和JSTL的自定义标签、Thymeleaf的th:fragment以及Sitemesh3框架类似。通常一个应用会以一颗嵌套的组件树的形式来组织。
DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<meta name = "viewport" content = "width = device - width, initial - scale = 1.0">
<meta http-equiv = "X-UA-Compatible" content = "ie-edge">
<title>Vue组件title>
head>
<body>
<div id="app">
<ul>
<my-component-li v-for="item in items" v-bind:item="item">my-component-li>
ul>
div>
<script src="./lib/vue-2.6.14.js">script>
<script>
// 定义一个组件
Vue.component("my-component-li",{
props:["item"],
template:'- {{item}}
'
})
//ViewModel区域
const vm = new Vue({
//3.1 使用el属性,指定vue要控制的区域(View视图区)
el: '#app',
//3.2 数据源(Model数据源)
data:{
items:["汉堡","鸡肉卷","薯条"]
},
})
script>
body>
html>
结果

计算属性是用来声明式的描述一个值依赖了其它的值。当在模板里把数据绑定到一个计算属性上时,Vue会在其依赖的任何值导致该计算属性改变时更新DOM。也是将计算结果缓存起来的属性(将行为转换成了静态的属性)
DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<meta name = "viewport" content = "width = device - width, initial - scale = 1.0">
<meta http-equiv = "X-UA-Compatible" content = "ie-edge">
<title>计算属性title>
head>
<body>
<div id="app">
<p>当前时间方法:{{getCurrentTime()}}p>
<p>当前时间方法:{{getCurrentTime1}}p>
div>
<script src="./lib/vue-2.6.14.js">script>
<script>
//ViewModel区域
const vm = new Vue({
//3.1 使用el属性,指定vue要控制的区域(View视图区)
el: '#app',
//3.2 方法
methods:{
getCurrentTime:function(){
return Date.now();
}
},
//3.3 计算属性
computed:{
getCurrentTime1:function(){
return Date.now();
}
},
//3.4 数据源(Model数据源)
data:{
},
})
script>
body>
html>
结果

Vue 实现了一套内容分发的 API,这套 API 的设计灵感源自 Web Components 规范草案,将 元素作为承载分发内容的出口。
DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<meta name = "viewport" content = "width = device - width, initial - scale = 1.0">
<meta http-equiv = "X-UA-Compatible" content = "ie-edge">
<title>插槽title>
head>
<body>
<div id="app">
<todo>
<todo-title slot="todo-title" v-bind:title="title">todo-title>
<todo-items slot="todo-items" v-for="item in items" v-bind:item=item>todo-items>
todo>
div>
<script src="./lib/vue-2.6.14.js">script>
<script>
// 定义 待办事项 组件
Vue.component("todo",{
template:'
'
})
// 定义 待办事项-标题 组件
Vue.component("todo-title",{
props:['title'],
template:"{{title}}"
})
// 定义 待办事项-内容 组件
Vue.component("todo-items",{
props:['item'],
template:"- {{item}}
"
})
//ViewModel区域
const vm = new Vue({
//3.1 使用el属性,指定vue要控制的区域(View视图区)
el: '#app',
//3.2 数据源(Model数据源)
data:{
title:'美食',
items:["汉堡","鸡肉卷","薯条"]
},
})
script>
body>
html>
结果

DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<meta name = "viewport" content = "width = device - width, initial - scale = 1.0">
<meta http-equiv = "X-UA-Compatible" content = "ie-edge">
<title>自定义事件title>
head>
<body>
<div id="app">
<todo>
<todo-title slot="todo-title" v-bind:title="title">todo-title>
<todo-items slot="todo-items" v-for="(item,index) in items" v-bind:item=item v-bind:index="index" v-on:remove="removeItems">todo-items>
todo>
div>
<script src="./lib/vue-2.6.14.js">script>
<script>
// 定义 待办事项 组件
Vue.component("todo",{
template:'
'
})
// 定义 待办事项-标题 组件
Vue.component("todo-title",{
props:['title'],
template:"{{title}}"
})
// 定义 待办事项-内容 组件
Vue.component("todo-items",{
props:['item','index'],
template:"- {{index}}--{{item}}
",
methods:{
remove:function(){
this.$emit("remove")
}
}
})
//ViewModel区域
const vm = new Vue({
//3.1 使用el属性,指定vue要控制的区域(View视图区)
el: '#app',
//3.2 数据源(Model数据源)
data:{
title:'美食',
items:["汉堡","鸡肉卷","薯条"]
},
methods:{
removeItems:function(index){
this.items.splice(index,1)
}
}
})
script>
body>
html>
结果
