axios

功能类似于jQuery.ajax。

axios.post()

axios.get()

axios.put()

axios.patch()

axios.delete()

比jQuery.ajax功能更多

除了ajax功能之外没有其他功能(更庄专注)

ajax操作使用axios,dom操作使用vue,从此可以不使用jquery

Mock

使用axios模拟后台请求与响应就是Mock,也有专门的Moc库例如:

http://mockjs.com/

生成随机数据,拦截 Ajax 请求

使用axios和jQuery完成简单的前后台交互(请求与响应)

要求从后台获取数据,初始化书的数量。加减书的时候也发送请求与响应,同时更新后台数据。

使用axios和jQuery完成简单的前后台交互(请求与响应)

书的名称:《__name__》

书的数量:__number__

加一

减一

归零

let book = {

name:'JavaScriptBook',

number:10,

id:'1'

}

// 在response真正返回之前拦截,修改他的数据,使用这个api来模拟后台响应数据

axios.interceptors.response.use(function(response){

let {config: {url, method, data}} = response

// ES6语法,从response里的config拿出url method data,并声明

if(url === '/book/1' && method === 'get'){//如果,就把初始book的数据响应过来

response.data = book

} else if(url === '/book/1' && method === 'put'){

let dataObj = JSON.parse(data)//先把拿到的请求转化为对象

Object.assign(book,dataObj)

// Object.assign这个函数的作用是局部更新对象,把接收到的请求(book)里面的number局部更新

console.log(book)

response.data = book ;//局部更新后,再次赋值给响应,在这里略过存储数据库,因为这只是假的后台

}

return response;

})

// -------------上面是假的后台-----------------

// 先声明好变量(有时候变量不能固定,比如更新了html的代码后,这个变量就是旧的,就得重新取)

let $app = $('#app')

// let $number = $('#number')

// let $addOne = $('#addOne')

// let $minusOne = $('#minusOne')

// let $reset = $("#reset")

// 请求初始值

axios.get('/book/1')

.then(({data})=>{//获取响应成功后更新html的代码

// 这里使用的是es6语法,实际上是let data = response.data

let originalHtml = $app.html()

let newHtml = originalHtml.replace('__name__',data.name).replace('__number__', data.number)

$app.html(newHtml)

})

// 进行加一个的请求

$app.on('click', '#addOne', function(){//事件委托,点击app上的addone的时候,将点击事件委托给addone

let newNumber = $('#number').text()-0+1

let book = {

number:newNumber

}

axios.put('/book/1', book)

.then(({data})=>{

$('#number').text(data.number)//接收到响应之后在更新前端代码

})

})

//下面减一和重置同理

$app.on('click', '#minusOne', function(){//事件委托,点击app上的addone的时候,将点击事件委托给addone

let newNumber = $('#number').text()-0-1

let book = {

number:newNumber

}

axios.put('/book/1', book)

.then(({data})=>{

$('#number').text(data.number)//接收到响应之后在更新前端代码

})

})

$app.on('click', '#reset', function(){//事件委托,点击app上的addone的时候,将点击事件委托给addone

let newNumber = 0

let book = {

number:newNumber

}

axios.put('/book/1', book)

.then(({data})=>{

$('#number').text(data.number)//接收到响应之后在更新前端代码

})

})

事件委托:点击父元素,如果同时点到了子元素就把事件委托给他。

通过事件委托,监听app的点击事件,如果点的是委托的子元素,就执行监听的函数

上面的代码很乱。

使用 MVC模式 改写上面的代码

上面的代码很乱。使用MVC模式重构代码,把代码分成视图,数据,控制数据和视图三块,分别用一个对象表示,下面是过程

添加model,分离控制数据的方法

fakeData()

// -------------上面是假的后台-----------------

let model = {

data:{

name:'',

number:0,

id:''

},

fetch:function (id){

return axios.get(`/book/${id}`).then((response)=>{

this.data = response.data

return response

})

},

update:function(id,data){

return axios.put(`/book/${id}`,data).then((response)=>{

this.data = response.data

return response

})

}

}

