《Vue.j实战》一书 p126 页练习 1 试做

练习1 : 在update 钩子中支持表达式的更新。

Demo在线浏览

解题:当 update 钩子被调用时,传入钩子中的binding对象的属性 expression,已经是更新后的 表达式了,也即是说,我们始终只能在 update 中访问到更新后的表达式字符串,而无法访问更新前的表达式字符串。

在update钩子中支持表达式的更新,我理解,既是当表达式更新后,即可以访问到当前的表达式字符串,也可以访问到之前的表达式字符串。

即,类似于在 update中,既可以访问到当前值 value, 也可以访问到更新前的 oldvalue。

如果我的解题是正确的,即,当update钩子被调用时,在钩子中,可以分别访问到表达式的当前值,即 binding.expression,此值始终为更新后的表达式字符串;还可以访问到更新前的表达式字符串,这里设定为 prevExp。

Q:如何在update钩子中访问到表达式的旧值呢?

A:利用 data自定义特性。

在绑定 v-test指令的 html 元素上,分别增设了 2 个自定义 data 特性。见下图:

    <div data-id="0" data-first v-test="1*0"></div>

从上面的代码可知,我为绑定了 v-test指令的 div 元素,添加了 2 个自定义特性,一个是 data-id="0",其用途为在 update 钩子中,用来判断 update 钩子,是否为第一次被调用,如是,进行相应操作,如否,则进行其他操作。

另一自定义特性为data-first,未设置值,其用途为在 bind钩子中,用来传递 binding.expression,即表达式的初始值。这样,在update钩子中,通过 el 的 dataset对象,即可访问到表达式的初始值。见下面的代码:

      bind(el, binding, vnode){
        el.dataset.first=binding.expression;
      },

在bind钩子中,为自定义特性first 赋值,如此,在update钩子中,即可访问到表达式的初始值了。

      update(el, binding, vnode){
        if(el.dataset.id++==0){
          var prevExp=el.dataset.first;
          el.dataset.first=binding.expression;
          var currentExp=binding.expression;
          console.log(prevExp);
          console.log(currentExp);
        }
        else{
          prevExp=el.dataset.first;

          currentExp=binding.expression;
          el.dataset.first=binding.expression;
          console.log(prevExp);
          console.log(currentExp);
        }

上面为 update 钩子,留意dataset.id的初始值为 0 ,通过判断其值是否为 0 ,来判断 update 钩子是否为第一次被 调用,如是,则将表达式的初始值赋给变量 prevExp 保存,供后面访问使用。

同时更新dataset.first的值。

如dataset.id不为0,则说明 update 钩子并非第一次被 调用,此时将更新后的dataset.first赋给preExp,同时设置currentExp,再次更新dataset.first的值。

如是,则可在 update 钩子中,同时访问表达式的当前 值 currentExp 和旧值prevExp。

完整代码如下:

<template>
  <div id="app">
    <div data-id="0" data-first v-test="1*0"></div>
  </div>
</template>
<script>

export default {
  data(){
    return{
      
    }
  },
  methods:{
    
  },
  directives:{
    test:{
      bind(el, binding, vnode){
        el.dataset.first=binding.expression;
      },
      update(el, binding, vnode){
        if(el.dataset.id++==0){
          var prevExp=el.dataset.first;
          el.dataset.first=binding.expression;
          var currentExp=binding.expression;
          console.log(prevExp);
          console.log(currentExp);
        }
        else{
          prevExp=el.dataset.first;

          currentExp=binding.expression;
          el.dataset.first=binding.expression;
          console.log(prevExp);
          console.log(currentExp);
        }



        

        console.log('................................');


        
        

        console.log('................................');
      }
    }
  }
}
</script>

 

posted @ 2019-08-13 22:58  sx00xs  阅读(608)  评论(0编辑  收藏  举报