标签 vue 下的文章

Thumb

移动端网页点击事件延时的解决办法

最近在一个Vue的项目中做了个虚拟键盘,结果遇到了点击延时问题。

第一反应,但是是去找 fastclick 的解决法案。但是发现在Vue项目中,并没有什么卵用~似乎是与Vue的点击事件有冲突,没时间也就懒得深入研究了。

接着搜到了一个 vue-tap 的项目,一试果然可以。。于是愉快的提交代码,下班嘚瑟去了~

但是。。。(如你们所料)万事都不可能这么简单的就能解决的~第二天又客户拿了一个设备来说点击还是有延时~心中还怀疑是否缓存的问题。结果怎么调试都还是有延时。。。(心中的草泥马已经无法压抑~)

正在纳闷的时候,突然想到,既然点击时间有延时,那我直接监听touchstart事件呢?毕竟是个虚拟键盘,并不需要只要能实现“点击”的效果就行。于是动手改了代码,一测试,果然。。。问题迎!刃!而!解!

回头再想想整个过程,我们在处理问题的时候,往往会将问题扩大化,而很多问题也许只需要换个思路,简单的改动就能解决~

代码就不上了,无非就是 @click="xxx" 改成 @touchstart="xxx" 而已~

Thumb

Vue2.0源码阅读笔记--双向绑定实现原理

作者:wj704 出处:http://www.cnblogs.com/wj204/p/6423478.html

一、实现双向绑定的做法

前端MVVM最令人激动的就是双向绑定机制了,实现双向数据绑定的做法大致有如下三种:

1.发布者-订阅者模式(backbone.js)

思路:使用自定义的data属性在HTML代码中指明绑定。所有绑定起来的JavaScript对象以及DOM元素都将“订阅”一个发布者对象。任何时候如果JavaScript对象或者一个HTML输入字段被侦测到发生了变化,我们将代理事件到发布者-订阅者模式,这会反过来将变化广播并传播到所有绑定的对象和元素。

2.脏值检查(angular.js)

思路:angular.js 是通过脏值检测的方式比对数据是否有变更,来决定是否更新视图,最简单的方式就是通过 setInterval() 定时轮询检测数据变动,angular只有在指定的事件触发时进入脏值检测,大致如下:
DOM事件,譬如用户输入文本,点击按钮等。( ng-click )
XHR响应事件 ( $http )
浏览器Location变更事件 ( $location )
Timer事件( $timeout , $interval )
执行 $digest() 或 $apply()

3.数据劫持(Vue.js)

思路: vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
由此可见,Object.defineProperty() 这个API是Vue实现双向数据绑定的关键,我们先简单了解下这个API,了解更多戳这里

Continue reading

Thumb

Vue下字符串转换为JSX方法

最近在群里看到有问到这个问题,然后自己又正好review到这部分的文档,就当作一个需求,做了一番研究,纪录一下。

需求:

将类似<div><span>{{ msg }}</span></div>的字符串直接转换为JSX数据,并挂载到vm中,以减少JS的代码量和复杂度(这应该也是Vue支持JSX的初衷吧)

解决:

文档可以看到,我们并不能直接把字符串变量拿来当JSX语法使用。不过幸运的是Vue提供了一个全局的compile方法,这个方法的作用就是在render函数中编译模板字符串,正如官方的例子:

var res = Vue.compile('<div><span>{{ msg }}</span></div>')
new Vue({
  data: {
        msg: 'hello'
  },
  render: res.render,
  staticRenderFns: res.staticRenderFns
})

我们可以将这段代码封装成一个专门用来解析的组件,就可以在需要时候使用了

const JSX = Vue.component('jsx', {
  render: function (h) {
    return Vue.compile(this.jsx).render.apply(this, arguments)
  },
  props: [
    'jsx'
  ]
})

总结:

如果你不需要解析一些变量,那么上面的代码就足够了。但是像上文所列的需求来看的话,你会发现msg这个变量没能解析出来,因为JSX这个组件里找不到msg变量,所以只能再增加个prop参数。不过这就牵扯出一个问题,有几个变量就要增加几个prop,这个目前误解(谁有好的解决方案,欢迎告知)

完整代码:

const JSX = Vue.component('jsx', {
  render: function (h) {
    return Vue.compile(this.jsx).render.apply(this, arguments)
  },
  props: [
    'jsx',
    'msg'
  ]
})

new Vue({
  el: '#app',
  data () {
    return {
      msg: 'hello',
      jsx: '<div>loading...</div>'
    }
  },
  components: {
    JSX
  },
  template: '<JSX :jsx="jsx" :msg="msg" />',
  created () {
    setTimeout(() => {
      this.jsx = '<div><span>{{msg}}</span></div>'
    }, 1000)
  }
})

在线示例:
https://jsfiddle.net/Hpyer/Lxd8mfmf/ (访问慢的自行翻墙)