@shijiu/jsview-vue 0.9.766 → 0.9.783

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.
Files changed (64) hide show
  1. package/dom/bin/jsview-browser-debug-dom.min.js +1 -1
  2. package/dom/bin/jsview-dom.min.js +1 -1
  3. package/package.json +1 -1
  4. package/samples/DemoHomepage/App.vue +30 -6
  5. package/samples/DemoHomepage/components/TabFrame.vue +7 -0
  6. package/samples/DemoHomepage/router.js +16 -18
  7. package/samples/DemoHomepage/views/Homepage.vue +5 -1
  8. package/samples/FocusBlockDemos/AutoFocus/App.vue +51 -0
  9. package/samples/FocusBlockDemos/AutoFocus/BaseBlock.vue +82 -0
  10. package/samples/FocusBlockDemos/AutoFocus/DialogBlock.vue +89 -0
  11. package/samples/FocusBlockDemos/AutoFocus/DialogContorls.js +42 -0
  12. package/samples/FocusBlockDemos/AutoFocus/FocusNamesDefine.js +9 -0
  13. package/samples/FocusBlockDemos/AutoFocus/PlaneBlock.vue +71 -0
  14. package/samples/FocusBlockDemos/ProgressiveFocusControl/App.vue +78 -0
  15. package/samples/FocusBlockDemos/ProgressiveFocusControl/BaseBlock.vue +77 -0
  16. package/samples/FocusBlockDemos/ProgressiveFocusControl/DownPlaneBlock.vue +83 -0
  17. package/samples/FocusBlockDemos/ProgressiveFocusControl/FocusNamesDefine.js +12 -0
  18. package/samples/FocusBlockDemos/ProgressiveFocusControl/UpPlaneBlock.vue +83 -0
  19. package/samples/Marquee/App.vue +34 -3
  20. package/samples/MetroWidgetDemos/PingPong/App.vue +22 -11
  21. package/samples/MetroWidgetDemos/PingPong/AppPage.vue +3 -3
  22. package/samples/MetroWidgetDemos/{Item.vue → PingPong/Item.vue} +1 -3
  23. package/samples/MetroWidgetDemos/PingPong/ViewSwiper.vue +3 -3
  24. package/samples/MetroWidgetDemos/{WidgetItem.vue → PingPong/WidgetItem.vue} +6 -1
  25. package/samples/MetroWidgetDemos/basic/App.vue +162 -0
  26. package/samples/MetroWidgetDemos/basic/Item.vue +43 -0
  27. package/samples/MetroWidgetDemos/direction/App.vue +158 -0
  28. package/samples/MetroWidgetDemos/direction/Item.vue +45 -0
  29. package/samples/MetroWidgetDemos/focusableItemBasic/App.vue +67 -0
  30. package/samples/MetroWidgetDemos/{Advanced → focusableItemBasic}/ButtonItem.vue +16 -20
  31. package/samples/MetroWidgetDemos/focusableItemMetroWidget/App.vue +74 -0
  32. package/samples/MetroWidgetDemos/{Advanced/widgets → focusableItemMetroWidget}/Item.vue +12 -30
  33. package/samples/MetroWidgetDemos/{Advanced/widgets → focusableItemMetroWidget}/WidgetItem.vue +10 -9
  34. package/samples/MetroWidgetDemos/focusableItemMix/App.vue +88 -0
  35. package/samples/MetroWidgetDemos/focusableItemMix/ButtonItem.vue +86 -0
  36. package/samples/MetroWidgetDemos/focusableItemMix/Item.vue +43 -0
  37. package/samples/MetroWidgetDemos/index.js +6 -0
  38. package/samples/MetroWidgetDemos/layoutType/App.vue +180 -0
  39. package/samples/MetroWidgetDemos/layoutType/Item.vue +45 -0
  40. package/samples/MetroWidgetDemos/padding/App.vue +222 -0
  41. package/samples/MetroWidgetDemos/padding/Item.vue +64 -0
  42. package/samples/MetroWidgetDemos/routeList.js +64 -0
  43. package/samples/MetroWidgetDemos/slideSetting/App.vue +225 -0
  44. package/samples/MetroWidgetDemos/slideSetting/Item.vue +45 -0
  45. package/samples/NinePatchDemo/App.vue +78 -122
  46. package/samples/NinePatchDemo/Item.vue +28 -26
  47. package/samples/Swiper/App.vue +148 -0
  48. package/utils/JsViewEngineWidget/MetroWidget/MetroWidget.vue +15 -12
  49. package/utils/JsViewEngineWidget/TemplateParser.js +6 -1
  50. package/utils/JsViewPlugin/JsvPlayer/version.js +4 -4
  51. package/utils/JsViewVueTools/JsvTextTools.js +24 -3
  52. package/utils/JsViewVueWidget/JsvMarquee.vue +81 -20
  53. package/utils/JsViewVueWidget/JsvSwiper/JsvSwiper.vue +115 -79
  54. package/utils/JsViewVueWidget/JsvSwiper/index.js +3 -2
  55. package/samples/MetroWidgetDemos/Advanced/App.vue +0 -46
  56. package/samples/MetroWidgetDemos/Advanced/Buttons.vue +0 -70
  57. package/samples/MetroWidgetDemos/Advanced/Mixed.vue +0 -77
  58. package/samples/MetroWidgetDemos/Advanced/widgets/Widgets.vue +0 -116
  59. package/samples/MetroWidgetDemos/Advanced/widgets/focus1.png +0 -0
  60. package/samples/MetroWidgetDemos/Simple/AbsoluteTemplate.vue +0 -75
  61. package/samples/MetroWidgetDemos/Simple/App.vue +0 -45
  62. package/samples/MetroWidgetDemos/Simple/RelativeTemplate.vue +0 -111
  63. package/samples/MetroWidgetDemos/data.js +0 -205
  64. package/utils/JsViewVueWidget/JsvSwiper/Indicator.vue +0 -35
