aaa-ui-test 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of aaa-ui-test might be problematic. Click here for more details.

Files changed (104) hide show
  1. package/README.md +62 -0
  2. package/babel-plugin-on-demand-load/index.js +74 -0
  3. package/babel-plugin-on-demand-load/report.js +49 -0
  4. package/lib/index.css +2213 -0
  5. package/lib/index.js +10083 -0
  6. package/package.json +73 -0
  7. package/src/assets/css/common/_mixin.scss +130 -0
  8. package/src/assets/css/common/_var.scss +69 -0
  9. package/src/components/address/index.js +8 -0
  10. package/src/components/address/index.scss +72 -0
  11. package/src/components/address/src/address.vue +238 -0
  12. package/src/components/amount/index.js +6 -0
  13. package/src/components/amount/index.scss +88 -0
  14. package/src/components/amount/src/amount.vue +143 -0
  15. package/src/components/button/__tests__/__snapshots__/index.test.js.snap +7 -0
  16. package/src/components/button/__tests__/index.test.js +39 -0
  17. package/src/components/button/index.js +7 -0
  18. package/src/components/button/index.scss +83 -0
  19. package/src/components/button/src/button.vue +39 -0
  20. package/src/components/button-group/index.js +8 -0
  21. package/src/components/button-group/index.scss +37 -0
  22. package/src/components/button-group/src/button-group.vue +21 -0
  23. package/src/components/checkbox/index.js +8 -0
  24. package/src/components/checkbox/index.scss +47 -0
  25. package/src/components/checkbox/src/checkbox-group.vue +53 -0
  26. package/src/components/checkbox/src/checkbox.vue +153 -0
  27. package/src/components/date-selecter/index.js +6 -0
  28. package/src/components/date-selecter/index.scss +190 -0
  29. package/src/components/date-selecter/src/dateselecter.vue +387 -0
  30. package/src/components/default/index.js +6 -0
  31. package/src/components/default/index.scss +25 -0
  32. package/src/components/default/src/default.vue +23 -0
  33. package/src/components/dialog/index.js +146 -0
  34. package/src/components/dialog/index.scss +250 -0
  35. package/src/components/dialog/src/dialog.vue +153 -0
  36. package/src/components/field/index.js +8 -0
  37. package/src/components/field/index.scss +93 -0
  38. package/src/components/field/src/field.vue +57 -0
  39. package/src/components/input/__tests__/__snapshots__/index.test.js.snap +10 -0
  40. package/src/components/input/__tests__/index.test.js +63 -0
  41. package/src/components/input/index.js +8 -0
  42. package/src/components/input/index.scss +91 -0
  43. package/src/components/input/src/input.vue +214 -0
  44. package/src/components/list/index.js +8 -0
  45. package/src/components/list/index.scss +21 -0
  46. package/src/components/list/src/list.vue +16 -0
  47. package/src/components/list-item/index.js +8 -0
  48. package/src/components/list-item/index.scss +126 -0
  49. package/src/components/list-item/src/list-item.vue +59 -0
  50. package/src/components/loading/__tests__/__snapshots__/index.test.js.snap +9 -0
  51. package/src/components/loading/__tests__/index.test.js +30 -0
  52. package/src/components/loading/index.js +128 -0
  53. package/src/components/loading/index.scss +33 -0
  54. package/src/components/loading/src/loading.vue +23 -0
  55. package/src/components/mask/index.js +9 -0
  56. package/src/components/mask/index.scss +16 -0
  57. package/src/components/mask/src/mask.vue +52 -0
  58. package/src/components/notice/index.js +6 -0
  59. package/src/components/notice/index.scss +81 -0
  60. package/src/components/notice/src/notice.vue +128 -0
  61. package/src/components/overlay/index.js +8 -0
  62. package/src/components/overlay/index.scss +119 -0
  63. package/src/components/overlay/src/overlay.vue +72 -0
  64. package/src/components/picker/index.js +7 -0
  65. package/src/components/picker/index.scss +49 -0
  66. package/src/components/picker/src/picker.vue +205 -0
  67. package/src/components/popup/index.js +8 -0
  68. package/src/components/popup/index.scss +79 -0
  69. package/src/components/popup/src/popup.vue +88 -0
  70. package/src/components/popup-header/index.js +8 -0
  71. package/src/components/popup-header/index.scss +45 -0
  72. package/src/components/popup-header/src/popup-header.vue +41 -0
  73. package/src/components/radio/index.js +8 -0
  74. package/src/components/radio/index.scss +19 -0
  75. package/src/components/radio/src/radio.vue +51 -0
  76. package/src/components/select/index.js +8 -0
  77. package/src/components/select/index.scss +51 -0
  78. package/src/components/select/src/select.vue +86 -0
  79. package/src/components/swiper/index.js +6 -0
  80. package/src/components/swiper/index.scss +49 -0
  81. package/src/components/swiper/src/swiper.vue +211 -0
  82. package/src/components/switch/__tests__/__snapshots__/index.test.js.snap +15 -0
  83. package/src/components/switch/__tests__/index.test.js +44 -0
  84. package/src/components/switch/index.js +8 -0
  85. package/src/components/switch/index.scss +85 -0
  86. package/src/components/switch/src/switch.vue +60 -0
  87. package/src/components/tabs/index.js +8 -0
  88. package/src/components/tabs/index.scss +73 -0
  89. package/src/components/tabs/src/tab-item.vue +40 -0
  90. package/src/components/tabs/src/tabs.vue +121 -0
  91. package/src/components/textarea/index.js +8 -0
  92. package/src/components/textarea/index.scss +41 -0
  93. package/src/components/textarea/src/textarea.vue +140 -0
  94. package/src/components/toast/__tests__/__snapshots__/index.test.js.snap +3 -0
  95. package/src/components/toast/__tests__/index.test.js +25 -0
  96. package/src/components/toast/index.js +53 -0
  97. package/src/components/toast/index.scss +102 -0
  98. package/src/components/toast/src/toast.vue +19 -0
  99. package/src/index.js +87 -0
  100. package/src/mixins/emitter.js +33 -0
  101. package/src/mixins/visible.js +23 -0
  102. package/src/utils/clickoutside.js +42 -0
  103. package/src/utils/fix-body.js +46 -0
  104. package/src/utils/utils.js +71 -0
