從MVC到MVVC

vue.js網(wǎng)址:https://cn.vuejs.org/v2/guide/
Vue就是用來代替MVC中的View的税迷。
MVVC = MVC + 雙向綁定

課程簡介


從 MVC 到 MVVM
預(yù)習(xí):Vue 官方文檔

代碼

MVC 版代碼:http://jsbin.com/dujutov/1/edit?js,output
Vue 版代碼:http://jsbin.com/dujutov/2/edit?html,js,output
Vue 浮層例子:http://jsbin.com/nabugot/1/edit?js,output
Vue 輪播例子:http://jsbin.com/liqicir/2/edit?js,output
Vue tab切換例子:http://jsbin.com/hijawuv/1/edit?html,css,output

睜大眼睛看清楚我用的是 jsbin.com 不是 js.jirengu.com订框,用 js.jirengu.com 有 bug 我才改成 jsbin.com 的。

用 Vue 代替 View

雙向綁定

引入axios

  1. 復(fù)習(xí)一下MVC

  2. 我們做一個書籍展示的頁面甥温,需要引入axios這個庫(https://github.com/axios/axios

  3. axios是一個ajax的庫,是一個基于Promise的Http客戶端。

    1. axios相對于jQuery的好處是除了get和post,還有put,patch痰催,delete等兜辞,其用法幾乎是照抄jQuery迎瞧,但是好處是支持更多的API,
    2. 除了ajax功能之外就沒有其余功能了逸吵,也就是更加專注凶硅。
  4. 以前我們使用jQuery,發(fā)現(xiàn)jQuery有一個問題扫皱,就是所有功能都混在一起足绅,即ajax相關(guān)使用.ajax(),而dom相關(guān)也是用『裕現(xiàn)在我們想將ajax和dom操作分開氢妈,使用ajax的時候就使用axios,誰用dom操作的時候就使用vue

    image.png

  5. 所以段多,后面基本不適用jQuery了

  6. 我們做一個圖書庫存管理的系統(tǒng)首量,現(xiàn)在以簡單的樣式實現(xiàn)


    image.png
  7. 我們的數(shù)據(jù)庫最好是從數(shù)據(jù)庫里面拿,axios比jQuery好的一個點在于支持自己給自己造數(shù)據(jù)进苍,即可以模擬服務(wù)器返回響應(yīng)加缘,其中interceptor就是攔截機的意思,其作用就會在真正返回response之前使用一個函數(shù)觉啊,這個函數(shù)會對response進行修改拣宏。


    image.png
  8. 上面這個操作就是mock server:為了更好的分工合作,讓前端能在不依賴后端環(huán)境的情況下進行開發(fā)杠人,其中一種手段就是為前端開發(fā)者提供一個web容器勋乾,這個本地環(huán)境就是 mock server。

  9. 我們可以根據(jù)不同的url來mock不同的數(shù)據(jù)搜吧,代碼如下所示市俊,當(dāng)axios的請求路徑不一樣的時候,將得不到返回數(shù)據(jù)

    axios.interceptors.response.use(function(response){
      // config里面有重要的url滤奈,method摆昧,data屬性,這個data是請求的data
      let {config: {url, method, data}} = response
      data = JSON.parse(data||'{}')
      // 這個row是響應(yīng)的data
      let row = {
        id: 1, name: 'JavaScript高級程序設(shè)計', number: 2
      }
      if(url === '/books/1' && method === 'get'){
        response.data = row
      }else if(url === '/books/1' && method === 'put'){
        response.data = Object.assign(row, data)
      }
      return response
    })
    
    axios.get('/books/1')
      .then((response)=>{
      console.log(response)
    })
    
    image.png
  10. ES6中蜒程,支持這種解構(gòu)語法:let {config: {url, method, data}} = response绅你,下面圖片中,第三行等于第一行+第二行


    image.png
  11. 同樣昭躺,下面第二種比第一種簡潔忌锯,也是ES6的解構(gòu)語法

    // 第一種寫法
    axios.get('/books/1')
      .then((response)=>{
      let data = response.data
      console.log(data)
    })
    
    // 第二種寫法
    axios.get('/books/1')
      .then(({data})=>{
      console.log(data)
    })
    
  12. 我們將拿到的數(shù)據(jù)重新渲染到頁面中,使用替換即可

    axios.interceptors.response.use(function(response){
      // config里面有重要的url领炫,method偶垮,data屬性,這個data是請求的data
      let {config: {url, method, data}} = response
      data = JSON.parse(data||'{}')
      // 這個row是響應(yīng)的data
      let row = {
        id: 1, name: 'JavaScript高級程序設(shè)計', number: 2
      }
      if(url === '/books/1' && method === 'get'){
        response.data = row
      }else if(url === '/books/1' && method === 'put'){
        response.data = Object.assign(row, data)
      }
      return response
    })
    
    axios.get('/books/1')
      .then(({data})=>{
      let originalHtml = $('#app').html()
      let newHtml = originalHtml.replace('__name__', data.name)
        .replace('__number__', data.number)
      $('#app').html(newHtml)
    })
    
    image.png
  13. 上面最終我們可以看到前面這個拿到的數(shù)據(jù)會顯示在網(wǎng)頁中

  14. 委托:但是我們發(fā)現(xiàn)一個BUG,發(fā)現(xiàn)原先的點擊事件起不了作用似舵,這是因為我們在操作$('#app').html(newHtml)這句話的時候脚猾,原先里面的button被替換了,我們需要做一個委托砚哗,下面這個寫法的意思就是在點擊app里面的任何一個元素的時候龙助,如果這個元素符合#addOne這個條件,就會執(zhí)行相關(guān)代碼蛛芥,這樣就算代碼被替換頁沒有關(guān)系提鸟,因為app始終是沒有動的,只是里面的內(nèi)容換了罷了

    $('#app').on('click', '#addOne', function(){
      var oldNumber = $('#number').text()
      var newNumber = oldNumber -0 +1
      $('#number').text(newNumber)
    })
    
  15. 整體的JS代碼如下

    axios.interceptors.response.use(function(response){
      // config里面有重要的url仅淑,method称勋,data屬性,這個data是請求的data
      let {config: {url, method, data}} = response
      data = JSON.parse(data||'{}')
      // 這個row是響應(yīng)的data
      let row = {
        id: 1, name: 'JavaScript高級程序設(shè)計', number: 2
      }
      if(url === '/books/1' && method === 'get'){
        response.data = row
      }else if(url === '/books/1' && method === 'put'){
        response.data = Object.assign(row, data)
      }
      return response
    })
    
    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()
      var newNumber = oldNumber -0 +1
      $('#number').text(newNumber)
    })
    
    $('#app').on('click', '#minusOne', function(){
      var oldNumber = $('#number').text()
      var newNumber = oldNumber -0 -1
      $('#number').text(newNumber)
    })
    
    $('#app').on('click', '#reset', function(){
      $('#number').text(0)
    })
    
  16. 到目前為止漓糙,我們先使用ajax獲取一個很簡單的數(shù)據(jù)铣缠,獲取到數(shù)據(jù)之后,將數(shù)據(jù)替換到html中昆禽,同時通過事件委托監(jiān)聽app的點擊事件蝗蛙;當(dāng)我們點擊的時候,我們需要發(fā)送請求醉鳖,到后臺去改數(shù)值捡硅,而不是表面上的加一減一。每一次改變number的時候盗棵,我們需要將新的number先put到服務(wù)器上面去壮韭,put成功就在頁面中更改值,發(fā)送不成功就不要更改值纹因。后端那邊也要做一個監(jiān)聽喷屋,將put上去的值給服務(wù)器。Object.assign(book, data)瞭恰,這個API用于部分更新屯曹,只更改對應(yīng)的部分,可以一次性賦值更改惊畏,可以多次覆蓋性更改


    image.png

    image.png
  17. 目前為止恶耽,我們做了一個模擬后臺,三個點擊按鈕當(dāng)被點擊的時候颜启,就會發(fā)送put請求偷俭,但是這個代碼很麻煩,因為每次都要重復(fù)寫put請求缰盏,這種屬于意大利面條式代碼涌萤,沒有太多組織性淹遵,總體的代碼如下,每次點擊的時候會出現(xiàn)延遲更新的狀態(tài)

    let book = {
      id: 1,
      name: 'JavaScript高級程序設(shè)計',
      number: 2
    }
    axios.interceptors.response.use(function(response){
      // config里面有重要的url负溪,method合呐,data屬性,這個data是請求的data
      let {config: {url, method, data}} = response
      if(url === '/books/1' && method === 'get'){
        // 這個data是響應(yīng)的data
        response.data = book
      }else if(url === '/books/1' && method === 'put'){
        Object.assign(book, data)
        response.data = book
      }
      return response
    })
    
    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()
      var newNumber = oldNumber -0 +1
      axios.put('/books/1', {
        number: newNumber
      }).then(()=>{
        $('#number').text(newNumber)
      })
    })
    
    $('#app').on('click', '#minusOne', function(){
      var oldNumber = $('#number').text()
      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)
      })
    })
    