@@ -0,0 +1,74 @@
1
+ <!--
2
+ * @Author: ChenChanghua
3
+ * @Date: 2022-07-11 13:31:36
4
+ * @Description: file content
5
+ -->
6
+ <script setup>
7
+ import { MetroWidget, VERTICAL, EdgeDirection, useFocusHub } from "jsview";
8
+ import WidgetItem from "./WidgetItem.vue";
9
+ import { onMounted } from "vue";
10
+
11
+ const focusHub = useFocusHub();
12
+
13
+ const provideData = () => {
14
+ const data = [];
15
+ for (let i = 0; i < 10; i++) {
16
+ data.push({
17
+ width: 500,
18
+ height: 170,
19
+ name: "widget_" + i,
20
+ marginBottom: 10,
21
+ index: i,
22
+ });
23
+ }
24
+ return data;
25
+ };
26
+
27
+ const measures = (item) => {
28
+ return {
29
+ width: item.width,
30
+ height: item.height,
31
+ marginRight: item.marginRight,
32
+ marginBottom: item.marginBottom,
33
+ /**重要代码: doSlide设置为false, 由子MetroWidget控制滚动 */
34
+ doSlide: false,
35
+ };
36
+ };
37
+
38
+ onMounted(() => {
39
+ focusHub.setFocus("mwWidget");
40
+ });
41
+ </script>
42
+
43
+ <template>
44
+ <div :style="{ width: 1920, height: 1080, backgroundColor: '#007788' }" />
45
+ <div
46
+ :style="{
47
+ left: 100,
48
+ top: 20,
49
+ width: 600,
50
+ height: 400,
51
+ fontSize: 30,
52
+ color: '#FFFFFF',
53
+ }"
54
+ >
55
+ {{ `MetroWidget的item是包含MetroWidget的组件` }}
56
+ </div>
57
+ <!-- 为了保证边缘的item缩放后依旧完整显示, 需要设置padding, 注意width/height是包含padding的 -->
58
+ <metro-widget
59
+ name="mwWidget"
60
+ :top="140"
61
+ :left="50"
62
+ :width="660"
63
+ :height="600"
64
+ :provideData="provideData"
65
+ :padding="{ left: 30, right: 30 }"
66
+ :direction="VERTICAL"
67
+ :measures="measures"
68
+ >
69
+ <!-- 重要代码: 为了实现焦点就近移动, 需要传递onItemEdge回调 -->
70
+ <template #renderItem="{ data, onAction, onItemEdge }">
71
+ <widget-item :data="data" :onAction="onAction" :onItemEdge="onItemEdge" />
72
+ </template>
73
+ </metro-widget>
74
+ </template>
@@ -1,15 +1,6 @@
1
1
  <!--
