资讯专栏INFORMATION COLUMN

从 jQuery 到 VUE 技术栈

qiangdada / 776人阅读

摘要:当前前端最火热的框架当属,在学习之前先来看下的内部是如何工作的。我们从最基本的页面操作开始做起。书籍数量加减清零把占位符替换成数据事件相关的交给操作,有两个重要的属性初始化时需要传入两参数和,后面操作的都是在的都是在身上,而不是直接操作。

当前前端最火热的框架当属 VUE,在学习 VUE 之前先来看下 VUE 的内部是如何工作的。

我们从最基本的页面操作开始做起。

用 jQuery 操作页面

我们来实现一个页面,当点击按钮式,页面上的数字增加或减少

书籍:《JavaScript高级程序设计》 数量:2

用 jQuery 操作它很容易实现需求

let log = console.log.bind(console)     //把console.log 替换成 log 少打点代码
$(".addOne").on("click",()=>{
  let oldHtml = $(".number").text()
  let newHtml = oldHtml -0 +1
  $(".number").html(newHtml)
})
$(".minusOne").on("click",()=>{
  let oldHtml = $(".number").text()
  let newHtml = oldHtml -0 -1
  $(".number").html(newHtml)
})
$(".reset").on("click",()=>{
  $(".number").text("0")
})
axios 实现 ajax

我们真实的需求是,当点击按钮时,操作的时数据库里的数据,而不是直接在页面中操作。

这里引入一个库axios,可以实现在前端模拟后台,它有一个重要的 API:interceptors,可以实现在它上面 Mock 数据

// 我们要的数据
let book = {
  name:"JavaScript高级程序设计",
  number:2,
  id:""
}
axios.interceptors.response.use((response)=>{
  //下面这句等价于 let {url,method,data} = response.config
  let {config:{url,method,data}} = response        // 这里的 data 是请求体
  if(url === "/book/1" && method === "get"){
     response.data = book    //这里的 data 是响应体
  }else if(url === "/book/1" && method === "put"){
    data = JSON.parse(data)
    Object.assign(book,data)     //请求体 data,assign可实现局部更新
    response.data = book        //响应体 data
  }
  return response
})

页面中的数据我们应该用占位符代替,数据获取到之后 更新到页面中

//刚进入页面后的数据加载
axios.get("/book/1").then(({data})=>{
  let oldHtml = $(".app").html()
  let newHtml = oldHtml.replace("__name__",data.name) 
    .replace("__number__",data.number)    //用真实数据替换占位符
  $(".app").html(newHtml)
})
$(".app").on("click",".addOne",()=>{
  let oldNumber = $(".number").text()
  let newNumber = oldNumber -0 +1
  axios.put("/book/1",{number:newNumber}).then(({data})=>{    //请求时更新最新数据
    $(".number").html(data.number)
  })
})
$(".app").on("click",".minusOne",()=>{
  let oldNumber = $(".number").text()
  let newNumber = oldNumber -0 -1
  axios.put("/book/1",{number:newNumber}).then(({data})=>{
    $(".number").html(data.number)
  })
})
$(".app").on("click",".reset",()=>{
  axios.put("/book/1",{number:0}).then(({data})=>{
    $(".number").html(data.number)
  })
})

这样的意大利面条似的写法,非常不利于后期维护,我们应该用 MVC 优化下

用 MVC 优化

获取数据,更新数据的事情交个model去做,model里面有三个属性:datafetchupdata;分别用来:data负责存储最新数据,fetch负责页面加载时向服务器获取数据,并将数据存储到data中,updata负责实时页面操作时,更新页面数据,并将最新数据保存到data中。

let model ={
  data:{    //model 内部用来存储数据
    name:"",
    number:0,
    id:""
  },
  fetch(id){
    return axios.get(`/books/${id}`).then((response)=>{
      this.data = response.data        //加载更新向 axios 获取的数据
      return response      
    })
  },
  updata(id,data){
    return axios.put(`/books/${id}`,data).then((response)=>{
      this.data = response.data        //点击按钮向 axios 获取最新数据,请求中的 data 是最新数据
      return response
    })
  }
}

