解析Vue示例中的网格组件

源码

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="forGrid.css" type="text/css">
    <script src="node_modules/vue/dist/vue.min.js"></script>
</head>
<body>
<script type="text/x-template" id="grid-template">
    <table>
        <thead>
        <tr>
            <th v-for="key in columns"
                @click="sortBy(key)"
                :class="{ active: sortKey == key }">

                {{ key | capitalize }}

                <span class="arrow" :class="sortOrders[key] > 0 ? 'asc' : 'dsc'"></span>

            </th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="entry in filteredData">
            <td v-for="key in columns">
                {{entry[key]}}
            </td>
        </tr>
        </tbody>
    </table>
</script>
<div id="demo">
    <form id="search">
        Search <input name="query" v-model="searchQuery">
    </form>
    <demo-grid
            :data="gridData"
            :columns="gridColumns"
            :filter-key="searchQuery">
    </demo-grid>
</div>
<script type="text/javascript">
    Vue.component('demo-grid', {
        template: '#grid-template',
        props: {
            data: Array,
            columns: Array,
            filterKey: String
        },
        data() {
            let sortOrders = {}
            this.columns.forEach(key => sortOrders[key] = 1)
            return {
                sortKey: '',
                sortOrders: sortOrders
            }
        },
        computed: {
          filteredData: function () {
              let sortKey = this.sortKey
              let filterKey = this.filterKey && this.filterKey.toLowerCase()
              let order = this.sortOrders[sortKey] || 1
              let data = this.data
              if (filterKey) {
                  data = data.filter(row => {
                      return Object.keys(row).some(
                          key=>{
                              return String(row[key]).toLowerCase().indexOf(filterKey) > -1
                          })
                  })
              }
              if (sortKey) {
                  data = data.slice().sort((a, b) => {
                      a = a[sortKey]
                      b = b[sortKey]
                      return (a === b ? 0:a>b? 1:-1)*order
                  })
              }
              return data
          }
        },
        filters: {
            capitalize: function (str) {
                return str.charAt(0).toUpperCase() + str.slice(1)
            }
        },
        methods: {
            sortBy: function (key) {
                this.sortKey = key
                this.sortOrders[key] = this.sortOrders[key]* -1
            }
        }
    })
    let Demo = new Vue({
        el: '#demo',
        data: {
            searchQuery: '',
            gridColumns: ['name', 'power'],
            gridData: [
                {name: 'Chuck Norris', power: Infinity},
                {name: 'Bruce Lee', power: 9000},
                {name: 'Jackie Chan', power: 7000},
                {name: 'Jet Li', power: 8000}
            ]
        }
    })
</script>
</body>
</html>

部分CSS

th.active {
    color: #fff;
}
th.active .arrow {
    opacity: 1;
}

.arrow {
    display: inline-block;
    vertical-align: middle;
    width: 0;
    height: 0;
    margin-left: 5px;
    opacity: 0.66;
}

.arrow.asc {
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-bottom: 4px solid #fff;
}

.arrow.dsc {
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-top: 4px solid #fff;
}

解析

首先定义了一个Vue,和一个组件
Vue实例中data有三个属性分别是searchQuery, gridColumns,gridData
分别对应的是搜索输入的文本,列名,表数据
分别对应组件中绑定的filter-key,columns,data

@click="sortBy(key)"
sortBy: function (key) {
                this.sortKey = key
                this.sortOrders[key] = this.sortOrders[key]* -1
            }

key是columns中的一个值可能是name或者power
sortKey是组件data中设置的一个属性,即点击时将sortKey绑定到对应的name或者power上
sortOrders对应

let sortOrders = {}
this.columns.forEach(key => sortOrders[key] = 1)

sortOrders本来是一个对象

sortOrders={
'name' : 1,
'power':1
}

点击事件发生后,对应key值的value变为了-1

:class="{ active: sortKey == key }"

遍历两个key值,等于sortKey的赋值class=active,对应到css中

th.active .arrow {
    opacity: 1;
}

表头的箭头透明度为1

{{ key | capitalize }}

是过滤函数

capitalize: function (str) {
                return str.charAt(0).toUpperCase() + str.slice(1)
            }

将key值单词的首个字母大写

<tr v-for="entry in filteredData">
            <td v-for="key in columns">
                {{entry[key]}}
            </td>
        </tr>

filteredData是定义在computed中的计算属性

filteredData: function () {
              let sortKey = this.sortKey
              let filterKey = this.filterKey && this.filterKey.toLowerCase()
              let order = this.sortOrders[sortKey] || 1
              let data = this.data
              if (filterKey) {
                  data = data.filter(row => {
                      return Object.keys(row).some(
                          key=>{
                              return String(row[key]).toLowerCase().indexOf(filterKey) > -1
                          })
                  })
              }
              if (sortKey) {
                  data = data.slice().sort((a, b) => {
                      a = a[sortKey]
                      b = b[sortKey]
                      return (a === b ? 0:a>b? 1:-1)*order
                  })
              }
              return data
          }

如果filterKey存在,也就是输入框有值,对data进行筛选操作,filter对数组中的每一项运行给定函数,对应数组中保留返回true的值,some每一项运行给定函数,对应数组中只要有一个满足就返回true,所以这段if的意思是对data中所有的字段进行遍历,返回只要filterKey存在于任何一个data的字段中的那一行。后一个if是将data根据sortKey和order进行排序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值