【MVC】 到 【MVVM】

212 阅读4分钟

参考链接:

medium.com/search?q=MV…

cn.vuejs.org/v2/guide/

1. axios库 —— 基于promise的http客户端,用于浏览器和node.js

1. axios和JQuery 的比较:

1. axios的功能函数更丰富些:(基本语法和JQuery差不多)
    
    axios.post()
    axios.get()
    axios.put()
    axios.patch()
    axios.delete()
    ……
    
2. axios除了Ajax功能之外没有其它功能,更专注,目前的很大程度上axios把Jquery的Ajax的功能给代替了
 (Vue把Jquery的DOM操作给取代了)
2. 使用axios库实现一个简单的功能:
    //html代码
    <div id="app">
        <div>
            书名:《__name__》 
            数量:<span id="number">__number__</span>
        </div>
        <div>
            <button id="addOne">加一</button>
            <button id="minusOne">减一</button>
            <button id="reset">清零</button>
        </div>
    </div> 
    //js代码(意大利,面条式代码/无组织无纪律)
        let book = {
            number: 2,
            id:1,
            name: 'JavaScript高级程序设计'
        }
        //在真正返回response之前拦截下面的函数
        axios.interceptors.response.use(function(response){ //这个函数对response做修改
            let {config:{url,method,data}} = response
    
            if(url='/books/1' && method === 'get'){
            response.data = book
            }else if(url === '/book2/' && method === 'put'){
            Object.assign(book,data)
            }
            return response
            response.data = book
        })

        /*上面的是假的数据库(后台)*/

        axios.get('/books/1')
            .then(({data}) =>{
                let originalHtml = $('#app').html()
                let newHtml = originalHtml.replace('__name__',data.name)
                    .replace('__number__',data.number)
            $('#app').html(newHtml)
        })


        $('#app').on('click','#addOne',function(){
            var oldNumber = $('#number').text() //string
            var newNumber = oldNumber - 0 + 1
            axios.put('/books/1/',{
            number : newNumber
        }).then( () => {
            $('#number').text(newNumber)
            })
        })
 
        $('#app').on('click','#minusOne',function(){
            var oldNumber = $('#number').text() //string
            var newNumber = oldNumber - 0 - 1
            axios.put('/books/1/',{
                number : newNumber
            }).then( () => {
                $('#number').text(newNumber)
            })
        })
 
 
        $('#app').on('click','#reset',function(){
            axios.put('/books/1/',{
                number : 0
            }).then( () => {
            $('#number').text(0)
            })
        })

以上代码实现的功能:

实现的功能

3. 使用axios库一些常用代码解析:
  1. axios.interceptors

      axios.interceptors.response.use()拦截响应,用户课任意篡改响应
    
      axios.interceptors.request.use()拦截请求,用户课任意篡改响应
    
  2. 如何用 axios get 请求 /xxx?id=1

       1. axios('/xxx?id=1')
       2. axios.get('/xxx?id=1')
       3. axios.get('/xxx',{params:{id:1}})
       4. axios({method:'get',url:'/xxx?id=1')
    
  3. axios.default.header.post['Content-Type'] = 'application/x-www-form-urlencoded';

    不发送post请求,设置所有post请求的默认请求头,默认Content-Type的值为application/x-www-form-urlencoded
    

2. 使用MVC实现上面的的功能:

    //html代码
    <div id="app">
    
    </div>
//js代码
fakeData()

function Model(options){
  this.data = options.data
  this.resource = options.resource
}
Model.prototype.fetch = function(id){
  return axios.get(`/${this.resource}s/${id}`).then((response) => {
      this.data = response.data
      console.log(this.data)
      return response
    })
}
Model.prototype.update = function(data){
  let id = this.data.id
    
    return axios.put(`/${this.resource}s/${id}`, data).then((response) => {
      this.data = response.data 
      console.log('response')
      console.log(response)
      return response
    })
}

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)
}


// ----------  上面是 MVC 类,下面是对象
let model = new Model({
  data: {
    name: '',
    number: 0,
    id: ''
  },
  resource: 'book'
})

let view = new 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">归零</button>
    </div>
  `
})

var controller = {
  init(options) {
    
    let view = options.view
    let model = options.model
    this.view = view
    this.model = model
    
    this.view.render(this.model.data)
    
    this.bindEvents()
    this.model.fetch(1).then(() => {
      console.log('this.model.data')
            console.log(this.model.data)
      this.view.render(this.model.data)
    })
    
  },
  addOne() {
    var oldNumber = $('#number').text() // string
    var newNumber = oldNumber - 0 + 1
    this.model.update({
      number: newNumber
    }).then(() => {
      this.view.render(this.model.data)
    })

  },
  minusOne() {
    var oldNumber = $('#number').text() // string
    var newNumber = oldNumber - 0 - 1
    this.model.update({
      number: newNumber
    }).then(() => {
      this.view.render(this.model.data)
    })
  },
  reset() {
    this.model.update({
      number: 0
    }).then(() => {
      this.view.render(this.model.data)
    })
  },
  bindEvents() {
    // 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))
  }
}

controller.init({view:view, model: model})


3. 使用vue实现上面的的功能:

1. Vue —— 本质上是MVC的升级,是一套用于构建用户界面的渐进式框架.

  • Vue只关注视图层,Vue不像React等其他框架,它对于js的基础要求不是很高,通过简单的步骤就能实现的炫酷的效果。
  • Vue的另一个优点是他只会更新该更新的部分页面,不会渲染整个网页。

2. 使用Vue实现功能

//js代码/html代码不变
let view = new Vue({
  el: '#app',
  data: { //必须把data放到Vue实例上面
    book : {
       name: '未命名',
       number: 2,
       id: ''
    },
    n: 0
  },
    created(){
    model.fetch(1).then(()=>{
      this.book = model.data
    })
  },
  template: `
   <div>
    <div>
    书名:《{{book.name}}》
    数量:<span id=number>{{book.number}}</span>
    </div>
    <div>
      <input v-model="n">
      N的只是{{n}}  
    </div>
    <div>
      <button v-on:click="addOne">加N</button>
      <button v-on:click="minusOne">减N</button>
      <button v-on:click="reset">清零</button>
    </div>
  </div>
  `,
  methods:{
    addOne() {
      model.update({
        number: this.book.number + (this.n-0)
      }).then(() => {
        this.view.book = this.model.data
      })
    },
    minusOne() {
      model.update({
        number: this.book.number - (this.n-0)
      }).then(() => {
       this.view.book = this.model.data
      })
    },
    reset() {
      model.update({
        number: 0
      }).then(() => {
        this.view.book = this.model.data
      })
    }
  }
})


3. 双向绑定——

核心代码: template:{ <div> <input v-model="n"> N的只是{{n}} </div> }

前端的世界可以分为页面和内存

  1. 单向绑定:内存中的数据更改使得页面中相应部分刷新
  2. 双向绑定:内存中的数据更改使得页面中相应部分刷新,如果用户在页面中改变一些数据,使得内存中的数据改变,这就是双向绑定

4. MVVM —— MVVM是增强关注点分离的体系结构模式之一,它允许将用户界面逻辑与业务(或后端)逻辑分离。

其目标(以及其他MVC模式目标)是实现以下原则“使UI代码保持简单且无应用逻辑,以使其易于管理”。 Vue是升级版的MVC,通过Vue,开发者只要取值和赋值,不需要设置Controller,他就会自动地帮用户完成一些函数的作用,因此叫做MVVM,ViewModel and LiveData的缩写。