2
2
  * @Author: ChenChanghua
3
- * @Date: 2022-11-01 15:30:14
4
- * @LastEditors: ChenChanghua
5
- * @LastEditTime: 2022-12-02 16:11:54
6
- * @Description: file content
7
- -->
8
- <!--
9
- * @Author: ChenChanghua
10
- * @Date: 2022-05-10 15:21:24
11
- * @LastEditors: ChenChanghua
12
- * @LastEditTime: 2022-11-01 15:24:26
3
+ * @Date: 2023-03-09 15:33:54
13
4
  * @Description: file content
14
5
  -->
15
6
  <script setup>
@@ -17,31 +8,14 @@ import { ref, shallowRef, inject } from "vue";
17
8
 
18
9
  const props = defineProps({
19
10
  data: Object,
20
- query: Object,
21
11
  onAction: Object,
22
12
  });
23
13
 
24
- const divRef = shallowRef(null);
25
14
  const focused = ref(false);
26
15
 
27
- const focusSize = inject("focusSize");
28
-
29
16
  // 自身的焦点状态自己记录, 通过回调来改变
30
17
  const onFocus = () => {
31
18
  focused.value = true;
32
- if (focusSize) {
33
- divRef.value?.getBoundingClientRect().then(
34
- (data) => {
35
- focusSize.width = data.width;
36
- focusSize.height = data.height;
37
- focusSize.left = data.left;
38
- focusSize.top = data.top;
39
- },
40
- (error) => {
41
- console.log("get absolute position failed", error);
42
- }
43
- );
44
- }
45
19
  };
46
20
  const onBlur = () => {
47
21
  focused.value = false;
@@ -66,14 +40,22 @@ props.onAction.register("onClick", onClick);
66
40
  }"
67
41
  >
68
42
  <div
69
- ref="divRef"
43
+ v-if="focused"
44
+ :style="{
45
+ left: -2,
46
+ top: -2,
47
+ width: data.width + 4,
48
+ height: data.height + 4,
49
+ backgroundColor: '#FF0000',
50
+ }"
51
+ />
52
+ <div
70
53
  :style="{
71
54
  width: data.width,
72
55
  height: data.height,
73
- fontSize: '30px',
56
+ fontSize: 30,
74
57
  color: '#FFFFFF',
75
58
  backgroundColor: data.color,
76
- borderRadius: '10px',
77
59
  }"
78
60
  >
79
61
  {{ data.content }}
@@ -6,7 +6,6 @@ import Item from "./Item.vue";
6
6
 
7
7
  const props = defineProps({
8
8
  data: Object,
9
- query: Object,
10
9
  onItemEdge: Function,
11
10
  onAction: Object,
12
11
  });
@@ -37,13 +36,15 @@ const provideData = () => {
37
36
  return data;
38
37
  };
39
38
  const onFocus = (rect) => {
40
- //获得焦点时需要做就近移动的处理, 因此需要通过setEnterFocusRect设置寻找最近焦点的区域
39
+ /** 重要代码: 参数rect为父MetroWidget传递的, 焦点过来的区域
40
+ * 因此需要调用setEnterFocusRect来设置焦点进入区域, 以寻找最近的焦点
41
+ */
41
42
  mwRef.value?.setEnterFocusRect(rect);
42
43
  focusHub.setFocus(props.data.name);
43
44
  };
44
45
  const onBlur = () => {
45
46
  //onBlur时需要返还焦点给父MetroWidget
46
- mwRef.value?.getFocusBlockRef().returnFocusToParent();
47
+ focusHub.returnFocusToParent();
47
48
  };
