美文网首页
Vue组件化设计启发

Vue组件化设计启发

作者: 夏海峰 | 来源:发表于2020-06-06 23:25 被阅读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!!!

    相关文章

      网友评论

          本文标题:Vue组件化设计启发

          本文链接:https://www.haomeiwen.com/subject/byzftktx.html