项目上使用 axios 的拦截器是在 jsbin.com 中进行的,同时要把jsbin的JavaScript改成es6 若是你在本地实验会发现拦截器不起做用,这是正常的。 你若是想让本地的拦截器也起做用,就须要本身写 server.js 来响应全部请求javascript
axios是ajax的库css
如何用 axios GET 请求 /xxx?id=1html
1.axios.get('/xxx?id=1')
2.axios.get('/xxx', {id:1})
3.axios.get('/xxx', {params: {id:1}} )
4.axios({method:'get', url: '/xxx?id=1'})
5.axios('/xxx?id=1');
复制代码
之前咱们使用ajax能够这么用:前端
1.$.ajax({
url: '/xxx'
method: 'post'
})
2.$.post('/xxx',data)
3.$.gat('/xxx')
复制代码
使用axios的用法:vue
1.axios.post()
2.axios.get()
3.axios.put()
4.axios.patch()
5.axios.deleate()
复制代码
1.比 jQuery.ajax功能更多java
2.除了ajax功能以外,没有其余功能(更专一)node
有了替代品以后jQuery就能够死掉了ios
第一个版本es6
为何减0,是把字符串转成numberajax
interceptors是拦截机,意思就是往...里面植入一个东西或者拦截一个东西
在真正返回response以前使用一个函数,这个函数会对response作一个修改
不作服务器,直接把前端的数据写死,也就是mock
咱们有没有办法根据请求的URl来mock不一样的数据呢?能够,咱们去获取一下这个response的config就好了,config里面有一个重要的属性url,method和data注意这里的data是请求data,这里的if ...else... 仍是和nodejs很像的,像nodejs的路由
let config = response.config
let {method,url,data} = config
复制代码
上面的2行能够用es6的解构语法把它们合并成一行,这样咱们就同时获得了4个变量分别是config,method,url,data
let {config:{method,url,data}} = response
复制代码
如今咱们就能够去伪造数据,response.data返回的就是咱们须要的数据,html中的书名和数量不能写死,要从response.data里去取
怎样把响应的数据塞到get的Promise的成功回到里呢?
能够: let data = response.data
,可是用es6的语法就是回调的参数{data},就能够拿到data了,log这个data
接着就是把这个data的数据弄到html中app里面
axios.get('/book/javascript').then(({data})=>{
let oldHtml = $('#app').html()
let newHtml = oldHtml.replace('__name__',data.name).replace('__number__',data.number)
$('#app').html(newHtml)
})
复制代码
这时候会发现,点击加1按钮不行了,为何由于以前的html被更改了,因此要作一下事件委托
由以前的
$('#addOne').on('click',function(){
var oldNumber = $('#number').text() -0
var newNumber = oldNumber + 1
$('#number').text(newNumber)
})
$('#minusOne').on('click',function(){
var oldNumber = $('#number').text() -0
var newNumber = oldNumber - 1
$('#number').text(newNumber)
})
$('#reset').on('click',function(){
var oldNumber = $('#number').text() -0
var newNumber = 0
$('#number').text(newNumber)
})
复制代码
改成:
$('#app').on('click','#addOne',function(){
var oldNumber = $('#number').text() -0
var newNumber = oldNumber + 1
$('#number').text(newNumber)
})
$('#app').on('click','#minusOne',function(){
var oldNumber = $('#number').text() -0
var newNumber = oldNumber - 1
$('#number').text(newNumber)
})
$('#app').on('click','#reset',function(){
var oldNumber = $('#number').text() -0
console.log(oldNumber)
var newNumber = 0
$('#number').text(newNumber)
})
复制代码
它的意思就是在点击#app里面的任何一个元素的时候,只要这个元素元素符合"#addOne"(或其余)就会触发事件
上面作的内容为:用ajax发请求,再用ajax获取到数据,而后再将数据替换到页面中的
$('#app').on('click','#addOne',function(){
var oldNumber = $('#number').text() -0
var newNumber = oldNumber + 1
axios.put('/book/javascript',{ // 加上的东西
number: newNumber
})
$('#number').text(newNumber)
})
复制代码
也就是说,先把{number: newNumer}数据push到服务器,若是push成功了,再改页面上的数据
假的服务器axios同时也要对put的作出响应,当请求的url是'/book/javascript'而且method为get的时候说明是想要获取旧的数据,就response旧的数据;当请求的路径是'/book/javascript'而且method是put的时候,确定要push一个新的数据,因而响应就要修改旧的数据,这个数据就是书的数量,全部要要有个书的变量,而且设置初始状态
assign的语法就是部分更新,asssgn就是批量的赋值,同时assign能够进行屡次赋值,后面的会覆盖前面的
回到代码中理解assign,传的是什么data(data是请求的data),assign就会把data覆盖到book上,同时book会存住数据的变化,而后把data做为数据(book上的数据)经过book返回给你,注意这里的data是字符串,要转成对象
let data = JSON.parse(data)
Object.assign(book,data); // 请求的data
response.data = book // 响应的data
复制代码
这时候点击按钮加1,控制台就会发送一个put请求
这样基本的功能就实现了,可是代码存在一个问题,就是是意大利面条式代码,代码逻辑结构不清晰
首先要把以前假的服务器的那一块包装成一个函数叫fakeData
所谓MVC就是把代码分割成3快功能职责划分明确的代码
首先改MVC的Model
声明一个model的对象,用来处理和数据相关的操做,model里面要有一个获取数据的函数fetch,一旦获取数据成功就把数据存到model上,记住要return这个response,只有return了,后面才能接着then.也要有一个更新数据的函数updata,它也和fetch同样一旦put成功就会返回一个Promise,成功了就调成功的回调 那咱们的数据存在哪里呢?因此model上还得有一个叫data的属性,用来放数据的初始值
而后就不要去管怎么去获取说数据了
axios.get('/book/javascript') => .then(({data})=>{
复制代码
改成:
model.fetch('javascript')
复制代码
也不用去管怎么去更新数据了
axios.put('/book/javascript',{
number: newNumber
})
复制代码
改成:
model.update({number: newNumber })
复制代码
它返回的是一个Promise对象,能够继续then,
model.update({number: newNumber })
$('#number').text(newNumber)
复制代码
改成:
model.update({number: newNumber }).then(()=>{
$('#number').text(newNumber)
})
复制代码
接下来去改MVC的View
全部和html相关的操做交给view来作,操做的元素是什么el,内容是什么,一开始内容是写在html里面,其实应该交给view来初始化,做为view的字符串模板
何时去作初始化呢?render(data)函数会去找到template而且把它里面的占位符替换为model传来的data,渲染页面的时候会从model那里获得这个data
let view = {
el: "#app",
template: `
<div>
书名: __name__
数量: <span id = "number">__number__</span>
</div>
<div>
<button id = "addOne">加1</button>
<button id = "minusOne">减1</button>
<button id = "reset">置0</button>
</div>
`,
render(){
let html = this.template.replace('__name__',data.name).replace('__number__',data.number)
$(this.el),html(html)
}
}
复制代码
这样以前旧的代码:
let newHtml = oldHtml.replace('__name__',data.name).replace('__number__',data.number).replace('__name__',data.name)
$('#app').html(newHtml)
复制代码
就能够被替换为:
let oldHtml = $('#app').html()
复制代码
更新view的代码:
$('#number').text(newNumber)
复制代码
也改成:
view.render(data)
复制代码
那么这个data哪里来的?
咱们能够从更新的成功回调里面去取.这个data = response.data
model.update({number: newNumber }).then(({data})=>{
view.render(data)
})
复制代码
也能够从model上去取:
由于model把response.data记到本身的data上了
let model = {
+++
update(data){
let id = this.data.id
return axios.put(`/book/{id}`,data).then((response)=>{
this.data = response.data
return response
})
+++
复制代码
因此把全部的
view.render(data) => view.render(model.data)
复制代码
回顾一下:
model会去获取一个数据,在返回数据以前,它会把response.data记到本身的data上;更新也是,返回更新的数据以前会把response.data记到本身的data上
view接收一个data,而后就把模板字符串更新渲染到#app里面
model会去获取叫javascript的书获取成功后,就把它的数据给view渲染一下
接下来再写controller
view和model以外的东西都交给controller来作,分为初始化和事件绑定bindEvents,bindEvents就是对view的元素进行事件绑定
(this.view.el)`
把3个对按钮的事件,封装成函数放在controller上
日常经过log(数字),二分法排bug
bindEvents(){
// 外面的this是controller
$(this.view.el).on('click','#addOne',this.addOne) // 这里的this是什么
$(this.view.el).on('click','#minusOne',this.minusOne)
$(this.view.el).on('click','#reset',this.reset)
}
复制代码
外面的this是controller若是想要它里面的this也是controller就得用bind()绑定,这样就能保证每个this表明controller
bindEvents(){
$(this.view.el).on('click','#addOne',this.addOne.bind(this) // 这里的this是被点击的元素,最好看一下jQ的on事件的click的this是什么
$(this.view.el).on('click','#minusOne',this.minusOne.bind(this))
$(this.view.el).on('click','#reset',this.reset.bind(this))
}
复制代码
对第二个版本继续迭代,若是实际中有不少页面,那么每一个也页面都要写一次M,V,C这3个对象,而后,每次写对象都要写不少重复的代码是否是很麻烦?
那如何解决这个问题呢?
咱们应该把共同的属性写到一个class里面或者构造函数,把共用的代码写到它的原型上面(要知道哪些是须要传的参数),特有属性放到它的构造函数里面,可是是经过传参的形式
例子中的model的data是属于特有的属性,因此要放到它构造函数的里面,而fetch和update是公寓属性得放到model的构造函数Model的共有属性上
请求的路径的book也能够不用写死,而是能够去从参数那里获取
这样写的好处就是:
咱们每次使用Model的代码就能够简化成只要写2个属性,而且还能够造一个关于车的Model等
let bookModel = new Model({
data:{
name: '',
id : '',
number: 0
},
resource: 'book'
})
booModel.fetch('javascript')
let carModel = new Model({
data: {
...
}
resource: 'car'
})
复制代码
再构造一个View的构造函数出来:
每个view的el是不同的,每个view的template也是不同的,只有render是共有属性放到View的原型上,el和template做为私有属性应该放到View的构造函数上
template的__name__和__number__也不能写死,得去遍历data
View.prototype.render = function(data){
let html = this.template
for(let key in data){
html = html.replace(`__${key}__`,data[key])
}
$(this.el).html(html)
}
复制代码
把View的el和templat绑定到它的this上
function View({el,template}){
this.el = el
this.template = template
}
复制代码
以便于后面使用
View.prototype.render = function(data){
let html = this.template
for(let key in data){
html = html.replace(`__${key}__`,data[key])
}
$(this.el).html(html)
}
复制代码
注意: this.xxx = xxx是一个很是重要的操做,一旦忘了记,就会报undefined
先去bootcdn上引入vue的cdn到页面上
而后把以前构造的View删除,而后把new view 改成new vue,这样基本就能够了
可是语法得改一下
1.把__name__改成{{name}}也就是说vue的作标记会不同
2.这个new出来的view会强制让把data传给它,不要传给model,它须要这个data,这个view须要根据这个data去初始化template
3.template只能有一个根元素,若是有2个,那么vue只会看第一个,也就是说最外面只需套一个div
vue就是把MVC作一下升级,只要把MVC搞清楚了,Vue的原理就搞清楚了
4.那render怎么办?没有render了,vue会有一个自动render的机制,以前写的MVC在controller中view会render数据data,引入Vue以后就不须要render了,由于data已经放到vue上了,初始化vue会帮咱们作
5.那当咱们获取到数据以后怎么去更新view呢?vue是没有render函数的,按道理说应该去改view的data
以前的
this.view.render(this.model.data)
复制代码
是否是这样改?
this.view.data = this.model.data
复制代码
6.Vue的一个重要特色,view会把data的属性升级到当前的view实例上面,也就是说有原来的view.data.name升级到了view.name,view.data.id升级到了view.name,view.data.number升级到了view.number 也就是说不是改view.data仍是直接去改view
this.model.fetch('javascript').then(()=>{
this.view.name = this.model.data.name
this.view.id = this.model.data.id
this.view.number= this.model.data.number
})
复制代码
也就是说一旦改动了view上的data的name,id,number,那么html就会自变,不用管render,vue会自动render
到目前为止引入vue以后和以前的MVC比较变化就是:
1>.忘掉render
2>.把data放到view上
3>.咱们须要改什么只要改data就好了
上面的写法感受比较麻烦有简洁一点的写法吗?
有
let view = new Vue({
el: "#app",
data:{
book:{
name: '未命名',
number: 0,
id: ''
}
},
+++
复制代码
这样写vue会把book当作view的属性而不是view.data的属性
this.model.fetch('javascript').then(()=>{
this.view.book = this.model.data
})
复制代码
注意:改了以后记得改模板字符换里面的变量的层级从属关系
let view = new Vue({
el: "#app",
data:{
book:{
name: '未命名',
number: 0,
id: ''
}
},
template: `
<div>
<div>
书名: 《{{book.name}}》
数量: <span id = "number">{{book.number}}</span>
</div>
<div>
<button id = "addOne">加1</button>
<button id = "minusOne">减1</button>
<button id = "reset">置0</button>
</div>
</div>
`
})
复制代码
vue把同步html这件事情变得很简单了,使得咱们把注意力从关注dom中抽离出来,vue会负责去拿到数据而后去渲染页面,使得咱们只须要去关注获取数据更改数据就好了,其余的事情交给vue就能够了
并且vue很厉害的地方就是vue不会刷新整个html,它只改该改的地方,能够作到拿到数据变化,只局部更新数据变化对应页面,而后局部渲染页面.做为对比,以前用MVC写的页面会从新更新所有的html
7.Vue的野心不止于此,Vue甚至可让咱们作到不须要controller,controller最重要的一件事就是绑定事件,若是Vue有一种语法能够更方便的绑定事件呢? 把以前放在controller上全部的工具函数,放到view的methods属性里面
那当用户点击按钮的时候怎么触发view里面的methods里面的addOne函数,minusOne函数, reset()函数呢?Vue有它本身的绑定事件的语法:
<button id = "addOne" v-on:click="addOne">加1</button>
复制代码
意思就是当用户点击这个按钮的时候就触发addOne函数,id也没用了!已经不须要选择元素了,直接在元素上就完成了事件绑定
修改完就是:
<div>
<div>
书名: 《{{book.name}}》
数量: <span id = "number">{{book.number}}</span>
</div>
<div>
<button v-on:click="addOne">加1</button>
<button v-on:click="minusOne">减1</button>
<button v-on:click="reset">置0</button>
</div>
</div>
复制代码
也不必用jQ去获取text了,直接去改view,让this.data.book.number + 1 ,可是Vue的语法不是这样的 vue会把data上的属性偷偷的放到本身身上,就变成了this.book.number + 1
methods: {
addOne(){
var oldNumber = $('#number').text() -0
var newNumber = oldNumber + 1
this.model.update({number: newNumber }).then(()=>{
this.view.render(this.model.data)
})
}
复制代码
==>
methods: {
addOne(){
model.update({number: this.book.number + 1}).then(()=>{
this.view.book = this.model.data
})
}```,
minusOne(){
this.model.update({number: this.book.number - 1 }).then(()=>{
this.view.book = this.model.data
})
},
reset(){
this.model.update({number: this.book.number - 1}).then(()=>{
this.view.book = this.model.data
})
}
}
复制代码
注意:
i.这里的this.book.就是this.data.book,Vue会把data里面的属性偷偷的放到本身身上
ii.model前不须要加this,由于Vue是无论model层的它不想操这个心,这个model是外面的model,是变量model不是属性model,因此把this删掉,直接用model这个变量,model仍是以前的MVC的model,可是controller被合并了,view被语法糖了
iii.更新数据成功后,也不须要rendel,只须要修改data上的数据就好了
iv.发现vue好像一直在作的事情就是更新model而后从Model那里拿数据,没有DOM
v.Vue的文档给了咱们第一步初始化的操做,在view里面加一个方法,created(){},通常能够在created函数中调用ajax获取页面初始化所需的数据
created(){
model.fetch('javascript').then(()=>{
this.book = model.data
})
}
复制代码
model.fetch('javascript')就是发起get请求,服务器给予响应,响应的内容为data,而后就把数据赋给view的book.name变成新的number,name变成新的name,id变成新的id,而后Vue就会自动更新页面.
当点击加1的时候,已经绑定了事件为addOne,因此就会自动调用addOne,addOne会让model去updata,而后会获得新的数据data,而后把这个新的数据给view的book
这样就只须要作赋值和取值,就好了.有新的数据就赋值给book,想取book的值时候就this.book.numbe.如:
addOne(){
model.update({number: this.book.number+1 }).then(()=>{ //想取book的时候
this.view.book = this.model.data // 有新的数据就赋值给book
})
复制代码
Vue的好处就是让以前的vue变得更智能(能够自动render),同时MVC的C能够合并到Vue里面(methods放工具函数,created方法用来调用ajax获取页面初始化所需的数据)
咱们不加1减1,而是加n减n
咱们须要一个n放到data上面
把n放到页面的input上,通常用v-model
把methods里面的1改成this.n(字符串须要减0)
当咱们在输入框中输入5的时候,n的值会立刻变成5,这就是双向绑定
以前并无用户的输入,只要渲染出来就好了,渲染只是一种单向绑定
注释:
一开始是1很好理解.直接根据data去渲染就好了
当咱们在输入框中输入5的时候,首先Vue会发现n变了,因而就把data的属性n变成5.n变成5以后Vue发现 n的值是:{{n}}这里的n也得变,因而就变了
从图中看出:
单向绑定: 若是只是从内存到页面的render的过程就是单向绑定
双向绑定: 若是render以后,当用户改输入框中的值的时候,还能反着映射到内存.那么这就是双向绑定
Vue属于自动化的MVC(不须要view.render(model.data)Vue会自动帮咱们render)
1.由于Vue把MVC的controllerg改成 ==> 放到它的methods属性里面(M) 2.同时把以前的MVC的初始化controller(就是把view和model当参数传给controller)改成 ==> 放到它的created方法里面(C)
因此Vue就是一个从MVC到MVVM的过程
axios代替了ajax,vue代替了dom先关的操做,因此jQ就...
用框架显示做者牛x,用原生js显示本身牛x
用了vue就不要去碰dom
第一个小组件: Popover 组件
第二个小组件: Slides 组件
v-on:click="go(x)" 不只支持加函数名表示执行函数还支持函数名加参数的形式
v-bind:style = ""表示在div上绑定一个style属性
v-on表示事件监听; v-bind表示绑定
Vue的调试不能用控制台调试须要用html调试,如: {transformValue}
第三个小组件: Tab组件
变复杂了,同时变容易了。复杂的反义词是简单。 容易的反义词是困难。电锯很复杂,可是用电锯砍树很容易。斧头很简单,可是用斧头砍树很困难。若是电锯坏了,你就哭吧。由于修电锯太复杂了。 若是斧头坏了,磨一磨斧刃或者换根柄就行了。由于斧头简单。若是你只须要砍几棵树,买个电锯是否是划不来?电锯还须要用电,你砍树的地方首先得有电你才能用电锯,否则你就得柴油发电了。对普通人家来讲,仍是常备斧子吧。通常来讲复杂的东西会有一堆须要记的东西(写在电锯的说明书上)你看 Vue、React、Angular 的说明书有多厚就知道了。而简单的东西则记住一些简单的规则就好了:好比不要用斧头砍本身或其余人。你喜欢容易,仍是简单?大部分人喜欢复杂而容易的东西。
会用Vue不能说明咱们牛X,只能说Vue的做者牛X
若是只是作很简单的事情,买电锯是划不来的,学习Vue的过程就是买电锯,学习Vue的过程是须要好久的,如今才能大概理解Vue就是MVC的升级版,MVC的M要作ajax,MVC的V是操做页面的DOm树,C是控制流程的学习了算法数据结构和jS的基本语法,这样才能勉强算理解Vue,理解Vue的过程就是买电锯的花费,就是学习了解Vue须要掌握的基础知识包括ES6语法
大部分人喜欢复杂而容易的东西。好比你很喜欢开车,掌握方向盘和油门刹车就能够去想去的地方,可是若是让你去了解汽车的构造原理,了解为何打方向盘车就会转弯,挂挡踩油门车为何就有动力等就会变得特别复杂,跟不想学
学基础就是为了能了解MVC,之后学习其余框架同样要用到MVC的知识,MVC的M同样会用到ajax,MVC的V同样会用到DOM,MVC的C同样会用到数据结构,算法以及面向对象的知识