48
49
 
49
50
  props.onAction.register("onFocus", onFocus);
@@ -61,15 +62,15 @@ props.onAction.register("onBlur", onBlur);
61
62
  >
62
63
  {{ data.name }}
63
64
  </div>
64
- <!-- sendFocusRectEvent可以让MetroWidget的item在获焦时发送事件, 通知父的MetroWidget进行滚动 -->
65
- <!-- onItemEdge直接作为onEdge回调, 既子MetroWidget到达边缘时触发父的onItemEdge -->
65
+ <!-- 重要代码: sendFocusRectEvent可以让MetroWidget的item在获焦时发送事件, 通知父的MetroWidget进行滚动 -->
66
+ <!-- 重要代码: onItemEdge直接作为onEdge回调, 既子MetroWidget到达边缘时触发父的onItemEdge -->
66
67
  <metro-widget
67
68
  ref="mwRef"
68
- :top="50"
69
69
  :name="data.name"
70
- :provideData="provideData"
70
+ :top="50"
71
71
  :width="data.width"
72
72
  :height="data.height"
73
+ :provideData="provideData"
73
74
  :direction="HORIZONTAL"
74
75
  :padding="{
75
76
  left: 30,
@@ -81,8 +82,8 @@ props.onAction.register("onBlur", onBlur);
81
82
  :onEdge="onItemEdge"
82
83
  :sendFocusRectEvent="true"
83
84
  >
84
- <template #renderItem="{ data, query, onAction }">
85
- <item :data="data" :query="query" :onAction="onAction" />
85
+ <template #renderItem="{ data, onAction }">
86
+ <item :data="data" :onAction="onAction" />
86
87
  </template>
87
88
  </metro-widget>
88
89
  </template>
