IT@大前端Web 前端开发

Vue文档笔记系列——可复用性&组合

2018-06-28  本文已影响16人  从小就很瘦

可复用性&组合

mixins混入

用我的话来解释就是包含了一些组件选项的对象,然后可以在不同的组件中引用。一个例子来演示:

    Vue.component('tooltip', {
      template: `
        <div>
            <button @mouseenter="show" @mouseout="hide">鼠标滑过</button>
            <div v-if="visible">我是内容1</div>
        </div>
      `,
      methods: {
        show: function () {
          this.visible = true
        },
        hide: function () {
          this.visible = false
        }
      },
      data: function () {
        return {
          visible: false
        }
      }
    })

    Vue.component('popup', {
      template: `
      <div>
        <button @click="toggle">点击切换</button>
        <button @click="hide">关闭</button>
        <div v-if="visible">我是内容2</div>
      </div>`,
      data: function () {
        return {
          visible: false
        }
      },
      methods: {
        toggle: function () {
          this.visible = !this.visible
        },
        hide: function () {
          this.visible = false
        }
      }
    })
    new Vue({
      el: '#app'
    })
  <div id="app">
    <tooltip></tooltip>
    <popup></popup>
  </div>

例子中两个组件,重复的功能太多,比如data中的visible,methods中的hide方法。此时我们要让代码变得简约,就用到了mixins,定义一个对象,然后在组件中用数组来引入。代码改进如下:

    var myMix = {
      methods: {
        show: function () {
          this.visible = true
        },
        hide: function () {
          this.visible = false
        },
        toggle: function () {
          this.visible = !this.visible
        }
      },
      data: function () {
        return {
          visible: false
        }
      }
    };

    Vue.component('tooltip', {
      template: `
        <div>
            <button @mouseenter="show" @mouseout="hide">鼠标滑过</button>
            <div v-if="visible">我是内容1</div>
        </div>
      `,
      mixins: [myMix]
    })

    Vue.component('popup', {
      template: `
      <div>
        <button @click="toggle">点击切换</button>
        <button @click="hide">关闭</button>
        <div v-if="visible">我是内容2</div>
      </div>`,
      mixins: [myMix]
    })

值得注意的是,在组件中定义和mixins相同的选项时,会覆盖mixins中的选项。比如我在popul组件中定义data,默认visible:ture,则会覆盖掉mixins中默认的visible:false.

自定义指令

跟自定义组件类似,还是用一个例子来看比较明白:

  <div id="app">
    <div v-pin="pinned" class="card">
      <button @click="pinned = !pinned">切换</button>
      我是相片
    </div>
    Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dolor suscipit ad consequuntur quia ipsam eius consequatur eum
    sint, minima adipisci nemo error, delectus quaerat sit magni non praesentium maiores? Voluptas. Lorem ipsum dolor sit
    amet consectetur adipisicing elit. Ipsa, molestias, a dicta commodi harum, ducimus iusto quo natus eos reprehenderit
    est ipsam nemo error tempora? Reprehenderit iure ipsum at similique! Lorem, ipsum dolor sit amet consectetur adipisicing
    elit. Asperiores saepe iusto dolore, magnam ex earum illo. Non, necessitatibus dignissimos libero sed dolorem ipsa ea
    sunt quo optio omnis praesentium atque. Lorem ipsum dolor sit amet consectetur adipisicing elit. Iste quibusdam ratione,
    quisquam dolorem doloribus delectus deserunt ab sit error placeat explicabo, ea, animi magnam. Ad, aperiam temporibus.
    Eos, exercitationem laborum. Lorem ipsum dolor, sit amet consectetur adipisicing elit. Accusamus fugiat incidunt sit
    deserunt consequatur molestias dicta praesentium corrupti autem nostrum dolorum facilis, quidem ipsa obcaecati ipsum
    saepe? Aliquid, inventore suscipit. Lorem, ipsum dolor sit amet consectetur adipisicing elit. Suscipit voluptatem debitis
    delectus veritatis, laboriosam repudiandae, ea non minima ipsam eligendi nam tempora porro id quae maxime doloribus nulla,
    accusantium animi. Lorem ipsum dolor sit amet consectetur, adipisicing elit. Iste temporibus molestias ratione. Porro
    itaque aperiam vero, voluptatum natus animi adipisci necessitatibus, quidem ipsam possimus molestias officiis, fugit
    velit quibusdam soluta! Lorem ipsum dolor sit amet consectetur adipisicing elit. Perferendis minus commodi architecto
    consectetur nesciunt totam sit aspernatur quas placeat fugit aut esse dolorum sed doloribus fugiat, nihil hic possimus
    rerum.
  </div>
.card {
      background: #ccc;
      padding: 15px;
      margin: 15px;
      width: 80px;
      height: 80px;
      text-align: center;
    }
    Vue.directive('pin', function (el, binding) {
      var val = binding.value;
      if (val) {
        el.style.position = 'fixed';
      } else {
        el.style.position = 'static'
      }
    })
    new Vue({
      el: '#app',
      data: {
        pinned: false
      }
    })

在本例子中,点击按钮就可以切换相片的position属性。
解释一下,例子中pin是自定义指令的名字,在全局中用v-pin来表示。函数中el代表指令所在的DOM元素,binding是指令的值的一些属性,这里直接从官网上copy了:

好,比如我们在指令上添加一些修饰符:

  <div v-pin:true.bottom.right="pinned" class="card">
 Vue.directive('pin', function (el, binding) {
      var val = binding.value;
      var position = binding.modifiers;
      var warning = binding.arg;
      if (val) {
        el.style.position = 'fixed';

        for(var key in position) {
          if(position[key]){
            el.style[key] = '20px'
          }
        }
        if (warning === 'true') {
          el.style.background = 'red'
        }
      } else {
        el.style.position = 'static';
        el.style.background = '#ccc'
      }
    })

这样点击按钮,相片就变为红色,位置移到了右下方。

过滤器filter

过滤器其实就是作一个优化的作用。它可以用在双花括号插值和 v-bind 表达式。来个例子吧:

  <div id="app">
    <input type="text" v-model="length">毫米   {{length | meter}}
    <br>
    <input type="text" v-model="price"> {{price | current}}
  </div>
    Vue.filter('meter', function (val, unit) {
      var val = val || 0;
      var unit = unit || '米';
      return (val / 1000).toFixed(3) + unit
    })
    Vue.filter('current', function (val, unit) {
      var val = val || 0;
      var unit = unit || '元';
      return val + unit
    })
    new Vue({
      el: '#app',
      data: {
        price: 10,
        length: 10
      }
    })

第二个小例子中,默认的单位就是元,如果我们把过滤器后面加个括号,加了美元符号。就可以变更视图。

 <input type="text" v-model="price"> {{price | current('$')}}

简单的一些单位换算可以用过滤器,如果比较复杂, 最好还是用计算属性computed

上一篇 下一篇

猜你喜欢

热点阅读