引入MVC


  1. 我們引入MVC笙以,所謂MVC是將其變成三部分。我們寫一個model冻辩,所有跟數(shù)據(jù)相關(guān)的操作猖腕,都用model來實現(xiàn)
  2. 所有跟html相關(guān)的操作都用view,來操作
  3. 所有model和View之外的都交給controller來操作恨闪。
  4. 最終的代碼如下所示:
    fakeData()
    
    let model = {
      data: {
        name: '',
        number: 0,
        id: 1
      },
      fetch: function(){
        return axios.get('/books/1').then((response)=>{
          this.data = response.data
          return response
        })
      },
      update: function(data){
        let id= this.data.id
        return axios.put('/books/1', data).then((response)=>{
          this.data = response.data
          return response
        })
      }
    }
    
    let view = {
      el: '#app',
      template: `
        <div>
          書名:《__name__》
          數(shù)量:<span id=number>__number__</span>
        </div>
        <div>
          <button id="addOne">加1</button>
          <button id="minusOne">減1</button>
          <button id="reset">歸零</button>
        </div>
      `,
      render(data){
        let html = this.template.replace('__name__', data.name)
          .replace('__number__', data.number)
        $(this.el).html(html)
      }
    }
    
    let controller = {
      init: function(options){
        let {view, model} = options
        this.view = view
        this.model = model
        this.view.render(this.model.data)
        this.bindEvents()
        this.model.fetch(1).then(() => {this.view.render(this.model.data)})
      },
      addOne: function(){
        var oldNumber = $('#number').text()
        var newNumber = oldNumber -0 +1
        this.model.update({number: newNumber}).then(({data})=>{
          this.view.render(this.model.data)
        })
      },
      minusOne: function(){
        var oldNumber = $('#number').text()
        var newNumber = oldNumber -0 -1
        this.model.update({number: newNumber}).then(()=>{
          this.view.render(this.model.data)
        })
      },
      reset: function(){
        this.model.update({number: 0}).then(()=>{
          this.view.render(this.model.data)
        })
      },
      bindEvents: function(){
        $(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})
    
    /* 上面是加了一個假的后臺 */
    
    function fakeData(){
      let book = {
        id: 1,
        name: 'JavaScript高級程序設(shè)計',
        number: 2
      }
      axios.interceptors.response.use(function(response){
        // config里面有重要的url倘感,method,data屬性咙咽,這個data是請求的data
        let {config: {url, method, data}} = response
        if(url === '/books/1' && method === 'get'){
          // 這個data是響應(yīng)的data
          response.data = book
        }else if(url === '/books/1' && method === 'put'){
          // 傳入的data被拆分成一個一個字符串老玛,需要將其放到一起
          data = JSON.parse(data)
          Object.assign(book, data)
          response.data = book
        }
        return response
      })
    }
    
  5. 上面這個代碼中,有三個對象钧敞,一個對象是Model蜡豹,一個View,一個是Controller溉苛,假設(shè)我們有多個頁面镜廉,如果每個頁面都要寫這三個對象,那么就會比較麻煩愚战。我們應(yīng)該創(chuàng)建類娇唯,將共同的屬性放入class中〖帕幔或者寫構(gòu)造函數(shù)塔插,將公有的東西寫到原型中。
  6. 我們將代碼進行更好拓哟,變成下面這樣:
    fakeData()
    
    // 下面是MVC的類
    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)=>{
        console.log(response)
        this.data = response.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
        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__》
          數(shù)量:<span id=number>__number__</span>
        </div>
        <div>
          <button id="addOne">加1</button>
          <button id="minusOne">減1</button>
          <button id="reset">歸零</button>
        </div>
      `
    })
    
    let controller = {
      init: function(options){
        let {view, model} = options
        this.view = view
        this.model = model
        this.view.render(this.model.data)
        this.bindEvents()
        this.model.fetch(1).then(() => {this.view.render(this.model.data)})
    
      },
      addOne: function(){
        var oldNumber = $('#number').text()
        var newNumber = oldNumber -0 +1
        this.model.update({number: newNumber}).then(({data})=>{
          this.view.render(this.model.data)
        })
      },
      minusOne: function(){
        var oldNumber = $('#number').text()
        var newNumber = oldNumber -0 -1
        this.model.update({number: newNumber}).then(()=>{
          this.view.render(this.model.data)
        })
      },
      reset: function(){
        this.model.update({number: 0}).then(()=>{
          this.view.render(this.model.data)
        })
      },
      bindEvents: function(){
        $(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})
    
    /* 上面是加了一個假的后臺 */
    function fakeData(){
      let book = {
        id: 1,
        name: 'JavaScript高級程序設(shè)計',
        number: 2
      }
      axios.interceptors.response.use(function(response){
        // config里面有重要的url想许,method,data屬性彰檬,這個data是請求的data
        let {config: {url, method, data}} = response
        if(url === '/books/1' && method === 'get'){
          // 這個data是響應(yīng)的data
          response.data = book
        }else if(url === '/books/1' && method === 'put'){
          // 傳入的data被拆分成一個一個字符串伸刃,需要將其放到一起
          data = JSON.parse(data)
          Object.assign(book, data)
          response.data = book
        }
        return response
      })
    }
    

引入Vue


  1. 引入Vue,我們先刪除自己的view逢倍,將里面的let view = new View()改成let view = new Vue()捧颅。里面的標(biāo)記__改成兩個大括號,如name改成{{name}}较雕。并且我們需要將model里面的data傳到Vue里面來碉哑,因為vue需要根據(jù)這個data初始化這個template
    image.png
  2. template里面只能有一個根元素挚币,如果有兩個根元素,那么特點1:Vue只看第一個扣典,這樣原先沒有顯示的button就出現(xiàn)了


    image.png
  3. Vue就是MVC做了升級妆毕,特點2:Vue里面不需要render事件,因為Vue里面自動有一個render機制
  4. 當(dāng)vue的data里面的數(shù)據(jù)發(fā)生變化的時候贮尖,會自動更新笛粘,記住,直接更改vue.data = ...是沒有用的湿硝,需要更改里面的值薪前,這是因為Vue的第三個特點是會將data里面的所有屬性升級到當(dāng)前的view上面,不能改data去改view关斜,應(yīng)該改data里面的屬性示括,也就是我們找data屬性沒用了
  5. 以前的更新,最重要的一句話是view.render(midel.data)痢畜,現(xiàn)在只需要更新view.data垛膝,html更新會自動進行
  6. 我們可以將三個屬性同時放到一個屬性里面,只要這個屬性變了就會更新丁稀,這個book是view的屬性吼拥,而不是放到data里面的,Vue會自動將book屬性提升到view層面


    image.png
  7. Vue只更改該改的地方线衫,不會整個去刷新頁面扔罪,而之前的MVC寫法,一旦app里面的任意內(nèi)容發(fā)生變化桶雀,這個app都會被重新替換矿酵。
  8. Vue支持不適用Controller,我們看到我們的Controller最重要的語法是綁定監(jiān)聽矗积,對應(yīng)到Vue上面就是method全肮,將controller里面所有的函數(shù)寫到這個method里面,而且bindEvents不需要了棘捣,因為vue內(nèi)置了bindEvents
  9. Vue是不管model的辜腺,但是我們省略了所有dom的獲取更新操作,這個形成了自動化
  10. 我們還需要進行初始化乍恐,Vue里面有一個created屬性函數(shù)评疗,用于在元素創(chuàng)建成功之后調(diào)用,還有一個mount函數(shù)茵烈,用于掛載成功之后調(diào)用百匆。
  11. Vue的好處就是讓以前寫的代碼更智能,讓MVC的C合并到Vue里面去
  12. 現(xiàn)在的代碼如下所示:
    fakeData()
    
    // 下面是MVC的類
    // 使用Vue之后呜投,M保留了加匈。C被合并到V中了存璃,View使用了Vue
    // 初始化以及事件綁定等操作都放入View中了
    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
        return response
      })
    }
    Model.prototype.update = function(data){
      console.log(data)
      let id= this.data.id
      return axios.put(`/${this.resource}s/${id}`, data).then((response)=>{
        this.data = response.data
        return response
      })
    }
    
    
    
    // 下面是MVC對象
    let model = new Model({
      data: {
        name: '',
        number: 0,
        id: ''
      },
      resource: 'book'
    })
    
    // 使用Vue創(chuàng)建view
    let view = new Vue({
      el: '#app',
      // 放在model里面的數(shù)據(jù)可以放一份到data中,data里面的屬性會自動提升給view
      // 訪問的時候使用this.book雕拼,而不是this.view.book
      data: {
        book: {
          name: '未命名',
          number: 0,
          id: ''
        },
        n: 1
      },
      // 變量的標(biāo)識使用兩個大括號包圍
      template: `
        <div>
          <div>
            書名:《{{book.name}}》
            數(shù)量:<span id=number>{{book.number}}</span>
          </div>
          <div>
            <input v-model="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>
      `,
      // 這個函數(shù)是在el被創(chuàng)建的時候自動調(diào)用纵东,可以認(rèn)為是初始化
      created(){
        model.fetch(1).then(()=>{
          this.book = model.data
        })
      },
      // 里面所有的綁定事件可以放到這個里面。使用v-on:click="方法名"進行調(diào)用
      // Vue有一個好處是啥寇,只要放在data標(biāo)識里面的數(shù)據(jù)被更改了偎球,就會自動渲染更改的部分,而不會更改其他部分
      methods: {
        addOne(){
          model.update({
            number: this.book.number + this.n*1
          }).then(()=>{
            this.view.book = model.data
          })
        },
        minusOne(){
          model.update({
            number: this.book.number - this.n*1
          }).then(()=>{
            this.view.book = model.data
          })
        },
        reset(){
          model.update({
            number: 0
          }).then(()=>{
            this.view.book = model.data
          })
        }
      }
    })
    
    
    
    /* 上面是加了一個假的后臺 */
    
    function fakeData(){
      let book = {
        id: 1,
        name: 'JavaScript高級程序設(shè)計',
        number: 2
      }
      axios.interceptors.response.use(function(response){
        // config里面有重要的url辑甜,method甜橱,data屬性,這個data是請求的data
        let {config: {url, method, data}} = response
        if(url === '/books/1' && method === 'get'){
          // 這個data是響應(yīng)的data
          response.data = book
        }else if(url === '/books/1' && method === 'put'){
          // 傳入的data被拆分成一個一個字符串栈戳,需要將其放到一起
          data = JSON.parse(data)
          Object.assign(book, data)
          response.data = book
        }
        return response
        console.log(response)
      })
    }
    
  13. 使用v-model="n"是將值綁定到data里面的n去。這是一種雙向綁定难裆,我們將input的值綁定到data的n值上面去子檀,同時又拿到這個值渲染到這個頁面中來,現(xiàn)在我們只需要更改input里面的值乃戈,后面的渲染也會隨即更改


    image.png
  14. 只有input能實現(xiàn)雙向綁定褂痰,span是不可以的
    • 我們之前使用span的時候,span能拿到data里面的n進行渲染症虑,當(dāng)更改內(nèi)存中n的時候缩歪,再次渲染將n的值給span。所有的過程都是單向的谍憔,拿到內(nèi)存中的n匪蝙,渲染給span
    • 但是當(dāng)有input的時候,我們第一次拿到n的是給input习贫,這是一個默認(rèn)值逛球,但是當(dāng)我們使用v-model="n"將input的value值與n鏈接起來,使得input的value變化的時候苫昌,n也變化颤绕,頁面中其余引用n的部分也跟著變化,這就是雙向綁定祟身。
    • image.png
    • 只從內(nèi)存到頁面奥务,這是單向的,但是如果頁面能映射到內(nèi)存袜硫,這就是雙向的氯葬。
  15. Vue是一種自動化的MVC,又叫MVVM

使用Vue做三個小東西


  1. 我們使用了Vue之后婉陷,jQuery就可以不使用了溢谤,因為我們已經(jīng)擺脫了操作DOM瞻凤。jQuery中的ajax已經(jīng)用axios代替了,我們現(xiàn)在只需要想數(shù)據(jù)之間的邏輯就好了世杀,不用花大量精力去處理DOM等阀参。

  2. 我們使用Vue可以很容易就實現(xiàn)一個點擊的浮動圖層,其中v-if="open"的意思就是當(dāng)open為true的時候瞻坝,顯示蛛壳,為false的時候就不顯示,toggle函數(shù)會更改open的值

    let view = new Vue({
      el: '#app',
      data: {
        open: false
      },
      template: `
        <div>
          <button v-on:click="toggle">點我</button>
          <div v-if="open">你好</div>
        </div>
      `,
      methods:{
        toggle(){
          this.open = !this.open
        }
      }
    })
    
    image.png
  3. 做個輪播所刀,使用了VUE就不用碰DOM衙荐,綁定的函數(shù)既支持加參數(shù),也支持只寫函數(shù)名浮创;可以使用v-bind:style綁定一個style屬性忧吟,

    let view = new Vue({
      el: '#app',
      data: {
        transformValue: ''
      },
      template: `
        <div>
          <div class="window">
            <div class="slides" v-bind:style="{transform:transformValue}"></div>
          </div>
          <button v-on:click="go(1)">1</button>
          <button v-on:click="go(2)">2</button>
          <button v-on:click="go(3)">3</button>
        </div>
      `,
      methods:{
        go(index){
          this.transformValue = `translateX(${-100*(index-1)}px)`
        }
      }
    })
    
    image.png

    如果要做圖片切換,需要使用v-for進行循環(huán)

  4. 做一個Tab切換斩披,v-show="值"溜族,如果值是真的,那么就展示垦沉,如果值是false煌抒,那么就不展示;v-on:click="selected = 0"這后面的字符串會被解析成公式進行執(zhí)行厕倍,v-bind:class="{active:selected === 0}的意思就是使用bind綁定一個active屬性寡壮,但是只有在selected === 0的時候,綁定才生效


  5. 最終的代碼如下所示

    let view = new Vue({
      el: '#app',
      data: {
        selected: 'a',
        tabs: [
          {name: 'a', content: 'aaa'},
          {name: 'b', content: 'bbb'},
          {name: 'c', content: 'ccc'}
        ]
      },
      template: `
        <div>
          <ol>
            <li v-for="tab in tabs"
              v-on:click="selected = tab.name"
              v-bind:class="{active: tab.name === selected}"
            >{{tab.name}}</li>
          </ol>
          <ol>
            <li v-for="tab in tabs"
              v-show="selected === tab.name"
            >{{tab.content}}</li>
          </ol>
        </div>
      `,
      methods:{
    
      }
    })
    
  6. 點擊的時候會出現(xiàn)內(nèi)容讹弯,以及樣式會進行更改


    image.png
  7. VUE學(xué)起來真的很簡單况既,但是一開始學(xué)VUE會不知道怎么實現(xiàn)

  8. 一個很好的Vue模擬網(wǎng)頁:https://jsfiddle.net/chrisvfritz/50wL7mdz/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市组民,隨后出現(xiàn)的幾起案子坏挠,更是在濱河造成了極大的恐慌,老刑警劉巖邪乍,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件降狠,死亡現(xiàn)場離奇詭異,居然都是意外死亡庇楞,警方通過查閱死者的電腦和手機榜配,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吕晌,“玉大人蛋褥,你說我怎么就攤上這事【Σ担” “怎么了烙心?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵膜廊,是天一觀的道長。 經(jīng)常有香客問我淫茵,道長爪瓜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任匙瘪,我火速辦了婚禮铆铆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘丹喻。我一直安慰自己薄货,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布碍论。 她就那樣靜靜地躺著谅猾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鳍悠。 梳的紋絲不亂的頭發(fā)上税娜,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機與錄音贼涩,去河邊找鬼。 笑死薯蝎,一個胖子當(dāng)著我的面吹牛遥倦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播占锯,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼袒哥,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了消略?” 一聲冷哼從身側(cè)響起堡称,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎艺演,沒想到半個月后却紧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡胎撤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年晓殊,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片伤提。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡亲澡,死狀恐怖梅猿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情乙埃,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布吹零,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏窗价。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一赶撰、第九天 我趴在偏房一處隱蔽的房頂上張望舌镶。 院中可真熱鬧,春花似錦豪娜、人聲如沸餐胀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽否灾。三九已至,卻和暖如春鸣奔,著一層夾襖步出監(jiān)牢的瞬間墨技,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工挎狸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留扣汪,地道東北人。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓锨匆,卻偏偏與公主長得像崭别,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子恐锣,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容