let $app = $('#app')

model.fetch(1).then(({data})=>{//这里把操作数据的方法写在了model里

let originalHtml = $app.html()

let newHtml = originalHtml.replace('__name__',data.name).replace('__number__', data.number)

$app.html(newHtml)

})

$app.on('click', '#addOne', function(){

let newNumber = $('#number').text()-0+1

let book = {

number:newNumber

}

model.update(1,book).then(({data})=>{//这里把操作数据的方法写在了model里

$('#number').text(data.number)

})

})

$app.on('click', '#minusOne', function(){

let newNumber = $('#number').text()-0-1

let book = {

number:newNumber

}

model.update(1,book)

.then(({data})=>{

$('#number').text(data.number)

})

})

$app.on('click', '#reset', function(){

let newNumber = 0

let book = {

number:newNumber

}

model.update(1,book)

.then(({data})=>{

$('#number').text(data.number)

})

})

function fakeData(){//假的后台

let book = {

name:'JavaScriptBook',

number:10,

id:'1'

}

// 在response真正返回之前拦截,修改他的数据,使用这个api来模拟后台响应数据

axios.interceptors.response.use(function(response){

let {config: {url, method, data}} = response

// ES6语法,从response里的config拿出url method data,并声明

if(url === '/book/1' && method === 'get'){

response.data = book

} else if(url === '/book/1' && method === 'put'){

let dataObj = JSON.parse(data)

Object.assign(book,dataObj)

console.log(book)

response.data = book ;

}

return response;

})

}

添加View,所有跟html相关的操作都给view来做

使用axios和jQuery完成简单的前后台交互(请求与响应)

fakeData()

// -------------上面是假的后台-----------------

let model = {

data:{

name:'',

number:0,

id:''

},

fetch:function (id){

return axios.get(`/book/${id}`).then((response)=>{

this.data = response.data

return response

})

},

update:function(id,data){

return axios.put(`/book/${id}`,data).then((response)=>{

this.data = response.data

return response

})

}

}

let view = {

el:'#app',

template:`

书的名称:《__name__》

书的数量:__number__

加一

减一

归零

`,

render(data){//渲染

let newhtml = this.template.replace('__name__',data.name).replace('__number__', data.number)

$(this.el).html(newhtml)

}

}

let $app = $('#app')

model.fetch(1).then(({data})=>{//es6语法,response里的data

//这里把操作数据的方法写在了model里

view.render(data)

// 或者view.render(model.data)因为上面model在操纵数据的时候,获取响应的时候,把data传给了model.data,所以response.data 和model.data一样,两个都可以用

})

$app.on('click', '#addOne', function(){

let newNumber = $('#number').text()-0+1

let book = {

number:newNumber

}

model.update(1,book).

then(({data})=>{//这里把操作数据的方法写在了model里

view.render(data)

})

})

$app.on('click', '#minusOne', function(){

let newNumber = $('#number').text()-0-1

let book = {

number:newNumber

}

model.update(1,book)

.then(({data})=>{

view.render(data)

})

})

$app.on('click', '#reset', function(){

let newNumber = 0

let book = {

number:newNumber

}

model.update(1,book)

.then(({data})=>{

view.render(data)

})

})

//假的后台,不要看

function fakeData(){//假的后台

let book = {

name:'JavaScriptBook',

number:10,

id:'1'

}

// 在response真正返回之前拦截,修改他的数据,使用这个api来模拟后台响应数据

axios.interceptors.response.use(function(response){

let {config: {url, method, data}} = response

// ES6语法,从response里的config拿出url method data,并声明

if(url === '/book/1' && method === 'get'){

response.data = book

} else if(url === '/book/1' && method === 'put'){

let dataObj = JSON.parse(data)

Object.assign(book,dataObj)

console.log(book)

response.data = book ;

}

return response;

})

}

代码开始变得条理清晰

添加Controller (操纵Model和View)

把操纵model和view的操作封装成controller 对象

演示地址:

https://jsbin.com/sezuquxuko/...

fakeData()

// -------------上面是假的后台-----------------

