szydiy.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. //最外层组件
  2. var componentHtml = '<div v-show="data.lazyLoadCss && data.lazyLoad">';
  3. componentHtml += '<div class="preview-draggable">';//拖拽区域
  4. componentHtml += '<slot name="preview"></slot>';
  5. componentHtml += '<i class="del" v-show="parseInt(data.is_delete) !== 1" v-on:click.stop="$parent.delComponent(data.index)" data-disabled="1">x</i>';
  6. componentHtml += '</div>';
  7. componentHtml += '<div class="edit-attribute" v-bind:data-have-edit="1" v-show="$parent.currentIndex==data.index">';// && $slots.edit
  8. componentHtml += '<div class="attr-wrap">';
  9. componentHtml += '<div class="restore-wrap">';
  10. componentHtml += '<h2 class="attr-title">{{data.name}}</h2>';
  11. componentHtml += '<slot name="edit"></slot>';
  12. componentHtml += '</div>';
  13. componentHtml += '</div>';
  14. componentHtml += '</div>';
  15. componentHtml += '<div style="display:none;">';
  16. componentHtml += '<slot name="resource"></slot>';
  17. componentHtml += '</div>';
  18. componentHtml += '</div>';
  19. var commonComponent = {
  20. props: ["data"],
  21. template: componentHtml,
  22. created: function () {
  23. //如果当前添加的组件没有添加过资源
  24. if (!this.$slots.resource) {
  25. this.data.lazyLoadCss = true;
  26. this.data.lazyLoad = true;
  27. } else {
  28. //检测是否只添加了JS或者CSS,没有添加默认为true
  29. var countCss = 0, countJs = 0, outerCountJs = 0;
  30. for (var i = 0; i < this.$slots.resource.length; i++) {
  31. if (this.$slots.resource[i].componentOptions) {
  32. if (this.$slots.resource[i].componentOptions.tag == "css") {
  33. countCss++;
  34. } else if (this.$slots.resource[i].componentOptions.tag == "js") {
  35. countJs++;
  36. //统计外部JS数量
  37. if (!$.isEmptyObject(this.$slots.resource[i].componentOptions.propsData)) outerCountJs++;
  38. }
  39. }
  40. }
  41. if (countCss == 0) this.data.lazyLoadCss = true;
  42. if (countJs == 0) this.data.lazyLoad = true;
  43. this.data.outerCountJs = outerCountJs;
  44. }
  45. }
  46. };
  47. //cm-construct
  48. var vue = new Vue({
  49. el: "#modify-view",
  50. data: {
  51. //当前编辑的组件位置
  52. currentIndex: -99,
  53. changeIndex: -1,
  54. isAdd: false,
  55. globalLazyLoad: false, //全局设置是为了页面设置这个独特组件
  56. //全局属性
  57. global: global ? global : {
  58. title: "页面名称",
  59. bgColor: "#f6f6f6",
  60. topNavColor: "#ffffff",
  61. topNavbg: false,
  62. textNavColor: "#000000",
  63. topNavImg: "",
  64. moreLink: {},
  65. //是否显示底部导航标识
  66. openBottomNav: false,
  67. navStyle: 1,
  68. textImgStyleLink: '1',
  69. textImgPosLink: 'center',
  70. mpCollect: false,
  71. bgUrl: '',
  72. // 弹框形式,不弹出 -1,首次弹出 1,每次弹出 0
  73. popWindow: {
  74. imageUrl: "",
  75. count: -1,
  76. link: {},
  77. imgWidth: '',
  78. imgHeight: ''
  79. },
  80. },
  81. textImgPositionList: [{
  82. text: "居左",
  83. value: "left",
  84. src: "/static/images/diy/nav/text_left.png",
  85. selectedSrc: "/static/images/diy/nav/text_left_hover.png"
  86. },
  87. {
  88. text: "居中",
  89. value: "center",
  90. src: "/static/images/diy/nav/text_right.png",
  91. selectedSrc: "/static/images/diy/nav/text_right_hover.png"
  92. }
  93. ],
  94. data: [],
  95. loaded: false
  96. },
  97. components: {
  98. 'cm-construct': commonComponent, //剥离当前data. 循环时这么处理佳
  99. },
  100. created:function(){
  101. console.log(this.data)
  102. },
  103. mounted: function () {
  104. this.refreshSort();
  105. this.loaded = true;
  106. },
  107. methods: {
  108. /**
  109. *
  110. * @param {*} obj 组件参数数据
  111. * @param {*} options 其他属性
  112. * @returns
  113. */
  114. addSzyComponent: function (obj, options) {
  115. obj.index = 0;
  116. obj.sort = 0;
  117. obj.lazyLoadCss = false;
  118. obj.lazyLoad = false;
  119. obj.outerCountJs = 0;
  120. if (options) {
  121. obj.addon_name = options.addon_name;
  122. obj.type = options.name;
  123. obj.name = options.title;
  124. obj.controller = options.controller;
  125. obj.is_delete = options.is_delete;
  126. }
  127. //1、检测是否添加到最大数量
  128. if (options && !this.checkComponentIsAdd(obj.type, options.max_count)) {
  129. this.autoSelected(obj.type); //自动选中这个元素
  130. return;
  131. }
  132. this.data.push(obj);
  133. //选中最后一个对象作为当前索引
  134. if (options) {
  135. this.currentIndex = this.data.length - 1;
  136. }
  137. this.isAdd = true;
  138. this.refreshSort();
  139. var self = this;
  140. $(".edit-attribute-placeholder").show();
  141. setTimeout(function () {
  142. $(".edit-attribute-placeholder").hide();
  143. if (obj.controller == "FloatBtn") {} else {
  144. if (self.changeIndex == -1 || (self.changeIndex != self.currentIndex)) {
  145. $(".preview-div .preview-screen .view-wrap").scrollTop($(".screen_center").height());
  146. }
  147. }
  148. }, 60);
  149. // console.log(this.data)
  150. },
  151. checkComponentIsAdd: function (type, max_count) {
  152. //判断添加数量是否最大
  153. //max_count为0时不处理
  154. if (max_count == 0) return true;
  155. var count = 0;
  156. //遍历已添加的自定义组件,检测是否超出数量
  157. for (var i in this.data) {
  158. if (this.data[i].type == type) count++;
  159. }
  160. if (count >= max_count) { return false; } else { return true; }
  161. },
  162. //改变当前编辑的组件选中
  163. changeCurrentIndex: function (sort) {
  164. this.currentIndex = parseInt(sort);
  165. this.changeIndex = this.currentIndex;
  166. this.isAdd = false;
  167. this.refreshSort();
  168. },
  169. autoSelected(type) {
  170. //选中这个类型的对象
  171. for (var i in this.data) {
  172. if (this.data[i].type == type) {
  173. this.changeCurrentIndex(this.data[i].index);
  174. var element = $('.preview-box .preview-div [data-index="' + this.data[i].index + '"]'),
  175. warp = $(".preview-box .preview-div .preview-screen"),
  176. warpTop = warp.offset().top,
  177. warpBottom = warpTop + warp.height(),
  178. elementTop = element.offset().top,
  179. elementBottom = elementTop + element.height(),
  180. scrollTop = $(".preview-box .preview-div .preview-screen").scrollTop();
  181. if (elementBottom > warpBottom) {
  182. scrollTop += (elementBottom - warpBottom) + 2;
  183. } else if (warpTop > elementTop) {
  184. scrollTop -= (warpTop - elementTop);
  185. }
  186. $(".preview-box .preview-div .preview-screen").animate({
  187. scrollTop: scrollTop
  188. }, 300);
  189. return;
  190. }
  191. }
  192. },
  193. refreshSort: function () {
  194. var self = this;
  195. setTimeout(function () {
  196. $(".draggable-element").each(function (i) {
  197. $(this).attr("data-sort", i);
  198. });
  199. for (var i = 0; i < self.data.length; i++) {
  200. self.data[i].index = $(".draggable-element[data-index=" + i + "]").attr("data-index");
  201. self.data[i].sort = $(".draggable-element[data-index=" + i + "]").attr("data-sort");
  202. }
  203. self.data.push({});
  204. self.data.pop();
  205. //如果当前编辑的组件不存在了,则选中最后一个
  206. if (parseInt(self.currentIndex) >= self.data.length) self.currentIndex--;
  207. $(".draggable-element[data-index=" + self.currentIndex + "] .edit-attribute .attr-wrap").css("height", ($(window).height() - 140) + "px");
  208. if (self.isAdd && self.changeIndex > -1 && (self.changeIndex != self.currentIndex) && self.changeIndex < (self.data.length - 1)) {
  209. var curr = $(".draggable-element[data-index=" + self.changeIndex + "]");
  210. var last = $(".draggable-element[data-index=" + (self.data.length - 1) + "]");
  211. curr.after(last);
  212. self.changeIndex = self.currentIndex;
  213. }
  214. // 显示插件添加的数量,防止一进入看到代码
  215. $(".js-component-add-count").show();
  216. }, 50);
  217. },
  218. //改变当前的删除弹出框的显示状态
  219. delComponent: function (i) {
  220. var self = this;
  221. layer.confirm('确定要删除吗?', {
  222. title: '操作提示'
  223. }, function (index) {
  224. self.data.splice(i, 1);
  225. //删除当前组件后,选中最后一个组件进行编辑
  226. if (self.data[self.data.length - 1]) {
  227. self.currentIndex = $(".draggable-element:last").attr("data-index");
  228. self.refreshSort();
  229. }
  230. layer.close(index);
  231. });
  232. },
  233. submitVerify: function () {
  234. if (this.global.title == "") {
  235. layer.msg('请输入页面名称');
  236. this.currentIndex = -99;
  237. this.refreshSort();
  238. return false;
  239. } else if (this.global.title.length > 50) {
  240. layer.msg('页面名称最多50个字符');
  241. this.currentIndex = -99;
  242. this.refreshSort();
  243. return false;
  244. }
  245. // if (this.global.popWindow.count != -1 && this.global.popWindow.imageUrl == '') {
  246. // layer.msg('请上传弹框广告');
  247. // this.currentIndex = -99;
  248. // this.refreshSort();
  249. // return false;
  250. // }
  251. for (var i = 0; i < this.data.length; i++) {
  252. try {
  253. if (this.data[i].verify) {
  254. for (var j = 0; j < this.data[i].verify.length; j++) {
  255. var res = this.data[i].verify[j]();
  256. if (!res.code) {
  257. this.currentIndex = i;
  258. this.refreshSort();
  259. layer.msg(res.message);
  260. return false;
  261. }
  262. }
  263. }
  264. } catch (e) {
  265. console.log("verify Error:" + e, i, this.data[i]);
  266. }
  267. }
  268. return true;
  269. },
  270. //转换图片路径
  271. changeImgUrl: function (url) {
  272. if (url == null || url == "") { return ''; }
  273. else return url;
  274. }
  275. }
  276. })
  277. // 拖拽事件
  278. $('.screen_center').DDSort({
  279. //拖拽数据源
  280. target: '.draggable-element',
  281. //拖拽时显示的样式
  282. floatStyle: {
  283. 'border': '1px solid #FF6A00',
  284. 'background-color': '#ffffff'
  285. },
  286. //设置可拖拽区域
  287. draggableArea: "preview-draggable",
  288. //拖拽中,隐藏右侧编辑属性栏
  289. move: function (index) {
  290. if ($(".draggable-element[data-index='" + index + "'] .edit-attribute").attr("data-have-edit") == 1)
  291. $(".draggable-element[data-index='" + index + "'] .edit-attribute").hide();
  292. },
  293. //拖拽结束后,选择当前拖拽,并且显示右侧编辑属性栏,刷新数据
  294. up: function (index) {
  295. if ($(".draggable-element[data-index='" + index + "'] .edit-attribute").attr("data-have-edit") == 1) {
  296. vue.currentIndex = index;
  297. $(".draggable-element[data-index='" + index + "'] .edit-attribute").show();
  298. }
  299. vue.refreshSort();
  300. }
  301. });