操作页面交给viewview有三个属性,分别是eltemplaterenderel负责视图部分,也就是你需要操作的 DOM,template是虚拟的html,并通过render去渲染。

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

事件相关的交给controller操作,有两个重要的属性:initbingEvents;初始化时需要传入两参数viewmodel,后面操作的都是在的viewmodel都是在controller身上,而不是直接操作model

let controller = {
  init({view,model}){
    this.view = view
    this.model = model
    this.bindEvents()
    this.model.fetch(1).then(()=>{  
      view.render(this.model.data)
    })
  },
  bindEvents(){
    $(this.view.el).on("click",".addOne",this.addOne.bind(this)) //这里 addOne 内部的 this 应该是点击的那个元素,所以这里要绑一下 this
    $(this.view.el).on("click",".minusOne",this.minusOne.bind(this))
    $(this.view.el).on("click",".reset",this.reset.bind(this))
  },
  addOne(){
    console.log(1)
    let oldNumber = $(".number").text()
    console.log(2)
    let newNumber = oldNumber -0 +1
    console.log(3)
    this.model.updata(1,{number:newNumber}).then(()=>{
        $(".number").html(this.model.data.number)
    })
    console.log(4)
  },
  minusOne(){
    let oldNumber = $(".number").text()
    let newNumber = oldNumber -0 -1
    this.model.updata(1,{number:newNumber}).then(()=>{
      $(".number").html(this.model.data.number)
    })
  },
  reset(){
    this.model.updata(1,{number:0}).then(()=>{
      $(".number").html(this.model.data.number)
    })
  }    
}
controller.init({view:view,model:model})
优化 MVC

现在是一个页面,这也写没有关系,但如果有很多页面,每个页面中的viewmodelcontroller都重复了,这里把一些公用的方法写在原型上。

在页面中使用model,只需要传递两参数

function Model({data,resouce}){
  this.data = data
  this.resouce = resouce
}

Model.prototype.updata = function(id,data){
  return axios.put(`/${this.resouce}s/${id}`,data).then((response)=>{
    this.data = response.data
    return response
  })
}

Model.prototype.fetch = function(id){
    return axios.get(`/${this.resouce}s/${id}`).then((response)=>{
      this.data = response.data
      return response      
    })
}
let model = new Model({
  data:{
    name:"",
    number:0,
    id:""
  },
  resouce:"book"  
})

view也是,页面使用时,传两个参数就 ok 了

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)
}
let view = new View({
  el:".app",
  template:`
    
书籍:《__name__》 数量:__number__
` })

Controller公用的方法比较少,这里就没有优化了

VUE

理解了 MVC 之后再来看 VUE 就会很简单,VUE 简单来说就是 MVC 中的 V,但它和 MVC 有点区别,就是它需要model中的数据