@@ -0,0 +1,121 @@
1
+ <template>
2
+ <div :class="[type==='line'?'jdd-tabs-line':'jdd-tabs-card',needScroll?'jdd-tabs-hasscroll':'','jdd-tabs-wrap']" ref="tab">
3
+ <div class="jdd-tabs-list" ref="scroll">
4
+ <slot></slot>
5
+ <span class="jdd-tabs-active-line" :style="{'left':left+'px'}"></span>
6
+ </div>
7
+ </div>
8
+ </template>
9
+
10
+ <script>
11
+ import JddTabItem from "./tab-item";
12
+ import { rAF, cancelRaf } from "@/utils/utils";
13
+ export default {
14
+ name: "JddTabs",
15
+ props: {
16
+ value: {
17
+ default: 0
18
+ },
19
+ type: {
20
+ type: String,
21
+ default: "line"
22
+ }
23
+ },
24
+ components: {
25
+ JddTabItem
26
+ },
27
+ provide() {
28
+ return {
29
+ handleClick: this.itemSelect,
30
+ parent:this
31
+ };
32
+ },
33
+ data() {
34
+ return {
35
+ needScroll: false,
36
+ left:0,
37
+ midPos:0,
38
+ rafHand:null,
39
+ period:5
40
+ };
41
+ },
42
+ created() {
43
+ let slotsLength = 0;
44
+ if(this.$slots.default&&this.$slots.default.length){
45
+ slotsLength = this.$slots.default.length;
46
+ }
47
+ if(slotsLength >= 5){
48
+ this.needScroll = true;
49
+ }
50
+ //let slotsLength = this.$slots.default.length;
51
+ // console.log()
52
+ },
53
+ methods: {
54
+ computedLeft(offsetLeft) {
55
+ let activeTab = this.$refs.tab.querySelector(".jdd-tabs-active");
56
+ let activeLineWidth = this.$refs.tab.querySelector(".jdd-tabs-active-line").offsetWidth;
57
+ this.left = activeTab.offsetLeft+activeTab.offsetWidth/2-activeLineWidth/2;
58
+ this.midPos = this.$refs.scroll.offsetWidth/2;
59
+ //console.log(this.midPos,offsetLeft)
60
+ let scrollLeft = this.$refs.scroll.scrollLeft;
61
+ if(this.midPos <= offsetLeft){
62
+ // this.$refs.scroll.scrollLeft = offsetLeft-this.midPos;
63
+ this.rafScroll(scrollLeft,offsetLeft-this.midPos)
64
+ }else {
65
+ // this.$refs.scroll.scrollLeft = 0;
66
+ this.rafScroll(scrollLeft,0)
67
+ }
68
+ //if()
69
+ },
70
+ itemSelect(value,content,offsetLeft) {
71
+ if(value !== this.value){
72
+ this.$emit("input",value);
73
+ this.$nextTick(() => {
74
+ this.computedLeft(offsetLeft);
75
+ // this
76
+ })
77
+ }
78
+ this.$emit("click",value)
79
+ },
80
+ rafScroll(begin,end) {
81
+
82
+ if(begin === end){
83
+ return;
84
+ }
85
+ // if(this.rafHand){
86
+ // cancelAnimationFrame(this.rafHand);
87
+ // }
88
+ //this.rafHand&&;
89
+ let arr = [];
90
+ let period = (end-begin)/this.period;
91
+ for (let index = 0; index < this.period; index++) {
92
+ arr.push(parseInt(begin+=period))
93
+ }
94
+ arr.push(end)
95
+ let _this = this;
96
+ // console.log(arr)
97
+ // let stop = null;
98
+ let i = 0;
99
+ //console.log(new Date().getTime())
100
+ function step(timestamp) {
101
+
102
+ if (i < arr.length) {
103
+ // console.log(arr[i])
104
+ _this.$refs.scroll.scrollLeft = arr[i];
105
+ i+=1;
106
+ rAF(step);
107
+ }else{
108
+ // console.log(new Date().getTime())
109
+ cancelRaf(_this.rafHand);
110
+ }
111
+
112
+ }
113
+
114
+ _this.rafHand = rAF(step);
115
+ }
116
+ },
117
+ mounted(){
118
+ this.computedLeft();
119
+ }
120
+ }
121
+ </script>
@@ -0,0 +1,8 @@
1
+ import Textarea from './src/textarea.vue';
2
+ import "./index.scss";
3
+
4
+ Textarea.install = function(Vue){
5
+ Vue.component(Textarea.name, Textarea);
6
+ }
7
+
8
+ export default Textarea;
@@ -0,0 +1,41 @@
1
+ .jdd-field-control {
2
+ textarea {
3
+ appearance: none;
4
+ width: 100%;
5
+ padding: 0;
6
+ border: 0;
7
+ background-color: transparent;
8
+ overflow: visible;
9
+ display: block;
10
+ resize: none;
11
+ word-break: break-word;
12
+ word-wrap: break-word;
13
+ box-sizing: content-box;
14
+ color: #333333;
15
+ letter-spacing: 0;
16
+ text-align: right;
17
+ line-height: 22px;
18
+ max-height: 66px;
19
+ &::placeholder {
20
+ font-size: 16px;
21
+ color: #cccccc;
22
+ }
23
+ }
24
+ }
25
+ .jdd-field-inline {
26
+ textarea {
27
+ line-height: 22px;
28
+ font-size: 16px;
29
+ font-family: PingFangSC-Regular;
30
+ }
31
+ .jdd-field-textarea {
32
+ padding: 16px 0px;
33
+ }
34
+ }
35
+ .jdd-field {
36
+ textarea {
37
+ font-family: PingFangSC-Medium;
38
+ font-size: 18px;
39
+ text-align: left;
40
+ }
41
+ }
@@ -0,0 +1,140 @@
1
+ <template>
2
+ <jdd-field
3
+ :label="label"
4
+ @label-click="onLabelclick"
5
+ :isFocus="isFocus"
6
+ :direction="direction"
7
+ :border="border"
8
+ >
9
+ <div
10
+ class="jdd-field-control jdd-field-textarea"
11
+ @click="onClick"
12
+ :style="{'paddingBottom':paddingBottom+'px'}"
13
+ >
14
+ <textarea
15
+ rows="1"
16
+ :placeholder="getPlaceholder"
17
+ v-model="inputValue"
18
+ @input="onInput"
19
+ @change="onChange"
20
+ @propertychange="onChange"
21
+ @blur="onBlur"
22
+ @focus="onFocus"
23
+ v-bind="$attrs"
24
+ ref="textarea"
25
+ ></textarea>
26
+ </div>
27
+ </jdd-field>
28
+ </template>
29
+ <script>
30
+ import jddField from "../../field";
31
+ export default {
32
+ name: "JddTextarea",
33
+ inheritAttrs:false,
34
+ props: {
35
+ value: {
36
+ type: String,
37
+ default: ""
38
+ },
39
+ title:{
40
+ type: String,
41
+ default: ""
42
+ },
43
+ direction: {
44
+ type: String,
45
+ default: "row"
46
+ },
47
+ placeholder: {
48
+ type: String,
49
+ default: ""
50
+ },
51
+ border: {
52
+ type: String,
53
+ default: ""
54
+ }
55
+ },
56
+ components: {
57
+ jddField
58
+ },
59
+ data() {
60
+ return {
61
+ checkValue: this.value,
62
+ label: this.title,
63
+ isFocus: false,
64
+ inputValue: this.value,
65
+ paddingBottom: 0
66
+ };
67
+ },
68
+ methods: {
69
+ onLabelclick() {
70
+ //if(!this.value)
71
+ this.isFocus = true;
72
+ this.$refs.textarea.focus();
73
+ },
74
+ onInput() {
75
+ this.resizeHeight();
76
+ this.$emit("input", this.inputValue);
77
+ },
78
+ onClick() {
79
+ this.$refs.textarea.focus();
80
+ this.isFocus = true;
81
+ },
82
+ onFocus() {},
83
+ onBlur() {
84
+ let textareaDom = this.$refs.textarea;
85
+ if(!this.inputValue){
86
+ this.isFocus = false;
87
+ textareaDom.style.height = "0px";
88
+ }
89
+ textareaDom.scrollTop = 0;
90
+ },
91
+ onChange() {
92
+ this.resizeHeight();
93
+ this.$emit("input", this.inputValue);
94
+ },
95
+ resizeHeight() {
96
+ //console.log(1)
97
+ //console.log(this.$refs.textarea.scrollHeight)
98
+ let textareaDom = this.$refs.textarea;
99
+ let scrollHeight = textareaDom.scrollHeight;
100
+ if (scrollHeight > 30 && this.direction === "column") {
101
+ this.paddingBottom = 12;
102
+ } else if(this.direction==='row'){
103
+ this.paddingBottom = 16;
104
+ }
105
+ var height = 0,
106
+ style = textareaDom.style;
107
+ var minHeight = 22;
108
+ textareaDom.style.height = minHeight + "px";
109
+ if (textareaDom.scrollHeight > minHeight) {
110
+ height = textareaDom.scrollHeight;
111
+ style.height = height + "px";
112
+ }
113
+ }
114
+ },
115
+ created(){
116
+ if(this.value){
117
+ this.isFocus = true;
118
+ }
119
+ },
120
+ computed: {
121
+ getPlaceholder() {
122
+ return this.direction !== "column" && this.placeholder;
123
+ }
124
+ },
125
+ mounted(){
126
+ this.resizeHeight()
127
+ },
128
+ watch: {
129
+ value(newVal) {
130
+ this.checkValue = newVal;
131
+ },
132
+ checkValue(newVal) {
133
+ this.$emit("change", newVal);
134
+ this.$emit("input", newVal);
135
+ }
136
+ }
137
+ };
138
+ </script>
139
+
140
+
@@ -0,0 +1,3 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Toast renders the correct markup 1`] = `<div class="jdd-toast jdd-toast-in jdd-toast-top"><span>我是测试信息,测试信息</span></div>`;
@@ -0,0 +1,25 @@
1
+ // Import the mount() method from the test utils
2
+ // and the component you want to test
3
+ import { mount, createWrapper} from '@vue/test-utils'
4
+ import Toast from '..'
5
+ import flushPromises from "@/../test/utils.js";
6
+
7
+ describe('Toast', () => {
8
+ // Now mount the component and you have the wrapper
9
+ const baseMsg = "我是测试信息,测试信息";
10
+ const toast = Toast(baseMsg);
11
+ const wrapper = createWrapper(toast)
12
+
13
+ it('renders the correct markup', async () => {
14
+ //await flushPromises()
15
+ //console.log(toast.$el.outerHTML)
16
+ expect(wrapper.html()).toMatchSnapshot();
17
+
18
+ })
19
+ it('has a span class', () => {
20
+ //expect(toast.$el.outerHTML.contains('span')).toBe(true)
21
+ expect(wrapper.classes()).toContain('jdd-toast-top');
22
+ expect(wrapper.find("span").text()).toBe(baseMsg);
23
+ //expect(wrapper.classes("jdd-toast jdd-toast-top")).toBe(true);
24
+ })
25
+ })
@@ -0,0 +1,53 @@
1
+ import Vue from "vue"
2
+ import ToastComponent from './src/toast.vue'
3
+
4
+ import "./index.scss"
5
+ // const Toast = {};
6
+
7
+ // // 注册Toast
8
+ // Toast.install = function (Vue) {
9
+
10
+ // 生成一个Vue的子类
11
+ // 同时这个子类也就是组件
12
+ const ToastConstructor = Vue.extend(ToastComponent)
13
+
14
+ let toastPool = [];
15
+
16
+ // 生成一个该子类的实例
17
+ let getAnInstance = () => {
18
+ if (toastPool.length > 0) {
19
+ let instance = toastPool[0];
20
+ toastPool.splice(0, 1);
21
+ return instance;
22
+ }
23
+ return new ToastConstructor({
24
+ el: document.createElement('div')
25
+ });
26
+ };
27
+
28
+ // 通过Vue的原型注册一个方法
29
+ // 让所有实例共享这个方法
30
+ let Toast = Vue.prototype.$toast = (msg,bgcolor) => {
31
+
32
+ if(document.querySelector('.jdd-toast')){
33
+ document.body.removeChild(document.querySelector('.jdd-toast'));
34
+ }
35
+
36
+ let instance = getAnInstance();
37
+ instance.message = msg;
38
+ if(bgcolor){
39
+ instance.bgcolor = bgcolor;
40
+ }
41
+
42
+ instance.show = true;
43
+
44
+ document.body.appendChild(instance.$el);
45
+ return instance;
46
+
47
+ }
48
+ Toast.install = function (Vue) {
49
+
50
+ }
51
+ //}
52
+
53
+ export default Toast
@@ -0,0 +1,102 @@
1
+ @import "~@/assets/css/common/var";
2
+ @import "~@/assets/css/common/mixin";
3
+
4
+ .jdd-toast {
5
+ position: fixed;
6
+ left: 0;
7
+ width: 100%;
8
+ text-align: center;
9
+ z-index: $z-index-toast;
10
+ opacity: 1;
11
+
12
+ &.jdd-toast-top{
13
+ //transform: translate3d(0,-100%,0);
14
+ top: -100%;
15
+
16
+ &.jdd-toast-in{
17
+ animation: jddToastTopIn 3.8s ease-in-out;
18
+ }
19
+ }
20
+
21
+ &.jdd-toast-bottom{
22
+
23
+ //transform: translate3d(0,100%,0);
24
+ bottom: -100%;
25
+ //bottom:0;
26
+
27
+ &.jdd-toast-in{
28
+ animation: jddToastBottomIn 3.8s ease-in-out;
29
+ }
30
+
31
+ }
32
+ }
33
+
34
+
35
+ .jdd-toast span {
36
+ margin: 10px 20px;
37
+ display: inline-block;
38
+ padding: 10px 20px;
39
+ line-height: 20px;
40
+ font-family: PingFangSC-Medium;
41
+ font-size: 14px;
42
+ color: #fff;
43
+ background: #4D7BFE;
44
+ border-radius: 100px;
45
+ box-shadow: 0 0 7px 0 rgba(3,6,14,.2)
46
+ }
47
+
48
+
49
+
50
+ @keyframes jddToastBottomIn {
51
+ 0% {
52
+ // opacity: 0;
53
+ bottom:0;
54
+ }
55
+ // 5%{
56
+ // // opacity: 0;
57
+ // bottom:0;
58
+ // }
59
+ 10% {
60
+ // opacity: 1;
61
+ bottom:96px;
62
+ }
63
+ 90%{
64
+ // opacity: 1;
65
+ bottom:96px;
66
+ }
67
+ // 90%{
68
+ // // opacity: 0;
69
+ // }
70
+ 100%{
71
+ bottom:0px;
72
+ // opacity: 0;
73
+ }
74
+ }
75
+
76
+
77
+
78
+ @keyframes jddToastTopIn {
79
+ 0% {
80
+ // opacity: 0;
81
+ bottom:0;
82
+ }
83
+ // 5%{
84
+ // // opacity: 0;
85
+ // bottom:0;
86
+ // }
87
+ 10% {
88
+ // opacity: 1;
89
+ top:60px;
90
+ }
91
+ 90%{
92
+ // opacity: 1;
93
+ top:60px;
94
+ }
95
+ // 90%{
96
+ // // opacity: 0;
97
+ // }
98
+ 100%{
99
+ top:0px;
100
+ // opacity: 0;
101
+ }
102
+ }
@@ -0,0 +1,19 @@
1
+ <template>
2
+ <div class="jdd-toast " v-if="show" :class="{'jdd-toast-in':show,'jdd-toast-bottom': android,'jdd-toast-top': !android}">
3
+ <span :style="{background:bgcolor}">{{message}}</span>
4
+ </div>
5
+ </template>
6
+
7
+ <script>
8
+ export default {
9
+ name: 'JddToast',
10
+ data() {
11
+ return {
12
+ show: false,
13
+ android:navigator.userAgent.toLowerCase().match(/android/i)=="android" ? true : false,
14
+ message: "",
15
+ bgcolor:"",
16
+ };
17
+ }
18
+ };
19
+ </script>
package/src/index.js ADDED
@@ -0,0 +1,87 @@
1
+ import List from './components/list'
2
+ import ListItem from './components/list-item'
3
+
4
+ import Button from './components/button'
5
+ import ButtonGroup from './components/button-group'
6
+
7
+ import Toast from './components/toast'
8
+ import Loading from './components/loading'
9
+
10
+ import Mask from './components/mask'
11
+ import Overlay from './components/overlay'
12
+ import Notice from './components/notice'
13
+
14
+ import DateSelecter from './components/date-selecter'
15
+
16
+ import Dialog from './components/dialog'
17
+
18
+ import Input from './components/input'
19
+ import Select from './components/select'
20
+ import Switch from './components/switch'
21
+ import Textarea from './components/textarea'
22
+ import Checkbox from './components/checkbox'
23
+ import Tabs from './components/tabs'
24
+ import Amount from './components/amount'
25
+ //import Swipe from './components/swipe'
26
+ import Swiper from './components/swiper'
27
+ import Default from './components/default'
28
+
29
+
30
+ import Popup from './components/popup'
31
+ import Radio from './components/radio'
32
+ import PopupHeader from './components/popup-header'
33
+
34
+ import Address from './components/address'
35
+
36
+ const components = {
37
+ List,
38
+ ListItem,
39
+ Button,
40
+ ButtonGroup,
41
+ Mask,
42
+ Notice,
43
+ Overlay,
44
+ DateSelecter,
45
+ Input,
46
+ Select,
47
+ Switch,
48
+ Textarea,
49
+ Popup,
50
+ Radio,
51
+ PopupHeader,
52
+ Address,
53
+ Toast,
54
+ Tabs,
55
+ Checkbox,
56
+ Amount,
57
+ // Swipe,
58
+ Default,
59
+ Swiper
60
+ }
61
+
62
+ function install(Vue) {
63
+ // register components
64
+ // debugger;
65
+ for (var item in components) {
66
+ if (components[item].name) {
67
+ // Vue.component(components[item].name, components[item])
68
+ Vue.use(components[item])
69
+ }
70
+ }
71
+ //Vue.use(Toast);
72
+ //Vue.use(Loading);
73
+ //Vue.use(Dialog)
74
+ // return {
75
+ // hello:123
76
+ // }
77
+
78
+ }
79
+ if (typeof window !== 'undefined' && window.Vue) {
80
+ window.Vue.use(install)
81
+ }
82
+ let modules = {
83
+ install:install,
84
+ ...components
85
+ }
86
+ export default modules;
87
+
@@ -0,0 +1,33 @@
1
+ function broadcast(componentName, eventName, params) {
2
+ this.$children.forEach(child => {
3
+ const name = child.$options.name;
4
+
5
+ if (name === componentName) {
6
+ child.$emit.apply(child, [eventName].concat(params));
7
+ } else {
8
+ broadcast.apply(child, [componentName, eventName].concat([params]));
9
+ }
10
+ });
11
+ }
12
+ export default {
13
+ methods: {
14
+ dispatch(componentName, eventName, params) {
15
+ let parent = this.$parent || this.$root;
16
+ let name = parent.$options.name;
17
+
18
+ while (parent && (!name || name !== componentName)) {
19
+ parent = parent.$parent;
20
+
21
+ if (parent) {
22
+ name = parent.$options.name;
23
+ }
24
+ }
25
+ if (parent) {
26
+ parent.$emit.apply(parent, [eventName].concat(params));
27
+ }
28
+ },
29
+ broadcast(componentName, eventName, params) {
30
+ broadcast.call(this, componentName, eventName, params);
31
+ }
32
+ }
33
+ };
@@ -0,0 +1,23 @@
1
+ const EVENT_UPDATE = 'update:visible';
2
+
3
+ export default {
4
+ props: {
5
+ visible: {
6
+ type: Boolean,
7
+ default: false
8
+ }
9
+ },
10
+ data() {
11
+ return {
12
+ isVisible: false
13
+ }
14
+ },
15
+ watch: {
16
+ isVisible(newVal) {
17
+ this.$emit(EVENT_UPDATE , newVal)
18
+ },
19
+ visible(newVal) {
20
+ this.isVisible = newVal;
21
+ }
22
+ }
23
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * v-clickoutside
3
+ * @desc 点击元素外面才会触发的事件
4
+ * @example
5
+ * ```vue
6
+ * <div v-clickoutside="handleClose">
7
+ * ```
8
+ */
9
+ const clickoutsideContext = '@@clickoutsideContext';
10
+
11
+ export default {
12
+ bind(el, binding, vnode) {
13
+ const documentHandler = function(e) {
14
+ if (vnode.context && !el.contains(e.target)) {
15
+ vnode.context[el[clickoutsideContext].methodName]();
16
+ }
17
+ };
18
+ el[clickoutsideContext] = {
19
+ documentHandler,
20
+ methodName: binding.expression,
21
+ arg: binding.arg || 'click'
22
+ };
23
+ document.addEventListener(el[clickoutsideContext].arg, documentHandler);
24
+ },
25
+
26
+ update(el, binding) {
27
+ el[clickoutsideContext].methodName = binding.expression;
28
+ },
29
+
30
+ unbind(el) {
31
+ document.removeEventListener(
32
+ el[clickoutsideContext].arg,
33
+ el[clickoutsideContext].documentHandler);
34
+ },
35
+
36
+ install(Vue) {
37
+ Vue.directive('clickoutside', {
38
+ bind: this.bind,
39
+ unbind: this.unbind
40
+ });
41
+ }
42
+ };