Commit 99d0429e276f6371d22bcc8279c4fb4a9708218b

Authored by 梁灏
1 parent 2ac208b9

update Button & Table Cell

Button add custom event @click,you can use @click in i-button now;
Table Cell support data from content
examples/routers/table.vue
1   -<!--<template>-->
2   - <!--<Card>-->
3   - <!--<Table border :content="self" :columns="columns7" :data="data6"></Table>-->
4   - <!--</Card>-->
5   -<!--</template>-->
6   -<!--<script>-->
7   - <!--export default {-->
8   - <!--data () {-->
9   - <!--return {-->
10   - <!--self: this,-->
11   - <!--columns7: [-->
12   - <!--{-->
13   - <!--title: '姓名',-->
14   - <!--key: 'name',-->
15   - <!--render (row, column, index) {-->
16   - <!--return `<Icon type="person"></Icon> <strong>${row.name}</strong>`;-->
17   - <!--}-->
18   - <!--},-->
19   - <!--{-->
20   - <!--title: '年龄',-->
21   - <!--key: 'age'-->
22   - <!--},-->
23   - <!--{-->
24   - <!--title: '地址',-->
25   - <!--key: 'address'-->
26   - <!--},-->
27   - <!--{-->
28   - <!--title: '操作',-->
29   - <!--key: 'action',-->
30   - <!--width: 150,-->
31   - <!--align: 'center',-->
32   - <!--render (row, column, index) {-->
33   - <!--return `<i-button type="primary" size="small" @click.native="show(${index})">查看</i-button> <i-button type="error" size="small" @click.native="remove(${index})">删除</i-button>`;-->
34   - <!--}-->
35   - <!--}-->
36   - <!--],-->
37   - <!--data6: [-->
38   - <!--{-->
39   - <!--name: '王小明',-->
40   - <!--age: 18,-->
41   - <!--address: '北京市朝阳区芍药居'-->
42   - <!--},-->
43   - <!--{-->
44   - <!--name: '张小刚',-->
45   - <!--age: 25,-->
46   - <!--address: '北京市海淀区西二旗'-->
47   - <!--},-->
48   - <!--{-->
49   - <!--name: '李小红',-->
50   - <!--age: 30,-->
51   - <!--address: '上海市浦东新区世纪大道'-->
52   - <!--},-->
53   - <!--{-->
54   - <!--name: '周小伟',-->
55   - <!--age: 26,-->
56   - <!--address: '深圳市南山区深南大道'-->
57   - <!--}-->
58   - <!--]-->
59   - <!--}-->
60   - <!--},-->
61   - <!--methods: {-->
62   - <!--show (index) {-->
63   - <!--console.log(`姓名:${this.data6[index].name}<br>年龄:${this.data6[index].age}<br>地址:${this.data6[index].address}`)-->
64   - <!--},-->
65   - <!--remove (index) {-->
66   - <!--this.data6.splice(index, 1);-->
67   - <!--}-->
68   - <!--},-->
69   - <!--mounted () {-->
70   - <!--setTimeout(() => {-->
71   -<!--// this.data6.splice(2, 1);-->
72   - <!--}, 3000)-->
73   - <!--}-->
74   - <!--}-->
75   -<!--</script>-->
76   -
77   -
78 1 <template>
79   - <div>
80   - <i-table border :columns="columns6" :data="data5"></i-table>
81   - </div>
  2 + <i-table border :content="self" :columns="columns7" :data="data6"></i-table>