let view = new Vue({
  el:".app",
  data:{
    book:{
       name:"我是书籍",
       number:0,
       id:"" 
     },
    n:1
  },
  template:`
    
书籍:《{{book.name}}》 数量:{{book.number}}
` }

VUE 会把data里的属性提升为 Vue 的属性,所以下面操作可以直接用Vue.name操作,而不是写Vue.data.name,所以我们可以在这些属性外面套一层book,用Vue.book就可以对这些属性进行批量操作。

Vue没有render方法,那你会说它怎么实现渲染页面呢?

它提供了一个叫created的方法,在里面直接修改Vuedata属性,它就会自动帮你渲染页面

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

当然 VUE 的野心不止于此 ,它甚至帮你省下controllor,你都不需要进行事件绑定



它在templatev-on:click的一个方法,它会帮你调用methods中的方法,你只需要将点击执行的函数写在上面即可。

methods:{
    addOne(){
      model.updata(1,{number:this.book.number + (this.n-0)})
        .then(()=>{
          this.book = model.data
        })
    },
    minusOne(){
      model.updata(1,{number:this.book.number - (this.n-0)})
        .then(()=>{
          this.book = model.data
        })
    },
    reset(){
      model.updata(1,{number:0})
        .then(()=>{
          this.book = model.data
        })
    }
}    

学会了 MVC 之后在来看 VUE,就变的很简单

MVVM

VUE 还实现另一个双向绑定的功能,我现在点击按钮只能+1-1,如果我要实现操作+n或减n呢?

这里用input实现,在按钮上面添加一行

N的值是{{n}}

当然Vuedata中也要添加一个n

当你在input中输入相应值时,后面N的值会相应变化,这就是 MVVM。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/97004.html

相关文章

  • 技术的沉淀

    摘要:我是一个从,,到的比较常规的技术栈过渡过程。第一授权,微信授权分为静默授权和弹皮授权目的就是获取用户信息取得用户的唯一以便业务的开发。 我也是一个经历过柴米油盐酱醋茶、尝过酸甜苦辣咸的前端程序员。知道前端的东西入门简单,有深度却很难;表似好看无比的应用,其实背后逻辑复杂,然而要想成长的更快,一定要学会站在巨人的肩膀上,学以师技以自长。所以一些经验非常可贵,在此我想和大家分享一下我的经验...

    JerryWangSAP 评论0 收藏0
  • 技术的沉淀

    摘要:我是一个从,,到的比较常规的技术栈过渡过程。第一授权,微信授权分为静默授权和弹皮授权目的就是获取用户信息取得用户的唯一以便业务的开发。 我也是一个经历过柴米油盐酱醋茶、尝过酸甜苦辣咸的前端程序员。知道前端的东西入门简单,有深度却很难;表似好看无比的应用,其实背后逻辑复杂,然而要想成长的更快,一定要学会站在巨人的肩膀上,学以师技以自长。所以一些经验非常可贵,在此我想和大家分享一下我的经验...

    e10101 评论0 收藏0
  • 技术的沉淀

    摘要:我是一个从,,到的比较常规的技术栈过渡过程。第一授权,微信授权分为静默授权和弹皮授权目的就是获取用户信息取得用户的唯一以便业务的开发。 我也是一个经历过柴米油盐酱醋茶、尝过酸甜苦辣咸的前端程序员。知道前端的东西入门简单,有深度却很难;表似好看无比的应用,其实背后逻辑复杂,然而要想成长的更快,一定要学会站在巨人的肩膀上,学以师技以自长。所以一些经验非常可贵,在此我想和大家分享一下我的经验...

    keke 评论0 收藏0
  • 技术的沉淀

    摘要:我是一个从,,到的比较常规的技术栈过渡过程。第一授权,微信授权分为静默授权和弹皮授权目的就是获取用户信息取得用户的唯一以便业务的开发。 我也是一个经历过柴米油盐酱醋茶、尝过酸甜苦辣咸的前端程序员。知道前端的东西入门简单,有深度却很难;表似好看无比的应用,其实背后逻辑复杂,然而要想成长的更快,一定要学会站在巨人的肩膀上,学以师技以自长。所以一些经验非常可贵,在此我想和大家分享一下我的经验...

    fsmStudy 评论0 收藏0
  • [ 一起学React系列 -- 0 ] React技术学习路线

    摘要:的出现真可谓是前端界的福音,正与之宗旨所说,。据统计,目前世界上有的项目使用了。技术栈学习路线直到前段时间笔者的朋友给推荐了一个,真是欣喜若狂也更加坚定了自己在继续前进的想法。这是一个外国友人总结的一套技术栈学习路线,先给传送门。 我相信点进来的同学都是冲着标题来的,当然本文也不会让各位失望。不过在正式介绍标题所述的内容之前,我们不妨先放下技术,一起回顾下自己做前端技术的心路历程。 前...

    Java3y 评论0 收藏0

发表评论

0条评论

qiangdada

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<