let model = {

data:{

name:'',

number:0,

id:''

},

fetch:function (id){

return axios.get(`/book/${id}`).then((response)=>{

this.data = response.data

return response

})

},

update:function(id,data){

return axios.put(`/book/${id}`,data).then((response)=>{

this.data = response.data

return response

})

}

}

let view = {

el:'#app',

template:`

书的名称:《__name__》

书的数量:__number__

加一

减一

归零

`,

render(data){//渲染

let newhtml = this.template.replace('__name__',data.name).replace('__number__', data.number)

$(this.el).html(newhtml)

}

}

let controller = {

init:function(options){

this.view = options.view

this.model = options.model

this.view.render(this.model.data)

this.bindEvents()

this.model.fetch(1).then(({data})=>{

this.view.render(data)

})

},

bindEvents:function(){

//到这一层,this还指的是controller这个对象,但是到点击事件那一层,addOne函数里,this代表点击的那个元素(jQuery规定的)。

// 所以要使用addOne.bind(this)把controller这一层的this绑定到addOne那更深入的一层去,使this同一为controller这个对象

$(this.view.el).on('click', '#addOne', this.addOne.bind(this))

$(this.view.el).on('click', '#minusOne',this.minusOne.bind(this) )

$(this.view.el).on('click', '#reset', this.reset.bind(this))

},

addOne:function(){

let newNumber = $('#number').text()-0+1

let book = {number:newNumber}

this.model.update(1,book).//这个this已经被bind为controller

then(({data})=>{

this.view.render(data)//这个this已经被bind为controller

})

},

minusOne:function(){

let newNumber = $('#number').text()-0-1

let book = {

number:newNumber

}

this.model.update(1,book)//这个this已经被bind为controller

.then(({data})=>{

this.view.render(data)

})

},

reset:function(){

let newNumber = 0

let book = {

number:newNumber

}

this.model.update(1,book)

.then(({data})=>{

this.view.render(data)

})

}

}

controller.init({model:model,view:view})//初始化,并把Model和View传进去

//假的后台,不要看

function fakeData(){//假的后台

let book = {

name:'JavaScriptBook',

number:10,

id:'1'

}

// 在response真正返回之前拦截,修改他的数据,使用这个api来模拟后台响应数据

axios.interceptors.response.use(function(response){

let {config: {url, method, data}} = response

// ES6语法,从response里的config拿出url method data,并声明

if(url === '/book/1' && method === 'get'){

response.data = book

} else if(url === '/book/1' && method === 'put'){

let dataObj = JSON.parse(data)

Object.assign(book,dataObj)

console.log(book)

response.data = book ;

}

return response;

})

}

把Model和View抽象成类

因为这个页面的Model和View只是这个页面特有的,假如下个页面不是这个View和Model,那么还需要重新重写一遍代码,所以要把把Model,View和controller抽象成类。这样每有新的页面中的一块html需要操作,就new一个对象即可。一般来说MVC做成一个库,然后去引用他就好了

先写构造函数,然后把公有属性写在prototype里,最后new就可以了。

演示地址:

https://jsbin.com/mifameqona/...

controller类暂时不写

fakeData()

// -------------上面是假的后台-----------------

//从这开始写MVC类

function Model(options){//这里面写特有的属性

this.data = options.data

this.resource = options.resource//把请求的地址也写成特有的属性

}

Model.prototype.fetch = function(id){//共有属性

return axios.get(`/${this.resource}/${id}`).then((response)=>{

this.data = response.data

return response

})

}

Model.prototype.update = function(id,data){

return axios.put(`/${this.resource}/${id}`,data).then((response)=>{

this.data = response.data

return response

})

}

function View(options){

this.el = options.el;

this.template = options.template;

}

View.prototype.render = function(data){

var newhtml = this.template

for(let key in data){

newhtml = newhtml.replace(`__${key}__`,data[key])//用循环替换data里面的字符串

}

$(this.el).html(newhtml)

}

// --------上面是MVC类-----------

//使用MVC类新生成的对象