@@ -0,0 +1,88 @@
1
+ <!--
2
+ * @Author: ChenChanghua
3
+ * @Date: 2022-07-11 13:31:36
4
+ * @LastEditors: Please set LastEditors
5
+ * @LastEditTime: 2023-03-09 15:31:53
6
+ * @Description: file content
7
+ -->
8
+ <script setup>
9
+ import { MetroWidget, HORIZONTAL, EdgeDirection, useFocusHub } from "jsview";
10
+ import ButtonItem from "./ButtonItem.vue";
11
+ import Item from "./Item.vue";
12
+ import { onMounted } from "vue";
13
+
14
+ const focusHub = useFocusHub();
15
+
16
+ const randomColor = () => {
17
+ let randomColor = Math.round(Math.random() * 2 ** 24).toString(16);
18
+ return (
19
+ "#" + new Array(6 - randomColor.length).fill("0").join("") + randomColor
20
+ );
21
+ };
22
+ //item混排的回调
23
+ const provideData = () => {
24
+ const advanceMix = [];
25
+ for (let i = 0; i < 20; i++) {
26
+ advanceMix.push({
27
+ width: 200,
28
+ height: 100,
29
+ name: "mix_button_" + i,
30
+ marginRight: 10,
31
+ marginBottom: 10,
32
+ type: i % 2 == 0 ? "button" : "item",
33
+ color: randomColor(),
34
+ content: i,
35
+ });
36
+ }
37
+ return advanceMix;
38
+ };
39
+ const measures = (item) => {
40
+ return {
41
+ width: item.width,
42
+ height: item.height,
43
+ marginRight: item.marginRight,
44
+ marginBottom: item.marginBottom,
45
+ };
46
+ };
47
+
48
+ const onEdge = (edgeInfo) => {};
49
+
50
+ onMounted(() => {
51
+ focusHub.setFocus("mwMix");
52
+ });
53
+ </script>
54
+
55
+ <template>
56
+ <div
57
+ :style="{
58
+ left: 50,
59
+ top: 10,
60
+ width: 600,
61
+ height: 400,
62
+ fontSize: 30,
63
+ color: '#FFFFFF',
64
+ }"
65
+ >
66
+ {{ "包含JsvFocusBlock的组件和纯描画组件混排" }}
67
+ </div>
68
+ <metro-widget
69
+ name="mwMix"
70
+ :top="100"
71
+ :left="50"
72
+ :provideData="provideData"
73
+ :width="600"
74
+ :height="400"
75
+ :direction="VERTICAL"
76
+ :measures="measures"
77
+ :onEdge="onEdge"
78
+ >
79
+ <template #renderItem="{ data, onAction }">
80
+ <button-item
81
+ v-if="data.type == 'button'"
82
+ :data="data"
83
+ :onAction="onAction"
84
+ />
85
+ <item v-else :data="data" :onAction="onAction" />
86
+ </template>
87
+ </metro-widget>
88
+ </template>
@@ -0,0 +1,86 @@
1
+ <!--
2
+ * @Author: ChenChanghua
3
+ * @Date: 2023-03-09 14:19:01
4
+ * @Description: 一个简单的按左右键, 焦点在左右两个view来回切换的控件
5
+ -->
6
+ <script setup>
7
+ import { ref, shallowRef } from "vue";
8
+ import { useFocusHub } from "jsview";
9
+
10
+ const props = defineProps({
11
+ data: Object,
12
+ onAction: Object,
13
+ });
14
+ const focusHub = useFocusHub();
15
+
16
+ let focused = ref(false);
17
+ let focusIndex = ref(0);
18
+ const onFocus = () => {
19
+ /**重要代码: onFocus时, 获得焦点, 以处理自己内部的焦点逻辑*/
20
+ focusHub.setFocus(props.data.name);
21
+ /*******/
22
+ focused.value = true;
23
+ };
24
+ const onBlur = () => {
25
+ focused.value = false;
26
+ focusIndex.value = 0;
27
+ /**重要代码: onBlur的时候, 需要将焦点返还给父*/
28
+ focusHub.returnFocusToParent();
29
+ /*******/
30
+ };
31
+
32
+ const onKeyDown = (ev) => {
33
+ if (ev.keyCode == 37 && focusIndex.value == 1) {
34
+ focusIndex.value = 0;
35
+ return true;
36
+ } else if (ev.keyCode == 39 && focusIndex.value == 0) {
37
+ focusIndex.value = 1;
38
+ return true;
39
+ } else if (ev.keyCode == 13) {
40
+ console.log("button click", props.data);
41
+ return true;
42
+ }
43
+ return false;
44
+ };
45
+
46
+ props.onAction.register("onFocus", onFocus);
47
+ props.onAction.register("onBlur", onBlur);
48
+ </script>
49
+
50
+ <template>
51
+ <jsv-focus-block
52
+ :name="data.name"
53
+ :onAction="{
54
+ onKeyDown: onKeyDown,
55
+ }"
56
+ >
57
+ <div
58
+ :style="{
59
+ width: 100,
60
+ height: 100,
61
+ fontSize: 20,
62
+ color: '#FFFFFF',
63
+ backgroundColor: '#00AA00',
64
+ }"
65
+ ></div>
66
+
67
+ <div
68
+ :style="{
69
+ left: 100,
70
+ width: 100,
71
+ height: 100,
72
+ backgroundColor: '#0000AA',
73
+ }"
74
+ ></div>
75
+
76
+ <div
77
+ :style="{
78
+ visibility: focused ? 'visible' : 'hidden',
79
+ left: 100 * focusIndex,
80
+ width: 10,
81
+ height: 10,
82
+ backgroundColor: '#FF0000',
83
+ }"
84
+ ></div>
85
+ </jsv-focus-block>
86
+ </template>
@@ -0,0 +1,43 @@
1
+ <!--
2
+ * @Author: ChenChanghua
3
+ * @Date: 2023-03-09 15:05:27
4
+ * @Description: file content
5
+ -->
6
+ <script setup>
7
+ import { ref, shallowRef, inject } from "vue";
8
+
9
+ const props = defineProps({
10
+ data: Object,
11
+ onAction: Object,
12
+ });
13
+
14
+ const focused = ref(false);
15
+
16
+ // 注册回调
17
+ const onFocus = () => {
18
+ focused.value = true;
19
+ };
20
+ const onBlur = () => {
21
+ focused.value = false;
22
+ };
23
+ const onClick = () => {
24
+ console.log("item onclick ", props.data);
25
+ };
26
+ props.onAction.register("onFocus", onFocus);
27
+ props.onAction.register("onBlur", onBlur);
28
+ props.onAction.register("onClick", onClick);
29
+ </script>
30
+
31
+ <template>
32
+ <div
33
+ :style="{
34
+ width: data.width,
35
+ height: data.height,
36
+ fontSize: 30,
37
+ color: focused ? '#FF0000' : '#FFFFFF',
38
+ backgroundColor: data.color,
39
+ }"
40
+ >
41
+ {{ data.content }}
42
+ </div>
43
+ </template>
@@ -0,0 +1,6 @@
1
+ /*
2
+ * @Author: ChenChanghua
3
+ * @Date: 2023-03-09 14:03:58
4
+ * @Description: file content
5
+ */
6
+ export { default as metroWidgetRouteList } from "./routeList"
@@ -0,0 +1,180 @@
1
+ <!--
2
+ * @Author: ChenChanghua
3
+ * @Date: 2023-03-08 16:15:45
4
+ * @Description: file content
5
+ -->
6
+ <script setup>
7
+ import { MetroWidget, HORIZONTAL, useFocusHub, EdgeDirection } from "jsview";
8
+ import Item from "./Item.vue";
9
+ import { onMounted } from "vue";
10
+
11
+ const TAG = "MetroWidgetDemo";
12
+
13
+ const focusHub = useFocusHub();
14
+
15
+ const randomColor = () => {
16
+ let randomColor = Math.round(Math.random() * 2 ** 24).toString(16);
17
+ return (
18
+ "#" + new Array(6 - randomColor.length).fill("0").join("") + randomColor
19
+ );
20
+ };
21
+
22
+ const widget1 = {
23
+ provideData: () => {
24
+ const data = [];
25
+ for (let i = 0; i < 30; i++) {
26
+ data.push({
27
+ width: 90,
28
+ height: 90,
29
+ marginRight: 10,
30
+ marginBottom: 10,
31
+ color: randomColor(),
32
+ content: i,
33
+ });
34
+ }
35
+ return data;
36
+ },
37
+ measures: (data) => {
38
+ return {
39
+ width: data.width,
40
+ height: data.height,
41
+ marginRight: data.marginRight,
42
+ marginBottom: data.marginBottom,
43
+ };
44
+ },
45
+ onEdge: (edgeInfo) => {
46
+ if (edgeInfo.direction == EdgeDirection.bottom) {
47
+ focusHub.setFocus("widget2");
48
+ }
49
+ },
50
+ widgetLayout: {
51
+ left: 50,
52
+ top: 50,
53
+ width: 500,
54
+ height: 200,
55
+ },
56
+ };
57
+
58
+ const widget2 = {
59
+ provideData: () => {
60
+ const data = [];
61
+ for (let i = 0; i < 30; i++) {
62
+ const p = Math.floor(i / 3);
63
+ let left, top;
64
+ if (i % 3 == 0) {
65
+ left = p * 200;
66
+ top = 50;
67
+ } else if (i % 3 == 1) {
68
+ left = p * 200 + 100;
69
+ top = 0;
70
+ } else if (i % 3 == 2) {
71
+ left = p * 200 + 100;
72
+ top = 100;
73
+ }
74
+ data.push({
75
+ left,
76
+ top,
77
+ width: 90,
78
+ height: 90,
79
+ marginRight: 10,
80
+ marginBottom: 10,
81
+ color: randomColor(),
82
+ content: i,
83
+ });
84
+ }
85
+ return data;
86
+ },
87
+ measures: (data) => {
88
+ return {
89
+ left: data.left,
90
+ top: data.top,
91
+ width: data.width,
92
+ height: data.height,
93
+ marginRight: data.marginRight,
94
+ marginBottom: data.marginBottom,
95
+ };
96
+ },
97
+ onEdge: (edgeInfo) => {
98
+ if (edgeInfo.direction == EdgeDirection.top) {
99
+ focusHub.setFocus("widget1");
100
+ }
101
+ },
102
+ widgetLayout: {
103
+ left: 50,
104
+ top: 300,
105
+ width: 500,
106
+ height: 220,
107
+ },
108
+ };
109
+
110
+ onMounted(() => {
111
+ //组件mount后设置焦点
112
+ focusHub.setFocus("widget1");
113
+ });
114
+ </script>
115
+
116
+ <template>
117
+ <div
118
+ :style="{
119
+ width: 1920,
120
+ height: 1080,
121
+ backgroundColor: '#007788',
122
+ }"
123
+ />
124
+ <div
125
+ :style="{
126
+ left: widget1.widgetLayout.left,
127
+ top: widget1.widgetLayout.top - 50,
128
+ width: 1280,
129
+ height: 50,
130
+ fontSize: 20,
131
+ color: '#FFFFFF',
132
+ }"
133
+ >
134
+ {{ "根据尺寸自动布局" }}
135
+ </div>
136
+ <metro-widget
137
+ name="widget1"
138
+ :left="widget1.widgetLayout.left"
139
+ :top="widget1.widgetLayout.top"
140
+ :width="widget1.widgetLayout.width"
141
+ :height="widget1.widgetLayout.height"
142
+ :provideData="widget1.provideData"
143
+ :measures="widget1.measures"
144
+ :onEdge="widget1.onEdge"
145
+ :direction="HORIZONTAL"
146
+ >
147
+ <template #renderItem="{ data, onAction }">
148
+ <item :data="data" :onAction="onAction" />
149
+ </template>
150
+ </metro-widget>
151
+
152
+ <div
153
+ :style="{
154
+ left: widget2.widgetLayout.left,
155
+ top: widget2.widgetLayout.top - 50,
156
+ width: 1280,
157
+ height: 50,
158
+ fontSize: 20,
159
+ color: '#FFFFFF',
160
+ }"
161
+ >
162
+ {{ "绝对坐标布局" }}
163
+ </div>
164
+ <metro-widget
165
+ name="widget2"
166
+ :left="widget2.widgetLayout.left"
167
+ :top="widget2.widgetLayout.top"
168
+ :width="widget2.widgetLayout.width"
169
+ :height="widget2.widgetLayout.height"
170
+ :provideData="widget2.provideData"
171
+ :measures="widget2.measures"
172
+ :onEdge="widget2.onEdge"
173
+ :direction="HORIZONTAL"
174
+ layoutType="absolute"
175
+ >
176
+ <template #renderItem="{ data, onAction }">
177
+ <item :data="data" :onAction="onAction" />
178
+ </template>
179
+ </metro-widget>
180
+ </template>
@@ -0,0 +1,45 @@
1
+ <!--
2
+ * @Author: ChenChanghua
3
+ * @Date: 2023-03-08 14:52:17
4
+ * @Description: file content
5
+ -->
6
+ <script setup>
7
+ import { ref, shallowRef, inject } from "vue";
8
+
9
+ const props = defineProps({
10
+ data: Object,
11
+ onAction: Object,
12
+ });
13
+
14
+ const divRef = shallowRef(null);
15
+ const focused = ref(false);
16
+
17
+ // 注册回调
18
+ const onFocus = () => {
19
+ focused.value = true;
20
+ };
21
+ const onBlur = () => {
22
+ focused.value = false;
23
+ };
24
+ const onClick = () => {
25
+ console.log("item onclick ", props.data);
26
+ };
27
+ props.onAction.register("onFocus", onFocus);
28
+ props.onAction.register("onBlur", onBlur);
29
+ props.onAction.register("onClick", onClick);
30
+ </script>
31
+
32
+ <template>
33
+ <div
34
+ ref="divRef"
35
+ :style="{
36
+ width: data.width,
37
+ height: data.height,
38
+ fontSize: 30,
39
+ color: focused ? '#FF0000' : '#FFFFFF',
40
+ backgroundColor: data.color,
41
+ }"
42
+ >
43
+ {{ data.content }}
44
+ </div>
45
+ </template>