82 3 </template>
83 4 <script>
84 5 export default {
85 6 data () {
86 7 return {
87   - columns6: [
88   - {
89   - title: '日期',
90   - key: 'date'
91   - },
  8 + info: '123',
  9 + self: this,
  10 + columns7: [
92 11 {
93 12 title: '姓名',
94   - key: 'name'
  13 + key: 'name',
  14 +// render (row, column, index) {
  15 +// return `<Icon type="person"></Icon> <strong>${row.name}</strong>`;
  16 +// }
95 17 },
96 18 {
97 19 title: '年龄',
98   - key: 'age',
99   - filters: [
100   - {
101   - label: '大于25岁',
102   - value: 1
103   - },
104   - {
105   - label: '小于25岁',
106   - value: 2
107   - }
108   - ],
109   - filterMultiple: false,
110   - filterMethod (value, row) {
111   - if (value === 1) {
112   - return row.age > 25;
113   - } else if (value === 2) {
114   - return row.age < 25;
115   - }
116   - }
  20 + key: 'age'
117 21 },
118 22 {
119 23 title: '地址',
120   - key: 'address',
121   - filters: [
122   - {
123   - label: '北京',
124   - value: '北京'
125   - },
126   - {
127   - label: '上海',
128   - value: '上海'
129   - },
130   - {
131   - label: '深圳',
132   - value: '深圳'
133   - }
134   - ],
135   - filterMethod (value, row) {
136   - return row.address.indexOf(value) > -1;
  24 + key: 'address'
  25 + },
  26 + {
  27 + title: '操作',
  28 + key: 'action',
  29 + width: 150,
  30 + align: 'center',
  31 + render (row, column, index) {
  32 + return `<i-button type="primary" size="small" @click="show(${index})">{{ info }}查看</i-button> <i-button type="error" size="small" @click="remove(${index})">删除</i-button>`;
137 33 }
138 34 }
139 35 ],
140   - data5: [
  36 + data6: [
141 37 {
142 38 name: '王小明',
143 39 age: 18,
144   - address: '北京市朝阳区芍药居',
145   - date: '2016-10-03'
146   - },
147   - {
148   - name: '张小刚',
149   - age: 25,
150   - address: '北京市海淀区西二旗',
151   - date: '2016-10-01'
  40 + address: '北京市朝阳区芍药居'
152 41 },
153   - {
154   - name: '李小红',
155   - age: 30,
156   - address: '上海市浦东新区世纪大道',
157   - date: '2016-10-02'
158   - },
159   - {
160   - name: '周小伟',
161   - age: 26,
162   - address: '深圳市南山区深南大道',
163   - date: '2016-10-04'
164   - }
  42 +// {
  43 +// name: '张小刚',
  44 +// age: 25,
  45 +// address: '北京市海淀区西二旗'
  46 +// },
  47 +// {
  48 +// name: '李小红',
  49 +// age: 30,
  50 +// address: '上海市浦东新区世纪大道'
  51 +// },
  52 +// {
  53 +// name: '周小伟',
  54 +// age: 26,
  55 +// address: '深圳市南山区深南大道'
  56 +// }
165 57 ]
166 58 }
  59 + },
  60 + computed: {
  61 + dddfff () {
  62 + return this.info
  63 + }
  64 + },
  65 + methods: {
  66 + show (index) {
  67 + this.$Modal.info({
  68 + title: '用户信息',
  69 + content: `姓名:${this.data6[index].name}<br>年龄:${this.data6[index].age}<br>地址:${this.data6[index].address}`
  70 + })
  71 + },
  72 + remove (index) {
  73 + this.data6.splice(index, 1);
  74 + }
  75 + },
  76 + mounted () {
  77 + setTimeout(() => {
  78 + this.info = '444';
  79 + }, 3000);
167 80 }
168 81 }
169 82 </script>
... ...
examples/routers/upload.vue
  1 +<!--<template>-->
  2 + <!--<div>-->
  3 + <!--<div class="demo-upload-list" v-for="item in uploadList">-->
  4 + <!--<template v-if="item.status === 'finished'">-->
  5 + <!--<img :src="item.url">-->
  6 + <!--<div class="demo-upload-list-cover">-->
  7 + <!--<Icon type="ios-eye-outline" @click.native="handleView(item.name)"></Icon>-->
  8 + <!--<Icon type="ios-trash-outline" @click.native="handleRemove(item)"></Icon>-->
  9 + <!--</div>-->
  10 + <!--</template>-->
  11 + <!--<template v-else>-->
  12 + <!--<i-progress v-if="item.showProgress" :percent="item.percentage" hide-info></i-progress>-->
  13 + <!--</template>-->
  14 + <!--</div>-->
  15 + <!--<Upload-->
  16 + <!--ref="upload"-->
  17 + <!--:show-upload-list="false"-->
  18 + <!--:default-file-list="defaultList"-->
  19 + <!--:on-success="handleSuccess"-->
  20 + <!--:format="['jpg','jpeg','png']"-->
  21 + <!--:max-size="2048"-->
  22 + <!--:on-format-error="handleFormatError"-->
  23 + <!--:on-exceeded-size="handleMaxSize"-->
  24 + <!--@on-progress="handleProgress"-->
  25 + <!--:before-upload="handleBeforeUpload"-->
  26 + <!--multiple-->
  27 + <!--type="drag"-->
  28 + <!--action="//jsonplaceholder.typicode.com/posts/"-->
  29 + <!--style="display: inline-block;width:58px;">-->
  30 + <!--<div style="width: 58px;height:58px;line-height: 58px;">-->
  31 + <!--<Icon type="camera" size="20"></Icon>-->
  32 + <!--</div>-->
  33 + <!--</Upload>-->
  34 + <!--{{ visible }}-->
  35 + <!--</div>-->
  36 +<!--</template>-->
  37 +<!--<script>-->
  38 + <!--export default {-->
  39 + <!--data () {-->
  40 + <!--return {-->
  41 + <!--defaultList: [-->
  42 + <!--{-->
  43 + <!--'name': 'a42bdcc1178e62b4694c830f028db5c0',-->
  44 + <!--'url': 'https://o5wwk8baw.qnssl.com/a42bdcc1178e62b4694c830f028db5c0/avatar'-->
  45 + <!--},-->
  46 + <!--{-->
  47 + <!--'name': 'bc7521e033abdd1e92222d733590f104',-->
  48 + <!--'url': 'https://o5wwk8baw.qnssl.com/bc7521e033abdd1e92222d733590f104/avatar'-->
  49 + <!--}-->
  50 + <!--],-->
  51 + <!--imgName: '',-->
  52 + <!--visible: false,-->
  53 + <!--uploadList: []-->
  54 + <!--}-->
  55 + <!--},-->
  56 + <!--computed: {-->
  57 +<!--// uploadList () {-->
  58 +<!--// return this.$refs.upload ? this.$refs.upload.fileList : [];-->
  59 +<!--// }-->
  60 + <!--},-->
  61 + <!--watch: {-->
  62 +
  63 + <!--},-->
  64 + <!--mounted () {-->
  65 + <!--this.uploadList = this.$refs.upload.fileList;-->
  66 +<!--// console.log(this.$refs.upload.fileList)-->
  67 + <!--},-->
  68 + <!--methods: {-->
  69 + <!--handleView (name) {-->
  70 + <!--this.imgName = name;-->
  71 + <!--this.visible = true;-->
  72 + <!--},-->
  73 + <!--handleRemove (file) {-->
  74 + <!--// 从 upload 实例删除数据-->
  75 + <!--const fileList = this.$refs.upload.fileList;-->
  76 + <!--this.$refs.upload.fileList.splice(fileList.indexOf(file), 1);-->
  77 + <!--},-->
  78 + <!--handleSuccess (res, file) {-->
  79 + <!--// 因为上传过程为实例,这里模拟添加 url-->
  80 + <!--file.url = 'https://o5wwk8baw.qnssl.com/7eb99afb9d5f317c912f08b5212fd69a/avatar';-->
  81 + <!--file.name = '7eb99afb9d5f317c912f08b5212fd69a';-->
  82 + <!--},-->
  83 + <!--handleFormatError (file) {-->
  84 + <!--this.$Notice.warning({-->
  85 + <!--title: '文件格式不正确',-->
  86 + <!--desc: '文件 ' + file.name + ' 格式不正确,请上传 jpg 或 png 格式的图片。'-->
  87 + <!--});-->
  88 + <!--},-->
  89 + <!--handleMaxSize (file) {-->
  90 + <!--this.$Notice.warning({-->
  91 + <!--title: '超出文件大小限制',-->
  92 + <!--desc: '文件 ' + file.name + ' 太大,不能超过 2M。'-->
  93 + <!--});-->
  94 + <!--},-->
  95 + <!--handleBeforeUpload () {-->
  96 + <!--const check = this.uploadList.length < 5;-->
  97 + <!--if (!check) {-->
  98 + <!--this.$Notice.warning({-->
  99 + <!--title: '最多只能上传 5 张图片。'-->
  100 + <!--});-->
  101 + <!--}-->
  102 + <!--return check;-->
  103 + <!--},-->
  104 + <!--handleProgress (s) {-->
  105 + <!--console.log(s)-->
  106 + <!--}-->
  107 + <!--}-->
  108 + <!--}-->
  109 +<!--</script>-->
  110 +<!--<style>-->
  111 + <!--.demo-upload-list{-->
  112 + <!--display: inline-block;-->
  113 + <!--width: 60px;-->
  114 + <!--height: 60px;-->
  115 + <!--text-align: center;-->
  116 + <!--line-height: 60px;-->
  117 + <!--border: 1px solid transparent;-->
  118 + <!--border-radius: 4px;-->
  119 + <!--overflow: hidden;-->
  120 + <!--background: #fff;-->
  121 + <!--position: relative;-->
  122 + <!--box-shadow: 0 1px 1px rgba(0,0,0,.2);-->
  123 + <!--margin-right: 4px;-->
  124 + <!--}-->
  125 + <!--.demo-upload-list img{-->
  126 + <!--width: 100%;-->
  127 + <!--height: 100%;-->
  128 + <!--}-->
  129 + <!--.demo-upload-list-cover{-->
  130 + <!--display: none;-->
  131 + <!--position: absolute;-->
  132 + <!--top: 0;-->
  133 + <!--bottom: 0;-->
  134 + <!--left: 0;-->
  135 + <!--right: 0;-->
  136 + <!--background: rgba(0,0,0,.6);-->
  137 + <!--}-->
  138 + <!--.demo-upload-list:hover .demo-upload-list-cover{-->
  139 + <!--display: block;-->
  140 + <!--}-->
  141 + <!--.demo-upload-list-cover i{-->
  142 + <!--color: #fff;-->
  143 + <!--font-size: 20px;-->
  144 + <!--cursor: pointer;-->
  145 + <!--margin: 0 2px;-->
  146 + <!--}-->
  147 +<!--</style>-->
  148 +
  149 +
1 150 <template>
2 151 <div>
3   - <div class="demo-upload-list" v-for="item in uploadList">
4   - <template v-if="item.status === 'finished'">
5   - <img :src="item.url">
6   - <div class="demo-upload-list-cover">
7   - <Icon type="ios-eye-outline" @click.native="handleView(item.name)"></Icon>
8   - <Icon type="ios-trash-outline" @click.native="handleRemove(item)"></Icon>
9   - </div>
10   - </template>
11   - <template v-else>
12   - <i-progress v-if="item.showProgress" :percent="item.percentage" hide-info></i-progress>
13   - </template>
14   - </div>
15   - <Upload
16   - ref="upload"
17   - :show-upload-list="false"
18   - :default-file-list="defaultList"
19   - :on-success="handleSuccess"
20   - :format="['jpg','jpeg','png']"
21   - :max-size="2048"
22   - :on-format-error="handleFormatError"
23   - :on-exceeded-size="handleMaxSize"
24   - @on-progress="handleProgress"
25   - :before-upload="handleBeforeUpload"
26   - multiple
27   - type="drag"
28   - action="//jsonplaceholder.typicode.com/posts/"
29   - style="display: inline-block;width:58px;">
30   - <div style="width: 58px;height:58px;line-height: 58px;">
31   - <Icon type="camera" size="20"></Icon>
32   - </div>
  152 + <Upload action="//jsonplaceholder.typicode.com/posts/" :before-upload="handleBeforeUpload" ref="file">
  153 + <i-button type="ghost" icon="ios-cloud-upload-outline">选择文件</i-button>
33 154 </Upload>
34   - {{ visible }}
  155 + <i-button @click.native="handleUpload">上传</i-button>
35 156 </div>
36 157 </template>
37 158 <script>
38 159 export default {
39 160 data () {
40 161 return {
41   - defaultList: [
42   - {
43   - 'name': 'a42bdcc1178e62b4694c830f028db5c0',
44   - 'url': 'https://o5wwk8baw.qnssl.com/a42bdcc1178e62b4694c830f028db5c0/avatar'
45   - },
46   - {
47   - 'name': 'bc7521e033abdd1e92222d733590f104',
48   - 'url': 'https://o5wwk8baw.qnssl.com/bc7521e033abdd1e92222d733590f104/avatar'
49   - }
50   - ],
51   - imgName: '',
52   - visible: false,
53   - uploadList: []
  162 + file: null
54 163 }
55 164 },
56   - computed: {
57   -// uploadList () {
58   -// return this.$refs.upload ? this.$refs.upload.fileList : [];
59   -// }
60   - },
61   - watch: {
62   -
63   - },
64   - mounted () {
65   - this.uploadList = this.$refs.upload.fileList;
66   -// console.log(this.$refs.upload.fileList)
67   - },
68 165 methods: {
69   - handleView (name) {
70   - this.imgName = name;
71   - this.visible = true;
72   - },
73   - handleRemove (file) {
74   - // 从 upload 实例删除数据
75   - const fileList = this.$refs.upload.fileList;
76   - this.$refs.upload.fileList.splice(fileList.indexOf(file), 1);
77   - },
78   - handleSuccess (res, file) {
79   - // 因为上传过程为实例,这里模拟添加 url
80   - file.url = 'https://o5wwk8baw.qnssl.com/7eb99afb9d5f317c912f08b5212fd69a/avatar';
81   - file.name = '7eb99afb9d5f317c912f08b5212fd69a';
  166 + handleBeforeUpload (file) {
  167 + this.file = file;
  168 + return false;
82 169 },
83   - handleFormatError (file) {
84   - this.$Notice.warning({
85   - title: '文件格式不正确',
86   - desc: '文件 ' + file.name + ' 格式不正确,请上传 jpg 或 png 格式的图片。'
87   - });
88   - },
89   - handleMaxSize (file) {
90   - this.$Notice.warning({
91   - title: '超出文件大小限制',
92   - desc: '文件 ' + file.name + ' 太大,不能超过 2M。'
93   - });
94   - },
95   - handleBeforeUpload () {
96   - const check = this.uploadList.length < 5;
97   - if (!check) {
98   - this.$Notice.warning({
99   - title: '最多只能上传 5 张图片。'
100   - });
101   - }
102   - return check;
103   - },
104   - handleProgress (s) {
105   - console.log(s)
  170 + handleUpload () {
  171 + this.$refs.file.post(this.file);
106 172 }
107 173 }
108 174 }
109 175 </script>
110   -<style>
111   - .demo-upload-list{
112   - display: inline-block;
113   - width: 60px;
114   - height: 60px;
115   - text-align: center;
116   - line-height: 60px;
117   - border: 1px solid transparent;
118   - border-radius: 4px;
119   - overflow: hidden;
120   - background: #fff;
121   - position: relative;
122   - box-shadow: 0 1px 1px rgba(0,0,0,.2);
123   - margin-right: 4px;
124   - }
125   - .demo-upload-list img{
126   - width: 100%;
127   - height: 100%;
128   - }
129   - .demo-upload-list-cover{
130   - display: none;
131   - position: absolute;
132   - top: 0;
133   - bottom: 0;
134   - left: 0;
135   - right: 0;
136   - background: rgba(0,0,0,.6);
137   - }
138   - .demo-upload-list:hover .demo-upload-list-cover{
139   - display: block;
140   - }
141   - .demo-upload-list-cover i{
142   - color: #fff;
143   - font-size: 20px;
144   - cursor: pointer;
145   - margin: 0 2px;
146   - }
147   -</style>
... ...
src/components/button/button.vue
1 1 <template>
2   - <button :type="htmlType" :class="classes" :disabled="disabled">
  2 + <button :type="htmlType" :class="classes" :disabled="disabled" @click="handleClick">
3 3 <Icon class="ivu-load-loop" type="load-c" v-if="loading"></Icon>
4 4 <Icon :type="icon" v-if="icon && !loading"></Icon>
5 5 <span v-if="showSlot" ref="slot"><slot></slot></span>
... ... @@ -64,8 +64,13 @@
64 64 ];
65 65 }
66 66 },
  67 + methods: {
  68 + handleClick (event) {
  69 + this.$emit('click', event);
  70 + }
  71 + },
67 72 mounted () {
68   - this.showSlot = this.$refs.slot.innerHTML.replace(/\n/g, '').replace(/<!--[\w\W\r\n]*?-->/gmi, '') !== '';
  73 + this.showSlot = this.$slots.default !== undefined;
69 74 }
70 75 };
71 76 </script>
... ...
src/components/table/cell.vue
... ... @@ -52,36 +52,32 @@
52 52 const template = this.column.render(this.row, this.column, this.index);
53 53 const cell = document.createElement('div');
54 54 cell.innerHTML = template;
55   -// const _oldParentChildLen = $parent.$children.length;
56   -// const _newParentChildLen = $parent.$children.length;
57   -// if (_oldParentChildLen !== _newParentChildLen) { // if render normal html node, do not tag
58   -// this.uid = $parent.$children[$parent.$children.length - 1]._uid; // tag it, and delete when data or columns update
59   -// }
  55 +
60 56 this.$el.innerHTML = '';
61 57 let methods = {};
62 58 Object.keys($parent).forEach(key => {
63   - const func = $parent[`${key}`];
  59 + const func = $parent[key];
64 60 if (typeof(func) === 'function' && func.name === 'boundFn') {
65   - methods[`${key}`] = func;
  61 + methods[key] = func;
66 62 }
67 63 });
68 64 const res = Vue.compile(cell.outerHTML);
  65 + // todo 临时解决方案
69 66 const component = new Vue({
70 67 render: res.render,
71 68 staticRenderFns: res.staticRenderFns,
72   - methods: methods
  69 + methods: methods,
  70 + data () {
  71 + return $parent._data;
  72 + }
73 73 });
  74 +
74 75 const Cell = component.$mount();
75 76 this.$refs.cell.appendChild(Cell.$el);
76 77 }
77 78 },
78 79 destroy () {
79   - const $parent = this.content;
80   - for (let i = 0; i < $parent.$children.length; i++) {
81   - if ($parent.$children[i]._uid === this.uid) {
82   - $parent.$children[i].$destroy();
83   - }
84   - }
  80 +
85 81 },
86 82 toggleSelect () {
87 83 this.$parent.$parent.toggleSelect(this.index);
... ...