let bookModel = new Model({data:{name:'',number:0,id:''},resource:'book'})

let bookView = new View({

el:'#app',

template:`

书的名称:《__name__》

书的数量:__number__

加一

减一

归零

`

})

let controller = {

init:function(options){

this.view = options.view

this.model = options.model

this.view.render(this.model.data)

this.bindEvents()

this.model.fetch(1).then(({data})=>{

this.view.render(data)

})

},

bindEvents:function(){

//到这一层,this还指的是controller这个对象,但是到点击事件那一层,addOne函数里,this代表点击的那个元素(jQuery规定的)。

// 所以要使用addOne.bind(this)把controller这一层的this绑定到addOne那更深入的一层去,使this同一为controller这个对象

$(this.view.el).on('click', '#addOne', this.addOne.bind(this))

$(this.view.el).on('click', '#minusOne',this.minusOne.bind(this) )

$(this.view.el).on('click', '#reset', this.reset.bind(this))

},

addOne:function(){

let newNumber = $('#number').text()-0+1

let book = {number:newNumber}

this.model.update(1,book).//这个this已经被bind为controller

then(({data})=>{

this.view.render(data)//这个this已经被bind为controller

})

},

minusOne:function(){

let newNumber = $('#number').text()-0-1

let book = {

number:newNumber

}

this.model.update(1,book)//这个this已经被bind为controller

.then(({data})=>{

this.view.render(data)

})

},

reset:function(){

let newNumber = 0

let book = {

number:newNumber

}

this.model.update(1,book)

.then(({data})=>{

this.view.render(data)

})

}

}

controller.init({model:bookModel,view:bookView})//初始化,并把Model和View传进去

//假的后台,不要看

function fakeData(){//假的后台

let book = {

name:'JavaScriptBook',

number:10,

id:'1'

}

// 在response真正返回之前拦截,修改他的数据,使用这个api来模拟后台响应数据

axios.interceptors.response.use(function(response){

let {config: {url, method, data}} = response

// ES6语法,从response里的config拿出url method data,并声明

if(url === '/book/1' && method === 'get'){

response.data = book

} else if(url === '/book/1' && method === 'put'){

let dataObj = JSON.parse(data)

Object.assign(book,dataObj)

console.log(book)

response.data = book ;

}

return response;

})

}

在前端开始慢慢发展的时候,前端程序员就是这样进行技术迭代的,上面就是MVC迭代的过程。这就是MVVM出现之前的MVC。

使用vue改写上面的代码

从上面的代码来看,view类的作用是:

有一个没有填充数据的HTML模板template

model发送请求获取数据后,view把数据填充到模板里,然后渲染填充后的html到页面

VUE框架的作用是可以把MVC里的view类使用VUE代替。

注意:

需要直接传入data,传入data后vue对象就有了这个data的属性

VUE会有自动的render机制,VUE会帮我们做渲染html的过程,那我们怎么更新(渲染)HTML呢?直接改data数据就好了双向绑定()

template只能有一个根元素

从传统MVC转到VUE的MVC就是忘掉render,把data放到vue上面,要更新数据,就直接更新vue里面的data即可。

把render变成了简单的赋值操作。而且这种渲染只更新你改变的那个值所在的节点,不会渲染全部模板。

vue第一个特点是data归他管,第二就是会精细得更新该渲染的地方。

但vue的野心不仅于此,vue可以让你做到不需要controller。因为controller最重要的功能绑定事件,vue有一种语法可以绑定事件。具体用法是在html属性里添加v-on:click="f",然后在methods 里写f函数即可。

主要代码:

fakeData()

// -------------上面是假的后台-----------------

//从这开始写MVC类

function Model(options){

this.data = options.data

this.resource = options.resource

}

Model.prototype.fetch = function(id){

return axios.get(`/${this.resource}/${id}`).then((response)=>{

this.data = response.data

return response

})

}

Model.prototype.update = function(id,data){

return axios.put(`/${this.resource}/${id}`,data).then((response)=>{

this.data = response.data

return response

})

}

// --------上面是Model类-----------

