Vue组件化设计启发

2020-06-06  本文已影响0人  夏海峰

现代化MVVM框架两大主要特点,分别是响应式和组件化。前者在声明式、虚拟DOM、Diff运算的基础上,实现了模型与视图的同步更新;后者犹如搭积木一样,把UI需求、业务需求剥离(封装)成一个个方便复用的组件。这为复杂的数据化应用提供了高效的解决方案。

在使用类似MVVM框架的时候,一定要理解响应式、声明式等底层原理。有了这样的理论基础,还要能够科学地良好地快速地进行组件设计。组件设计常与数据息息相关,相同的需求、不同的数据结构,常常会导致不同的组件设计方案。可以这么讲,数据结构是影响组件设计的最主要因素。

组件化(组件设计)特别能够体现出前端开发者的能力水平。我个人习惯把组件划分为两类:一类是纯UI组件,根据后端数据进行UI渲染,几乎不涉及到数据操作;另一类是业务组件,常常需要涉及到业务数据的处理。我个人认为一个合格的前端开发者,必须要具备良好的数据思维。

下面给出两个小例子:不一定能充分说明问题,但仍然能体现出数据结构对于组件设计的重要影响,大家可以重点关注其中声明式数据结构的差异,从而导致的组件设计思路的不同。希望能够启发初级前端开发者认识到数据之于组件的重要性。

例(1)
<!DOCTYPE html>
<html lang="en">
<head>
  <style>
    .item {
      display: inline-block;
      background: #eee; padding: 5px 10px;
      margin: 10px; cursor: pointer;
    }
    .on {
      color: orange; font-weight: bold;
    }
  </style>
</head>
<body>
  <div id='app'>
    <div>标赔</div>
    <my-row :list='list1' v-model='index'></my-row>
    <div>让球</div>
    <my-row :list='list2' v-model='index'></my-row>
    <my-row :list='list3' v-model='index'></my-row>

    <h2>你选择的结果是:<span v-text='rate.title'></span></h2>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script type="text/javascript">
  // my-row表示demo效果中的“一行”
  Vue.component('my-row', {
    props: {
      list: {
        type: Array,
        required: true
      },
      value: {
        type: Number,
        required: true
      }
    },
    template: `
      <div>
        <span
          :class="{'on': item.id == value}"
          class='item'
          v-for='item in list'
          :key='item.id'
          v-text='item.title'
          @click='change(item)'>
        </span>
      </div>
    `,
    methods: {
      change(item) {
        this.$emit('input', item.id)
      }
    }
  })

  var app = new Vue({
    el: '#app',
    data: {
      list1: [{id:1,title:'1.01'}, {id:2,title: '1.02'}, {id:3,title:'1.03'}, {id:4,title: '1.04'}],
      list2: [{id:5,title:'1.05'}, {id:6,title: '1.06'}, {id:7,title:'1.07'}, {id:8,title: '1.08'}],
      list3: [{id:9,title:'1.09'}, {id:10,title: '1.10'}, {id:11,title:'1.11'}, {id:12,title: '1.12'}],
      index: 1,
    },
    computed: {
      rate: function() {
        return [...this.list1, ...this.list2, ...this.list3].find(ele=>ele.id==this.index)
      }
    }
  })
  </script>
</body>
</html>

例(2)
<!DOCTYPE html>
<html lang="en">
<head>
  <style>
    .item {
      display: inline-block;
      background: #eee; padding: 5px 10px;
      margin: 10px; cursor: pointer;
    }
    .on {
      color: orange; font-weight: bold;
    }
  </style>
</head>
<body>
  <div id='app'>
    <my-bet :list='list' v-model='index'></my-bet>
    <h2>你选择的结果是:<span v-text='rate.title'></span></h2>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script type="text/javascript">
  Vue.component('my-bet', {
    props: {
      list: {
        type: Array,
        required: true
      },
      value: {
        type: Number,
        required: true
      }
    },
    template: `
    <div>
      <div v-for='(item,index) in list' :key='index'>
        <div v-text='item.title'></div>
        <div v-for='(item,index) in item.list' :key='index'>
          <span class='item' v-text='item.title'></span>
          <span
            class='item'
            v-for='item in item.list'
            v-text='item.title'
            :key='item.id'
            :class='{"on":value==item.id}'
            @click='change(item)'>
          </span>
        </div>
      </div>
    </div>
    `,
    methods: {
      change: function(item) {
        this.$emit('input', item.id)
      }
    }
  })

  var app = new Vue({
    el: '#app',
    data: {
      list: [
        {
          title: '标赔',
          list: [
            {
              title: 'A',
              list: [{id:1,title:'1.01'}, {id:2,title: '1.02'}, {id:3,title:'1.03'}]
            }
          ]
        },
        {
          title: '让球',
          list: [
            {
              title: 'B',
              list: [{id:4,title:'1.04'}, {id:5,title: '1.05'}, {id:6,title:'1.06'}],
            },
            {
              title: 'C',
              list: [{id:7,title:'1.07'}, {id:8,title: '1.08'}, {id:9,title:'1.09'}]
            }
          ]
        }
      ],
      index: 1
    },
    computed: {
      rate: function() {
        var rate = 0
        this.list.map(ele=>{
          ele.list.map(ele=>{
            ele.list.map(ele=>{
              if(ele.id == this.index) rate = ele
            })
          })
        })
        return rate
      }
    }
  })
  </script>
</body>
</html>

END!!!

上一篇下一篇

猜你喜欢

热点阅读