Phone.vue 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  1. <template>
  2. <div ref="phone-content" class="phone-content">
  3. <!-- 顶部导航栏 -->
  4. <div
  5. class="phone-top optional"
  6. :class="{ selected: 'page' === selectedIndex, [data.page.style.titleTextColor]: true }"
  7. :style="{ backgroundColor: data.page.style.titleBackgroundColor }"
  8. @click="handelClickItem('page')"
  9. >
  10. <p
  11. class="title"
  12. :style="{ color: data.page.style.titleTextColor }"
  13. >{{ data.page.params.title }}</p>
  14. </div>
  15. <!-- 内容区域 -->
  16. <div class="phone-main">
  17. <draggable
  18. :list="data.items"
  19. class="content"
  20. @update="handelDragItem"
  21. v-bind="{ animation: 120, filter: '.undrag' }"
  22. >
  23. <!-- 内容元素 -->
  24. <div
  25. class="devise-item optional"
  26. v-for="(item, index) in data.items"
  27. :key="index"
  28. @click="handelClickItem(index)"
  29. :class="{ selected: index === selectedIndex, undrag: inArray(item.type, undragList) }"
  30. :style="renderItemStyle(item)"
  31. >
  32. <!-- 轮播图 -->
  33. <div
  34. v-if="item.type == 'banner'"
  35. class="diy-banner"
  36. :style="{ padding: `${item.style.paddingTop}px ${item.style.paddingLeft}px`, background: item.style.background }"
  37. >
  38. <div
  39. class="swiper-item"
  40. v-show="dataIdx <= 1"
  41. v-for="(dataItem, dataIdx) in item.data"
  42. :key="`${index}_${dataIdx}_img`"
  43. :style="{ borderRadius: `${item.style.borderRadius}px` }"
  44. >
  45. <img class="image" :src="dataItem.imgUrl" />
  46. </div>
  47. <div
  48. class="indicator-dots"
  49. :class="item.style.btnShape"
  50. :style="{ '--padding-top': `${item.style.paddingTop}px` }"
  51. >
  52. <div
  53. v-for="(dataItem, dataIdx) in item.data"
  54. :key="`${index}_${dataIdx}_dots`"
  55. :style="{ background: item.style.btnColor }"
  56. class="dots-item"
  57. ></div>
  58. </div>
  59. </div>
  60. <!-- 图片组 -->
  61. <div
  62. v-else-if="item.type == 'image'"
  63. class="diy-image"
  64. :style="{ padding: `${item.style.paddingTop}px ${item.style.paddingLeft}px`, background: item.style.background }"
  65. >
  66. <div
  67. class="item-image"
  68. v-for="(dataItm, dataIdx) in item.data"
  69. :key="`${index}_${dataIdx}`"
  70. :style="{ marginBottom: `${item.style.itemMargin}px`, borderRadius: `${item.style.borderRadius}px` }"
  71. >
  72. <img class="image" :src="dataItm.imgUrl" />
  73. </div>
  74. </div>
  75. <!-- 图片橱窗 -->
  76. <div
  77. v-else-if="item.type == 'window'"
  78. class="diy-window"
  79. :style="{ background: item.style.background, padding: `${item.style.paddingTop}px ${item.style.paddingLeft}px` }"
  80. >
  81. <ul
  82. v-if="item.style.layout > -1"
  83. class="data-list clearfix"
  84. :class="`avg-sm-${item.style.layout}`"
  85. >
  86. <li
  87. v-for="(window, dataIdx) in item.data"
  88. :key="`${index}_${dataIdx}`"
  89. class="data-item"
  90. :style="{ padding: `${item.style.paddingTop}px ${item.style.paddingLeft}px` }"
  91. >
  92. <div class="item-image">
  93. <img class="image" :src="window.imgUrl" />
  94. </div>
  95. </li>
  96. </ul>
  97. <div class="display" v-else>
  98. <div
  99. class="display-left"
  100. :style="{ padding: `${item.style.paddingTop}px ${item.style.paddingLeft}px` }"
  101. >
  102. <img class="image" :src="item.data[0].imgUrl" />
  103. </div>
  104. <div class="display-right">
  105. <div
  106. v-if="item.data.length >= 2"
  107. class="display-right1"
  108. :style="{ padding: `${item.style.paddingTop}px ${item.style.paddingLeft}px` }"
  109. >
  110. <img class="image" :src="item.data[1].imgUrl" />
  111. </div>
  112. <div class="display-right2">
  113. <div
  114. v-if="item.data.length >= 3"
  115. class="left"
  116. :style="{ padding: `${item.style.paddingTop}px ${item.style.paddingLeft}px` }"
  117. >
  118. <img class="image" :src="item.data[2].imgUrl" />
  119. </div>
  120. <div
  121. v-if="item.data.length >= 4"
  122. class="right"
  123. :style="{ padding: `${item.style.paddingTop}px ${item.style.paddingLeft}px` }"
  124. >
  125. <img class="image" :src="item.data[3].imgUrl" />
  126. </div>
  127. </div>
  128. </div>
  129. </div>
  130. </div>
  131. <!-- 热区组 -->
  132. <div
  133. v-else-if="item.type == 'hotZone'"
  134. class="diy-hotZone"
  135. :style="{ padding: `${item.style.paddingTop}px ${item.style.paddingLeft}px`, background: item.style.background }"
  136. >
  137. <div class="bg-image" :style="{ borderRadius: `${item.style.borderRadius}px` }">
  138. <img class="image" :src="item.data.imgUrl" />
  139. </div>
  140. </div>
  141. <!-- 视频组 -->
  142. <div
  143. v-else-if="item.type == 'video'"
  144. class="diy-video"
  145. :style="{ padding: `${item.style.paddingTop}px ${item.style.paddingLeft}px`, background: item.style.background }"
  146. >
  147. <video
  148. :style="{ height: `${item.style.height}px` }"
  149. :src="item.params.videoUrl"
  150. :poster="item.params.poster"
  151. controls
  152. >您的浏览器不支持 video 标签</video>
  153. </div>
  154. <!-- 文章组 -->
  155. <div v-else-if="item.type == 'article'" class="diy-article">
  156. <div
  157. class="article-item"
  158. v-for="(dataItm, dataIdx) in (item.params.source == 'choice' ? item.data : item.defaultData)"
  159. :key="`${index}_${dataIdx}`"
  160. :class="`show-type__${dataItm.show_type}`"
  161. >
  162. <!-- 小图模式 -->
  163. <template v-if="dataItm.show_type == 10">
  164. <div class="article-item__left flex-box">
  165. <div class="article-item__title twoline-hide">
  166. <span class="article-title">{{ dataItm.title }}</span>
  167. </div>
  168. <div class="article-item__footer">
  169. <span class="article-views">{{ dataItm.views_num }}次浏览</span>
  170. </div>
  171. </div>
  172. <div class="article-item__image">
  173. <img class="image" :src="dataItm.image" alt />
  174. </div>
  175. </template>
  176. <!-- 大图模式 -->
  177. <template v-if="dataItm.show_type == 20">
  178. <div class="article-item__title">
  179. <span class="article-title">{{ dataItm.title }}</span>
  180. </div>
  181. <div class="article-item__image">
  182. <img class="image" :src="dataItm.image" />
  183. </div>
  184. <div class="article-item__footer">
  185. <span class="article-views">{{ dataItm.views_num }}次浏览</span>
  186. </div>
  187. </template>
  188. </div>
  189. </div>
  190. <!-- 搜索栏 -->
  191. <div
  192. v-else-if="item.type == 'search'"
  193. class="diy-search"
  194. :class="{ sticky: item.params.sticky }"
  195. :style="{ background: item.style.background, padding: `${item.style.paddingY}px ${item.style.paddingX}px` }"
  196. >
  197. <div class="inner" :class="item.style.searchStyle">
  198. <div
  199. class="search-input"
  200. :style="{ textAlign: item.style.textAlign, background: item.style.searchBg, color: item.style.searchFontColor }"
  201. >
  202. <a-icon class="search-icon" :component="PageIcon.search" />
  203. <span>{{ item.params.placeholder }}</span>
  204. </div>
  205. </div>
  206. </div>
  207. <!-- 店铺公告 -->
  208. <div
  209. v-else-if="item.type == 'notice'"
  210. class="diy-notice"
  211. :style="{ padding: `${item.style.paddingTop}px 0` }"
  212. >
  213. <div
  214. class="notice-body"
  215. :style="{ background: item.style.background, color: item.style.textColor }"
  216. >
  217. <div class="notice__icon">
  218. <a-icon class="notice-icon" :component="PageIcon.volumeFill" />
  219. </div>
  220. <div
  221. class="notice__text flex-box oneline-hide"
  222. :style="{ fontSize: `${item.style.fontSize}px` }"
  223. >
  224. <span>{{ item.params.text }}</span>
  225. </div>
  226. </div>
  227. </div>
  228. <!-- 导航组 -->
  229. <div
  230. v-else-if="item.type == 'navBar'"
  231. class="diy-navBar"
  232. :style="{ padding: `${item.style.paddingTop}px 0`, background: item.style.background, color: item.style.textColor }"
  233. >
  234. <div class="data-list clearfix" :class="`avg-sm-${item.style.rowsNum}`">
  235. <div
  236. class="item-nav"
  237. v-for="(dataItm, dataIdx) in item.data"
  238. :key="`${index}_${dataIdx}`"
  239. >
  240. <div class="item-image">
  241. <img
  242. class="image"
  243. :style="{ width: `${item.style.imageSize}px`, height: `${item.style.imageSize}px` }"
  244. :src="dataItm.imgUrl"
  245. />
  246. </div>
  247. <p class="item-text oneline-hide">{{ dataItm.text }}</p>
  248. </div>
  249. </div>
  250. </div>
  251. <!-- 商品组 -->
  252. <div
  253. v-else-if="item.type == 'goods'"
  254. class="diy-goods"
  255. :style="{ background: item.style.background, padding: `${item.style.paddingY}px ${item.style.paddingX}px` }"
  256. >
  257. <div
  258. class="goods-list"
  259. :class="[`display-${item.style.display}`, `column-${item.style.column}` ]"
  260. :style="{ marginBottom: `-${item.style.itemMargin}px` }"
  261. >
  262. <div
  263. class="goods-item"
  264. v-for="(dataItm, dataIdx) in (item.params.source == 'choice' ? item.data : item.defaultData)"
  265. :key="`${index}_${dataIdx}`"
  266. :class="[`display-${item.style.cardType}`]"
  267. :style="{ marginBottom: `${item.style.itemMargin}px`, borderRadius: `${item.style.borderRadius}px` }"
  268. >
  269. <!-- 单列商品 -->
  270. <template v-if="item.style.column == 1">
  271. <div class="flex">
  272. <!-- 商品图片 -->
  273. <div class="goods-item-left">
  274. <img class="image" :src="dataItm.goods_image" />
  275. </div>
  276. <div class="goods-item-right">
  277. <div class="goods-info">
  278. <div
  279. v-if="inArray('goodsName', item.style.show)"
  280. class="goods-name"
  281. :class="[ item.style.goodsNameRows == 'two' ? 'twoline-hide' : 'oneline-hide', `row-${item.style.goodsNameRows}` ]"
  282. >{{ dataItm.goods_name }}</div>
  283. <div v-if="inArray('sellingPoint', item.style.show)" class="goods-selling">
  284. <span
  285. class="selling oneline-hide"
  286. :style="{ color: item.style.sellingColor }"
  287. >{{ dataItm.selling_point }}</span>
  288. </div>
  289. <div
  290. v-if="inArray('goodsSales', item.style.show)"
  291. class="goods-sales oneline-hide"
  292. >
  293. <span class="sales">已售{{ dataItm.goods_sales }}</span>
  294. <!-- <span class="line">|</span>
  295. <span>惊艳度100%</span>-->
  296. </div>
  297. <div class="footer">
  298. <div
  299. v-if="inArray('goodsPrice', item.style.show)"
  300. class="goods-price oneline-hide"
  301. :style="{ color: item.style.priceColor }"
  302. >
  303. <span class="unit">¥</span>
  304. <span class="value">{{ dataItm.goods_price_min }}</span>
  305. <!-- <span class="unit2">到手价</span> -->
  306. <span v-if="inArray('linePrice', item.style.show)" class="line-price">
  307. <span class="unit">¥</span>
  308. <span class="value">{{ dataItm.line_price_min }}</span>
  309. </span>
  310. </div>
  311. <div
  312. v-show="inArray('cartBtn', item.style.show) && item.style.column < 3"
  313. class="action"
  314. >
  315. <div class="btn-cart" :style="{ color: item.style.btnCartColor }">
  316. <a-icon
  317. class="cart-icon"
  318. :component="PageIcon[`jiagou${item.style.btnCartStyle}`]"
  319. />
  320. </div>
  321. </div>
  322. </div>
  323. </div>
  324. </div>
  325. </div>
  326. </template>
  327. <!-- 两列/三列 -->
  328. <template v-else>
  329. <div class="goods-image">
  330. <img class="image" :src="dataItm.goods_image" />
  331. </div>
  332. <div class="goods-info">
  333. <div
  334. v-if="inArray('goodsName', item.style.show)"
  335. class="goods-name"
  336. :class="[ item.style.goodsNameRows == 'two' ? 'twoline-hide' : 'oneline-hide', `row-${item.style.goodsNameRows}` ]"
  337. >{{ dataItm.goods_name }}</div>
  338. <div v-if="inArray('sellingPoint', item.style.show)" class="goods-selling">
  339. <span
  340. class="selling oneline-hide"
  341. :style="{ color: item.style.sellingColor }"
  342. >{{ dataItm.selling_point }}</span>
  343. </div>
  344. <div
  345. v-if="inArray('goodsSales', item.style.show)"
  346. class="goods-sales oneline-hide"
  347. >
  348. <span class="sales">已售{{ dataItm.goods_sales }}</span>
  349. <!-- <span class="line">|</span>
  350. <span>惊艳度100%</span>-->
  351. </div>
  352. <div class="footer">
  353. <div
  354. v-if="inArray('goodsPrice', item.style.show)"
  355. class="goods-price oneline-hide"
  356. :style="{ color: item.style.priceColor }"
  357. >
  358. <span class="unit">¥</span>
  359. <span class="value">{{ dataItm.goods_price_min }}</span>
  360. <!-- <span class="unit2">到手价</span> -->
  361. <span v-if="inArray('linePrice', item.style.show)" class="line-price">
  362. <span class="unit">¥</span>
  363. <span class="value">{{ dataItm.line_price_min }}</span>
  364. </span>
  365. </div>
  366. <div
  367. v-show="inArray('cartBtn', item.style.show) && item.style.column < 3"
  368. class="action"
  369. >
  370. <div class="btn-cart" :style="{ color: item.style.btnCartColor }">
  371. <a-icon
  372. class="cart-icon"
  373. :component="PageIcon[`jiagou${item.style.btnCartStyle}`]"
  374. />
  375. </div>
  376. </div>
  377. </div>
  378. </div>
  379. </template>
  380. </div>
  381. </div>
  382. </div>
  383. <!-- 辅助空白 -->
  384. <div
  385. v-else-if="item.type == 'blank'"
  386. class="diy-blank"
  387. :style="{ height: `${item.style.height}px` , background: item.style.background }"
  388. ></div>
  389. <!-- 辅助线 -->
  390. <div
  391. v-else-if="item.type == 'guide'"
  392. class="diy-guide"
  393. :style="{ padding: `${item.style.paddingTop}px 0`, background: item.style.background }"
  394. >
  395. <p
  396. class="line"
  397. :style="{
  398. borderTopWidth: item.style.lineHeight + 'px',
  399. borderTopColor: item.style.lineColor,
  400. borderTopStyle: item.style.lineStyle
  401. }"
  402. ></p>
  403. </div>
  404. <!-- 在线客服 -->
  405. <div
  406. v-else-if="item.type == 'service'"
  407. class="diy-service"
  408. :style="{ opacity: item.style.opacity / 100 }"
  409. >
  410. <div class="service-icon">
  411. <img class="image" :src="item.params.image" alt />
  412. </div>
  413. </div>
  414. <!-- 富文本 -->
  415. <div
  416. v-else-if="item.type == 'richText'"
  417. class="diy-richText"
  418. :style="{ background: item.style.background, padding: `${item.style.paddingTop}px ${item.style.paddingLeft}px` }"
  419. v-html="item.params.content"
  420. ></div>
  421. <!-- 关注公众号 -->
  422. <div v-else-if="item.type == 'officialAccount'" class="diy-officialAccount">
  423. <div class="item-top">
  424. <span>关联的公众号</span>
  425. </div>
  426. <div class="item-content">
  427. <div class="item-cont-avatar">
  428. <img class="image" src="~@/assets/img/circular.png" alt />
  429. </div>
  430. <div class="item-cont-public">
  431. <div class="public-name">
  432. <span>公众号名称</span>
  433. </div>
  434. <div class="public-describe">
  435. <span>公众号简介公众号简介公众号简介</span>
  436. </div>
  437. </div>
  438. <div class="item-cont-active">
  439. <div class="active-btn">
  440. <span>关注</span>
  441. </div>
  442. </div>
  443. </div>
  444. </div>
  445. <!-- 优惠券 -->
  446. <div
  447. v-else-if="item.type == 'coupon'"
  448. class="diy-coupon"
  449. :style="{ padding: `${item.style.paddingTop}px 0`, background: item.style.background }"
  450. >
  451. <div class="coupon-wrapper">
  452. <div
  453. class="coupon-item"
  454. v-for="(coupon, idx) in (item.params.source == 'choice' ? (item.data.length ? item.data : item.defaultData) : item.defaultData)"
  455. :key="idx"
  456. :style="{ marginRight: `${item.style.marginRight}px` }"
  457. >
  458. <i class="before" :style="{ background: item.style.background }"></i>
  459. <div
  460. class="left-content"
  461. :style="{ background: item.style.couponBgColor, color: item.style.couponTextColor }"
  462. >
  463. <div class="content-top">
  464. <template v-if="coupon.coupon_type == 10">
  465. <span class="unit">¥</span>
  466. <span class="price">{{ coupon.reduce_price }}</span>
  467. </template>
  468. <template v-if="coupon.coupon_type == 20">
  469. <span class="price">{{ coupon.discount }}折</span>
  470. </template>
  471. </div>
  472. <div class="content-bottom">
  473. <span>满{{ coupon.min_price }}元可用</span>
  474. </div>
  475. </div>
  476. <div
  477. class="right-receive"
  478. :style="{ background: item.style.receiveBgColor, color: item.style.receiveTextColor }"
  479. >
  480. <span>立即</span>
  481. <span>领取</span>
  482. </div>
  483. </div>
  484. </div>
  485. </div>
  486. <!-- 头条快报 -->
  487. <div
  488. v-else-if="item.type == 'special'"
  489. class="diy-special"
  490. :style="{ padding: `${item.style.paddingTop}px 0`, background: item.style.background }"
  491. >
  492. <div class="special-left">
  493. <img class="image" :src="item.params.image" alt />
  494. </div>
  495. <div class="special-content" :class="[`display_${item.params.display}`]">
  496. <ul class="special-content-list">
  497. <li
  498. class="content-item oneline-hide"
  499. v-for="(dataItm, idx) in (item.params.source == 'choice' ? item.data : item.defaultData)"
  500. :key="idx"
  501. >
  502. <span :style="{ color: item.style.textColor }">{{ dataItm.title }}</span>
  503. </li>
  504. </ul>
  505. </div>
  506. <div class="special-more">
  507. <a-icon :component="Icon.arrowRight" />
  508. </div>
  509. </div>
  510. <!-- 网站备案号 -->
  511. <div
  512. v-else-if="item.type == 'ICPLicense'"
  513. class="diy-ICPLicense"
  514. :style="{ padding: `${item.style.paddingTop}px ${item.style.paddingLeft}px`, background: item.style.background }"
  515. >
  516. <p class="line" :style="{ textAlign: item.style.textAlign }">
  517. <a
  518. :style="{ fontSize: item.style.fontSize + 'px', color: item.style.textColor }"
  519. :href="item.params.link"
  520. target="_blank"
  521. >{{ item.params.text }}</a>
  522. </p>
  523. </div>
  524. <!-- 标题文本 -->
  525. <div
  526. v-else-if="item.type == 'title'"
  527. class="diy-title"
  528. :style="{ padding: `${item.style.paddingY}px 15px`, background: item.style.background }"
  529. >
  530. <div class="title-content">
  531. <!-- 标题文字 -->
  532. <div class="title">
  533. <span
  534. :style="{ color: item.style.titleTextColor, fontSize: `${item.params.titleFontSize}px`, fontWeight: item.params.titleFontWeight }"
  535. >{{ item.params.title }}</span>
  536. </div>
  537. <!-- 查看更多 -->
  538. <div
  539. v-if="item.params.more.enable"
  540. class="more-content"
  541. :style="{ color: item.style.moreTextColor }"
  542. >
  543. <span class="more-text">{{ item.params.more.text }}</span>
  544. <span v-if="item.params.more.enableIcon" class="more-icon">
  545. <a-icon :component="Icon.arrowRight" />
  546. </span>
  547. </div>
  548. </div>
  549. <!-- 描述文字 -->
  550. <div class="desc-content">
  551. <span
  552. :style="{ color: item.style.descTextColor, fontSize: `${item.params.descFontSize}px`, fontWeight: item.params.descFontWeight }"
  553. >{{ item.params.desc }}</span>
  554. </div>
  555. </div>
  556. <!-- 操作工具栏 -->
  557. <div class="action-tools">
  558. <div class="tools-content">
  559. <div class="tools-item" v-for="(itm, idx) in actionTools(item, index)" :key="idx">
  560. <a-tooltip placement="right" :getPopupContainer="() => $refs['phone-content']">
  561. <span class="tooltip-text" slot="title">{{ itm.title }}</span>
  562. <div
  563. class="item-btn"
  564. :class="{ disabled: itm.disabled }"
  565. @click.stop="handleActionToolItem(itm, index)"
  566. >
  567. <a-icon class="tools-icon" :type="itm.type" />
  568. </div>
  569. </a-tooltip>
  570. </div>
  571. </div>
  572. </div>
  573. </div>
  574. </draggable>
  575. </div>
  576. </div>
  577. </template>
  578. <script>
  579. import PropTypes from 'ant-design-vue/es/_util/vue-types'
  580. import draggable from 'vuedraggable'
  581. import { inArray } from '@/utils/util'
  582. import * as PageIcon from '@/assets/icons/page'
  583. import * as Icon from '@/core/icons'
  584. import { UTag } from './modules'
  585. // 禁止拖拽的组件
  586. const undragList = ['service']
  587. export default {
  588. props: {
  589. // 页面数据
  590. data: PropTypes.object.def({}),
  591. // 当前选中的元素索引
  592. selectedIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).def(0)
  593. },
  594. components: {
  595. draggable,
  596. UTag
  597. },
  598. data () {
  599. return {
  600. // 禁止拖拽的组件
  601. undragList
  602. }
  603. },
  604. computed: {
  605. },
  606. beforeCreate () {
  607. this.Icon = Icon
  608. this.PageIcon = PageIcon
  609. this.inArray = inArray
  610. },
  611. methods: {
  612. /**
  613. * 操作工具栏
  614. * @param item
  615. * @param index
  616. */
  617. actionTools (item, index) {
  618. const { data: { items } } = this
  619. const isUndrag = inArray(item.type, undragList)
  620. return [
  621. {
  622. title: '上移',
  623. type: 'up',
  624. disabled: isUndrag || index == 0 || inArray(items[index - 1].type, undragList)
  625. },
  626. {
  627. title: '下移',
  628. type: 'down',
  629. disabled: isUndrag || items.length <= index + 1 || inArray(items[index + 1].type, undragList)
  630. },
  631. {
  632. title: '复制',
  633. type: 'copy',
  634. disabled: false
  635. },
  636. {
  637. title: '删除',
  638. type: 'delete',
  639. disabled: false
  640. }
  641. ]
  642. },
  643. /**
  644. * 拖动diy元素更新当前索引
  645. * @param e
  646. */
  647. handelDragItem (e) {
  648. this.$emit('onEditer', e.newIndex)
  649. },
  650. /**
  651. * 点击当前选中的Diy元素
  652. * @param index
  653. */
  654. handelClickItem (index) {
  655. this.$emit('onEditer', index)
  656. },
  657. // 操作工具栏点击事件
  658. handleActionToolItem (acItem, index) {
  659. !acItem.disabled && this.$emit('onActionItem', acItem.type, index)
  660. },
  661. // 渲染组件外层容器的样式
  662. renderItemStyle (item) {
  663. if (item.type === 'service') {
  664. return {
  665. position: 'absolute',
  666. right: item.style.right + 'px',
  667. bottom: item.style.bottom + 'px',
  668. zIndex: 999
  669. }
  670. }
  671. return {}
  672. }
  673. }
  674. }
  675. </script>
  676. <style lang="less" scoped>
  677. @import './style.less';
  678. </style>