let bookModel = new Model({data:{name:'',number:0,id:''},resource:'book'})

let bookView = new Vue({//不用写view类了,直接用vue充当view类,需要传入data,

el:'#app',

data:{//data里的属性会转变为vue对象的属性

book:{

name:'',

number:0,

id:'1'

},

n:1//两个数据,一个book对象,一个n的值

},

//template只能有一个根元素

template:`

书的名称:《{{book.name}}》

书的数量:{{book.number}}

双向绑定:

输入需要加或者减的数:

n的值为{{n}}

加n

减n

归零

`,

created:function(){//在创造vue时执行的函数,进行首次渲染

bookModel.fetch(1).then(({data})=>{

//vue会直接同步渲染html,所以直接赋值给view.name和number就好了

this.book = bookModel.data;//或者this.book = data;因为data是传回来的response,在model里,也把传回来的数据放到了model里

// this.view.render(this.model.data)这句不需要了,因为修改vue数据后会自动渲染

})

},

methods:{//绑定的事件的函数

addOne:function(){

let newNumber = this.book.number + (this.n-0)//+n

//直接获取内存里的number,因为内存和页面是统一的,不需要获取dom了

let book = {number:newNumber}

bookModel.update(1,book).//直接用声明的bookModel对象里面的update方法,因为没有controller了

then(({data})=>{

// this.view.render(data)

this.book = data//返回的数据直接赋值给book,即可渲染

})

},

minusOne:function(){

let newNumber = this.book.number - (this.n-0)//-n

let book = {

number:newNumber

}

bookModel.update(1,book)

.then(({data})=>{

// this.view.render(data)

this.book = data

})

},

reset:function(){

let newNumber = 0

let book = {

number:newNumber

}

bookModel.update(1,book)

.then(({data})=>{

// this.view.render(data)

this.book = data

})

}

}

})

//假的后台,不要看

function fakeData(){//假的后台

let book = {

name:'我是初始名称JavaScriptBook',

number:10,

id:'1'

}

// 在response真正返回之前拦截,修改他的数据,使用这个api来模拟后台响应数据

axios.interceptors.response.use(function(response){

let {config: {url, method, data}} = response

// ES6语法,从response里的config拿出url method data,并声明

if(url === '/book/1' && method === 'get'){

response.data = book

} else if(url === '/book/1' && method === 'put'){

let dataObj = JSON.parse(data)

Object.assign(book,dataObj)

console.log(book)

response.data = book ;

}

return response;

})

}

但是vue不管model层的事

vue做的事就是让mvc里的v更智能,且能合并mvc的c

双向绑定

单向绑定:从内存里数据的更新到渲染页面的更新

双向绑定:不单单是从内存到页面,页面上的input修改了,还会反过来映射内存,内存会同时修改(只能input实现,因为只有input可以更改内存)

渲染是一种单向绑定,只单向得改变html的值。

vue就是自动化的mvc,既MVVM

MVVM

通过以上的分析,我们发现,我们不需要去绑定事件,也不需要去render了,我需要做的就是取值和赋值。

用vue做三个小东西

java mvc mvvm_从MVC到MVVM(为什么要用vue)相关推荐

  1. 被误解的MVC和被神化的MVVM

    被误解的 MVC MVC 的历史 MVC,全称是 Model View Controller,是模型 (model)-视图 (view)-控制器 (controller) 的缩写.它表示的是一种常见的 ...

  2. mvvm模式和mvc的区别_被误解的 MVC 和被神化的 MVVM,值得收藏!

    MVC 的历史 MVC,全称是 Model View Controller,是模型 (model)-视图 (view)-控制器 (controller) 的缩写.它表示的是一种常见的客户端软件开发框架 ...

  3. 猿学~被误解的MVC和被神化的MVVM

    被误解的 MVC MVC 的历史 MVC,全称是 Model View Controller,是模型 (model)-视图 (view)-控制器 (controller) 的缩写.它表示的是一种常见的 ...

  4. iOS开发-进阶:被误解的MVC和被神化的MVVM(作者:唐巧)

    文章转自: http://www.infoq.com/cn/articles/rethinking-mvc-mvvm 作者 唐巧 发布于 2015年11月1日 | 被误解的 MVC MVC 的历史 M ...

  5. java mvc引擎_Velocity是一种Java模版引擎技术,MVC架构的一种实现,但它更多的是关注在Model和View之间,作为它们的桥梁。服务端渲染,我们使用最多的就是用他...

    Velocity是一种Java模版引擎技术,MVC架构的一种实现,但它更多的是关注在Model和View之间,作为它们的桥梁.服务端渲染,我们使用最多的就是用他来渲染HTML.下面我们看看他与spri ...

  6. [原创]java WEB学习笔记18:java EE 中的MVC 设计模式(理论)

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  7. java计算机毕业设计基于MVC框架的在线书店设计源码+数据库+系统+lw文档+mybatis+运行部署

    java计算机毕业设计基于MVC框架的在线书店设计源码+数据库+系统+lw文档+mybatis+运行部署 java计算机毕业设计基于MVC框架的在线书店设计源码+数据库+系统+lw文档+mybatis ...

  8. 物流快递系统前、后端+Java语言+SpringBoot项目+MVC三层架构+maven+Mysql+Tomcat+可以用于学习SpringBoot项目入门

    物流快递系统前.后端+Java语言+SpringBoot项目+MVC三层架构+Mysql+Tomcat+可以用于学习SpringBoot项目入门 可以用于课程设计.毕业设计的知识点入门学习 提示:此资 ...

  9. 【愚公系列】2023年04月 Java教学课程 135-Spring MVC框架的概念和基本使用

    文章目录 一.SpringMVC 概述 二.入门案例 1.入门案例制作 2.入门案例工作流程分析 3.SpringMVC 技术架构图 三.基本配置 1.常规配置(Controller加载控制) 1.1 ...

最新文章

  1. NEC使用C+L EDFA在超过1.1万公里的海底光缆中首次实现50Tb传输
  2. pytorch的两个函数 tensor.detach(),tensor.detach_(),tensor.clone() 的作用和区别
  3. python语言有哪两个系列_(转)Python学习笔记系列——Python是一种纯粹的语言
  4. C/C++基本数据类型所占字节数
  5. attiny13a程序实例_ATtiny13A图文构成
  6. Linux下读取smBIOS源码,Linux下读取SMBIOS信息
  7. php弹幕技术轮询,PHP实现长轮询消息实时推送功能代码
  8. 爬虫从入门到放弃——爬虫的基本原理
  9. 测试AS3的性能9800粒子
  10. 推荐系统应该如何保障推荐的多样性?
  11. Mysql-元数据的查询/case when配合聚合函数的技巧
  12. 自己对行业未来发展的认知_我们正在建立的认知未来
  13. [codeforces 1293A] ConneR and the A.R.C. Markland-N 不超时的二分/无限长数组map+桶排序
  14. 网吧用计算机性能配件清单,网吧主机都是什么配置?看看清单就知道!
  15. java pfx_如何在Java读取PFX格式证书
  16. 纯前端实现人体抠图背景融合-调用Face++抠像接口API实现人像抠图
  17. DNSPod十问顺丰科技唐恺:为什么顺丰快递那么快?
  18. 状态机(FSM)的分类描述
  19. 基于OpenPose的坐姿识别
  20. 创业者觉得苦逼得真正原因

热门文章

  1. 白话之jsonp跨域原理分析
  2. github-新建文件夹
  3. walle多渠道打包+Tinker(bugly)热更新集成+360加固(乐固)
  4. Emacs基本操作说明
  5. 公务员“上班睡觉”为何会被强势围观?
  6. 日本程序开发式自定义的malloc/free函数(一)-外部式样书(外部仕様書)
  7. auto_ptr scoped_ptr shared_ptr weak_ptr unique_ptr
  8. 一小段Python的sha256/md5/sha1验证
  9. SEO工具,站长必备
  10. 区块链开发公司开拓新用途 区块链对网络安全的作用