首页编辑器优化

This commit is contained in:
pushuo 2022-07-11 13:57:38 +08:00
parent 4489f28506
commit 39bc33d453
15 changed files with 1046 additions and 14 deletions

View File

@ -36,7 +36,7 @@ class Editor extends Component
'code' => 'slideshow',
'sort' => 0,
'name' => '幻灯片模块',
'icon' => '',
'icon' => '',
];
return view('design.module.slideshow.editor.index', $data);

View File

@ -807,3 +807,73 @@ body.page-account-address .addresses-wrap .item .address-bottom, body.page-check
body.page-account-address .addresses-wrap .item .address-bottom a, body.page-checkout .addresses-wrap .item .address-bottom a {
color: #2d68a8;
}
.module-item {
position: relative;
}
.module-item:hover .module-edit {
display: flex;
}
.module-item:hover:after {
display: block;
}
.module-item:after {
content: "";
display: none;
position: absolute;
left: 2px;
right: 2px;
top: 2px;
bottom: 2px;
outline: 2px solid #fd560f;
}
.module-item .module-edit {
position: absolute;
top: -22px;
left: 0;
width: 100%;
z-index: 9;
align-items: center;
justify-content: center;
display: none;
}
.module-item .module-edit .edit-wrap {
background-color: #fd560f;
color: #fff;
display: flex;
align-items: center;
}
.module-item .module-edit .edit-wrap > div {
height: 24px;
line-height: 24px;
padding: 0 10px;
cursor: pointer;
position: relative;
}
.module-item .module-edit .edit-wrap > div:first-of-type:after {
content: "";
position: absolute;
top: 0;
border: solid rgba(0, 0, 0, 0);
border-right: solid #fd560f;
border-width: 24px 10px 0 0;
right: 100%;
}
.module-item .module-edit .edit-wrap > div:first-of-type:hover:after {
border-right-color: #eb4802;
}
.module-item .module-edit .edit-wrap > div:last-of-type:after {
content: "";
position: absolute;
top: 0;
border: solid rgba(0, 0, 0, 0);
border-left: solid #fd560f;
border-width: 24px 0 0 10px;
left: 100%;
}
.module-item .module-edit .edit-wrap > div:last-of-type:hover:after {
border-left-color: #eb4802;
}
.module-item .module-edit .edit-wrap > div:hover {
background-color: #eb4802;
}

View File

@ -1,7 +1,23 @@
@charset "UTF-8";
@font-face {
font-family: "iconfont";
src: url("/vendor/iconfont/iconfont.woff") format("woff"), url("/vendor/iconfont/iconfont.ttf") format("truetype");
/* chrome、firefox、opera、Safari, Android, iOS 4.2+*/
}
.iconfont {
font-family: "iconfont";
font-size: 1rem;
font-style: normal;
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: 0.2px;
-moz-osx-font-smoothing: grayscale;
}
body.page-design {
background-color: #fff;
padding: 0;
margin: 0;
font-size: 14px;
height: 100vh;
overflow: hidden;
}
@ -9,9 +25,64 @@ body.page-design .design-box {
display: flex;
height: 100vh;
}
body.page-design .design-box .design-head {
display: flex;
align-items: center;
justify-content: space-between;
}
body.page-design .design-box .design-head > div {
flex: 1;
height: 40px;
color: #fff;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
background-color: #0072ff;
text-align: center;
font-size: 0.8rem;
transition: all 0.2s ease-in-out;
}
body.page-design .design-box .design-head > div:hover {
background-color: #005bcc;
}
body.page-design .design-box .sidebar-edit-wrap {
width: 300px;
background-color: #fff;
}
body.page-design .design-box .sidebar-edit-wrap .module-edit {
padding: 0 10px 14px;
}
body.page-design .design-box .sidebar-edit-wrap .module-edit .module-editor-row {
height: 47px;
line-height: 47px;
background-color: #f5f5f5;
padding: 0 20px;
margin: 0 -14px 14px;
font-size: 16px;
color: #212121;
}
body.page-design .design-box .sidebar-edit-wrap .module-edit .module-edit-group {
margin-bottom: 20px;
}
body.page-design .design-box .sidebar-edit-wrap .module-edit .module-edit-group:last-of-type {
border-bottom: none;
}
body.page-design .design-box .sidebar-edit-wrap .module-edit .module-edit-group .module-edit-title {
margin-bottom: 10px;
position: relative;
padding-left: 6px;
display: flex;
justify-content: space-between;
}
body.page-design .design-box .sidebar-edit-wrap .module-edit .module-edit-group .module-edit-title:before {
content: "";
position: absolute;
left: 0;
top: 3px;
width: 2px;
height: 14px;
background: #0072ff;
}
body.page-design .design-box .sidebar-edit-wrap .modules-list {
background: #e6e9ec;
@ -34,7 +105,7 @@ body.page-design .design-box .sidebar-edit-wrap .module-list .module-info:hover
box-shadow: 0 6px 23px rgba(0, 0, 0, 0.2);
}
body.page-design .design-box .sidebar-edit-wrap .module-list .icon {
padding: 7px 0;
padding: 12px 0 7px;
width: 36px;
height: 36px;
display: inline-block;
@ -54,3 +125,96 @@ body.page-design .design-box .sidebar-edit-wrap .module-list .name {
body.page-design .design-box .preview-iframe {
flex: 1;
}
body.page-design .pb-images-selector {
border: 1px solid #eee;
margin-bottom: 10px;
border-radius: 2px;
}
body.page-design .pb-images-selector:hover {
border-color: #ddd;
}
body.page-design .pb-images-selector:hover .selector-head {
background: #eee;
}
body.page-design .pb-images-selector .pb-images-selector-add {
width: 100%;
margin-top: 16px;
padding: 10px 20px;
}
body.page-design .pb-images-selector .selector-head {
display: flex;
align-items: center;
background-color: #f5f5f5;
padding: 4px 10px;
cursor: pointer;
justify-content: space-between;
}
body.page-design .pb-images-selector .selector-head > div.left {
display: flex;
align-items: center;
}
body.page-design .pb-images-selector .selector-head > div.left i {
margin-right: 10px;
}
body.page-design .pb-images-selector .selector-head > div.left img {
width: 24px;
}
body.page-design .pb-images-selector .selector-head > div.right {
display: flex;
align-items: center;
}
body.page-design .pb-images-selector .selector-head > div.right i {
color: #999;
font-size: 20px;
}
body.page-design .pb-images-selector .selector-head > div.right .remove-item {
margin-right: 8px;
padding-right: 8px;
position: relative;
}
body.page-design .pb-images-selector .selector-head > div.right .remove-item:after {
content: "";
border-right: 1px solid #ccc;
position: absolute;
right: 1px;
top: 20%;
height: 60%;
}
body.page-design .pb-images-selector .selector-head > div.right .remove-item i {
font-size: 15px;
}
body.page-design .pb-images-selector .pb-images-list {
padding: 7px;
padding-bottom: 8px;
position: relative;
display: none;
}
body.page-design .pb-images-selector .pb-images-list.active {
display: block;
}
body.page-design .pb-images-selector .pb-images-list .remove-item {
margin-top: 20px;
background: #ffc8c8;
color: #c70000;
z-index: 9;
height: 20px;
line-height: 20px;
padding: 5px 10px;
text-align: center;
cursor: pointer;
}
body.page-design .pb-images-selector .pb-images-list .remove-item i {
font-size: 14px;
}
body.page-design .pb-images-selector .pb-images-list .pb-image-selector {
cursor: pointer;
min-width: 50px;
min-height: 50px;
}
body.page-design .pb-images-selector .pb-images-list .pb-images-btns button {
margin-left: 0 !important;
padding: 9px 10px;
}
body.page-design .pb-images-selector .pb-images-list .el-input-group__prepend {
padding: 0 10px;
}

2
public/vendor/vue/Sortable.min.js vendored Normal file

File diff suppressed because one or more lines are too long

407
public/vendor/vue/vuedraggable.js vendored Normal file
View File

@ -0,0 +1,407 @@
'use strict';
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
(function () {
"use strict";
if (!Array.from) {
Array.from = function (object) {
return [].slice.call(object);
};
}
function buildAttribute(object, propName, value) {
if (value == undefined) {
return object;
}
object = object == null ? {} : object;
object[propName] = value;
return object;
}
function buildDraggable(Sortable) {
function removeNode(node) {
node.parentElement.removeChild(node);
}
function insertNodeAt(fatherNode, node, position) {
var refNode = position === 0 ? fatherNode.children[0] : fatherNode.children[position - 1].nextSibling;
fatherNode.insertBefore(node, refNode);
}
function computeVmIndex(vnodes, element) {
return vnodes.map(function (elt) {
return elt.elm;
}).indexOf(element);
}
function _computeIndexes(slots, children, isTransition) {
if (!slots) {
return [];
}
var elmFromNodes = slots.map(function (elt) {
return elt.elm;
});
var rawIndexes = [].concat(_toConsumableArray(children)).map(function (elt) {
return elmFromNodes.indexOf(elt);
});
return isTransition ? rawIndexes.filter(function (ind) {
return ind !== -1;
}) : rawIndexes;
}
function emit(evtName, evtData) {
var _this = this;
this.$nextTick(function () {
return _this.$emit(evtName.toLowerCase(), evtData);
});
}
function delegateAndEmit(evtName) {
var _this2 = this;
return function (evtData) {
if (_this2.realList !== null) {
_this2['onDrag' + evtName](evtData);
}
emit.call(_this2, evtName, evtData);
};
}
var eventsListened = ['Start', 'Add', 'Remove', 'Update', 'End'];
var eventsToEmit = ['Choose', 'Sort', 'Filter', 'Clone'];
var readonlyProperties = ['Move'].concat(eventsListened, eventsToEmit).map(function (evt) {
return 'on' + evt;
});
var draggingElement = null;
var props = {
options: Object,
list: {
type: Array,
required: false,
default: null
},
value: {
type: Array,
required: false,
default: null
},
noTransitionOnDrag: {
type: Boolean,
default: false
},
clone: {
type: Function,
default: function _default(original) {
return original;
}
},
element: {
type: String,
default: 'div'
},
move: {
type: Function,
default: null
},
componentData: {
type: Object,
required: false,
default: null
}
};
var draggableComponent = {
name: 'draggable',
props: props,
data: function data() {
return {
transitionMode: false,
noneFunctionalComponentMode: false,
init: false
};
},
render: function render(h) {
var slots = this.$slots.default;
if (slots && slots.length === 1) {
var child = slots[0];
if (child.componentOptions && child.componentOptions.tag === "transition-group") {
this.transitionMode = true;
}
}
var children = slots;
var footer = this.$slots.footer;
if (footer) {
children = slots ? [].concat(_toConsumableArray(slots), _toConsumableArray(footer)) : [].concat(_toConsumableArray(footer));
}
var attributes = null;
var update = function update(name, value) {
attributes = buildAttribute(attributes, name, value);
};
update('attrs', this.$attrs);
if (this.componentData) {
var _componentData = this.componentData,
on = _componentData.on,
_props = _componentData.props;
update('on', on);
update('props', _props);
}
return h(this.element, attributes, children);
},
mounted: function mounted() {
var _this3 = this;
this.noneFunctionalComponentMode = this.element.toLowerCase() !== this.$el.nodeName.toLowerCase();
if (this.noneFunctionalComponentMode && this.transitionMode) {
throw new Error('Transition-group inside component is not supported. Please alter element value or remove transition-group. Current element value: ' + this.element);
}
var optionsAdded = {};
eventsListened.forEach(function (elt) {
optionsAdded['on' + elt] = delegateAndEmit.call(_this3, elt);
});
eventsToEmit.forEach(function (elt) {
optionsAdded['on' + elt] = emit.bind(_this3, elt);
});
var options = _extends({}, this.options, optionsAdded, { onMove: function onMove(evt, originalEvent) {
return _this3.onDragMove(evt, originalEvent);
} });
!('draggable' in options) && (options.draggable = '>*');
this._sortable = new Sortable(this.rootContainer, options);
this.computeIndexes();
},
beforeDestroy: function beforeDestroy() {
this._sortable.destroy();
},
computed: {
rootContainer: function rootContainer() {
return this.transitionMode ? this.$el.children[0] : this.$el;
},
isCloning: function isCloning() {
return !!this.options && !!this.options.group && this.options.group.pull === 'clone';
},
realList: function realList() {
return !!this.list ? this.list : this.value;
}
},
watch: {
options: {
handler: function handler(newOptionValue) {
for (var property in newOptionValue) {
if (readonlyProperties.indexOf(property) == -1) {
this._sortable.option(property, newOptionValue[property]);
}
}
},
deep: true
},
realList: function realList() {
this.computeIndexes();
}
},
methods: {
getChildrenNodes: function getChildrenNodes() {
if (!this.init) {
this.noneFunctionalComponentMode = this.noneFunctionalComponentMode && this.$children.length == 1;
this.init = true;
}
if (this.noneFunctionalComponentMode) {
return this.$children[0].$slots.default;
}
var rawNodes = this.$slots.default;
return this.transitionMode ? rawNodes[0].child.$slots.default : rawNodes;
},
computeIndexes: function computeIndexes() {
var _this4 = this;
this.$nextTick(function () {
_this4.visibleIndexes = _computeIndexes(_this4.getChildrenNodes(), _this4.rootContainer.children, _this4.transitionMode);
});
},
getUnderlyingVm: function getUnderlyingVm(htmlElt) {
var index = computeVmIndex(this.getChildrenNodes() || [], htmlElt);
if (index === -1) {
//Edge case during move callback: related element might be
//an element different from collection
return null;
}
var element = this.realList[index];
return { index: index, element: element };
},
getUnderlyingPotencialDraggableComponent: function getUnderlyingPotencialDraggableComponent(_ref) {
var __vue__ = _ref.__vue__;
if (!__vue__ || !__vue__.$options || __vue__.$options._componentTag !== "transition-group") {
return __vue__;
}
return __vue__.$parent;
},
emitChanges: function emitChanges(evt) {
var _this5 = this;
this.$nextTick(function () {
_this5.$emit('change', evt);
});
},
alterList: function alterList(onList) {
if (!!this.list) {
onList(this.list);
} else {
var newList = [].concat(_toConsumableArray(this.value));
onList(newList);
this.$emit('input', newList);
}
},
spliceList: function spliceList() {
var _arguments = arguments;
var spliceList = function spliceList(list) {
return list.splice.apply(list, _arguments);
};
this.alterList(spliceList);
},
updatePosition: function updatePosition(oldIndex, newIndex) {
var updatePosition = function updatePosition(list) {
return list.splice(newIndex, 0, list.splice(oldIndex, 1)[0]);
};
this.alterList(updatePosition);
},
getRelatedContextFromMoveEvent: function getRelatedContextFromMoveEvent(_ref2) {
var to = _ref2.to,
related = _ref2.related;
var component = this.getUnderlyingPotencialDraggableComponent(to);
if (!component) {
return { component: component };
}
var list = component.realList;
var context = { list: list, component: component };
if (to !== related && list && component.getUnderlyingVm) {
var destination = component.getUnderlyingVm(related);
if (destination) {
return _extends(destination, context);
}
}
return context;
},
getVmIndex: function getVmIndex(domIndex) {
var indexes = this.visibleIndexes;
var numberIndexes = indexes.length;
return domIndex > numberIndexes - 1 ? numberIndexes : indexes[domIndex];
},
getComponent: function getComponent() {
return this.$slots.default[0].componentInstance;
},
resetTransitionData: function resetTransitionData(index) {
if (!this.noTransitionOnDrag || !this.transitionMode) {
return;
}
var nodes = this.getChildrenNodes();
nodes[index].data = null;
var transitionContainer = this.getComponent();
transitionContainer.children = [];
transitionContainer.kept = undefined;
},
onDragStart: function onDragStart(evt) {
this.context = this.getUnderlyingVm(evt.item);
evt.item._underlying_vm_ = this.clone(this.context.element);
draggingElement = evt.item;
},
onDragAdd: function onDragAdd(evt) {
var element = evt.item._underlying_vm_;
if (element === undefined) {
return;
}
removeNode(evt.item);
var newIndex = this.getVmIndex(evt.newIndex);
this.spliceList(newIndex, 0, element);
this.computeIndexes();
var added = { element: element, newIndex: newIndex };
this.emitChanges({ added: added });
},
onDragRemove: function onDragRemove(evt) {
insertNodeAt(this.rootContainer, evt.item, evt.oldIndex);
if (this.isCloning) {
removeNode(evt.clone);
return;
}
var oldIndex = this.context.index;
this.spliceList(oldIndex, 1);
var removed = { element: this.context.element, oldIndex: oldIndex };
this.resetTransitionData(oldIndex);
this.emitChanges({ removed: removed });
},
onDragUpdate: function onDragUpdate(evt) {
removeNode(evt.item);
insertNodeAt(evt.from, evt.item, evt.oldIndex);
var oldIndex = this.context.index;
var newIndex = this.getVmIndex(evt.newIndex);
this.updatePosition(oldIndex, newIndex);
var moved = { element: this.context.element, oldIndex: oldIndex, newIndex: newIndex };
this.emitChanges({ moved: moved });
},
computeFutureIndex: function computeFutureIndex(relatedContext, evt) {
if (!relatedContext.element) {
return 0;
}
var domChildren = [].concat(_toConsumableArray(evt.to.children)).filter(function (el) {
return el.style['display'] !== 'none';
});
var currentDOMIndex = domChildren.indexOf(evt.related);
var currentIndex = relatedContext.component.getVmIndex(currentDOMIndex);
var draggedInList = domChildren.indexOf(draggingElement) != -1;
return draggedInList || !evt.willInsertAfter ? currentIndex : currentIndex + 1;
},
onDragMove: function onDragMove(evt, originalEvent) {
var onMove = this.move;
if (!onMove || !this.realList) {
return true;
}
var relatedContext = this.getRelatedContextFromMoveEvent(evt);
var draggedContext = this.context;
var futureIndex = this.computeFutureIndex(relatedContext, evt);
_extends(draggedContext, { futureIndex: futureIndex });
_extends(evt, { relatedContext: relatedContext, draggedContext: draggedContext });
return onMove(evt, originalEvent);
},
onDragEnd: function onDragEnd(evt) {
this.computeIndexes();
draggingElement = null;
}
}
};
return draggableComponent;
}
if (typeof exports == "object") {
var Sortable = require("sortablejs");
module.exports = buildDraggable(Sortable);
} else if (typeof define == "function" && define.amd) {
define(['sortablejs'], function (Sortable) {
return buildDraggable(Sortable);
});
} else if (window && window.Vue && window.Sortable) {
var draggable = buildDraggable(window.Sortable);
Vue.component('draggable', draggable);
}
})();

View File

@ -20,3 +20,4 @@ $primary: #fd560f;
@import './order-success';
@import './page-account-order';
@import './page-account-address';
@import './home';

View File

@ -1,7 +1,12 @@
@import '../iconfont';
$main_color: #0072ff;
body.page-design {
background-color: #fff;
padding: 0;
margin: 0;
font-size: 14px;
height: 100vh;
overflow: hidden;
@ -9,10 +14,78 @@ body.page-design {
display: flex;
height: 100vh;
.design-head {
display: flex;
align-items: center; // flex-start | center
justify-content: space-between; // flex-end | center | space-between
// flex-wrap: wrap;
> div {
flex: 1;
height: 40px;
color: #fff;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
background-color: $main_color;
text-align: center;
font-size: .8rem;
transition: all .2s ease-in-out;
&:hover {
background-color: darken($main_color, 10%);
}
}
}
.sidebar-edit-wrap {
// flex: 1;
width: 300px;
background-color: #f5f5f5;
background-color: #fff;
.module-edit {
padding: 0 10px 14px;
.module-editor-row {
height: 47px;
line-height: 47px;
background-color: #f5f5f5;
padding: 0 20px;
margin: 0 -14px 14px;
font-size: 16px;
color: #212121;
}
.module-edit-group {
margin-bottom: 20px;
&:last-of-type {
border-bottom: none;
}
.module-edit-title {
margin-bottom: 10px;
position: relative;
padding-left: 6px;
display: flex;
justify-content: space-between;
&:before {
content: '';
position: absolute;
left: 0;
top: 3px;
width: 2px;
height: 14px;
background: #0072ff;
}
}
.module-edit-sub-title {
}
}
}
.modules-list {
background: #e6e9ec;
@ -38,7 +111,7 @@ body.page-design {
}
.icon {
padding: 7px 0;
padding: 12px 0 7px;
width: 36px;
height: 36px;
display: inline-block;
@ -64,4 +137,121 @@ body.page-design {
flex: 1;
}
}
.pb-images-selector {
border: 1px solid #eee;
margin-bottom: 10px;
border-radius: 2px;
// overflow: hidden;
&:hover {
border-color: #ddd;
.selector-head {
background: #eee;
}
}
.pb-images-selector-add {
width: 100%;
margin-top: 16px;
padding: 10px 20px;
}
.selector-head {
display: flex;
align-items: center;
background-color: #f5f5f5;
padding: 4px 10px;
cursor: pointer;
justify-content: space-between;
> div.left {
display: flex;
align-items: center;
i {
margin-right: 10px;
}
img {
width: 24px;
}
}
> div.right {
display: flex;
align-items: center;
i {
color: #999;
font-size: 20px;
}
.remove-item {
margin-right: 8px;
padding-right: 8px;
position: relative;
&:after {
content: '';
border-right: 1px solid #ccc;
position: absolute;
right: 1px;
top: 20%;
height: 60%;
}
i {
font-size: 15px;
}
}
}
}
.pb-images-list {
padding: 7px;
padding-bottom: 8px;
position: relative;
display: none;
&.active {
display: block;
}
.pb-image-selector {
}
.remove-item {
margin-top: 20px;
background: #ffc8c8;
color: #c70000;
z-index: 9;
height: 20px;
line-height: 20px;
padding: 5px 10px;
text-align: center;
cursor: pointer;
i {
font-size: 14px;
}
}
.pb-image-selector {
cursor: pointer;
min-width: 50px;
min-height: 50px;
// background: #f5f5f5;
}
.pb-images-btns button {
margin-left: 0 !important;
padding: 9px 10px;
}
.el-input-group__prepend {
padding: 0 10px;
}
}
}
}

View File

@ -0,0 +1,94 @@
@charset "UTF-8";
.module-item {
position: relative;
&:hover {
.module-edit {
display: flex;
}
&:after {
display: block;
}
}
&:after {
content: '';
display: none;
position: absolute;
left: 2px;
right: 2px;
top: 2px;
bottom: 2px;
outline: 2px solid $primary;
}
.module-edit {
// position: relative;
position: absolute;
top: -22px;
left: 0;
width: 100%;
z-index: 9;
// display: flex;
align-items: center; // flex-start | center
justify-content: center; // flex-end | center | space-between
display: none;
.edit-wrap {
background-color: $primary;
color: #fff;
display: flex;
align-items: center;
> div {
height: 24px;
line-height: 24px;
padding: 0 10px;
cursor: pointer;
position: relative;
&:first-of-type {
&:after {
content: "";
position: absolute;
top: 0;
border: solid #0000;
border-right: solid $primary;
border-width: 24px 10px 0 0;
right: 100%;
}
&:hover {
&:after {
border-right-color: darken($primary, 6%);
}
}
}
&:last-of-type {
&:after {
content: "";
position: absolute;
top: 0;
border: solid #0000;
border-left: solid $primary;
border-width: 24px 0 0 10px;
left: 100%;
}
&:hover {
&:after {
border-left-color: darken($primary, 6%);
}
}
}
&:hover {
background-color: darken($primary, 6%);
}
}
// flex-wrap: wrap;
}
}
}

View File

@ -12,6 +12,8 @@
<script src="{{ asset('vendor/layer/3.5.1/layer.js') }}"></script>
<script src="{{ asset('/build/beike/shop/default/js/app.js') }}"></script>
<script src="{{ asset('vendor/vue/2.6.14/vue.js') }}"></script>
<script src="{{ asset('vendor/vue/Sortable.min.js') }}"></script>
<script src="{{ asset('vendor/vue/vuedraggable.js') }}"></script>
<script src="{{ asset('vendor/element-ui/2.15.6/js.js') }}"></script>
<link rel="stylesheet" href="{{ asset('vendor/element-ui/2.15.6/css.css') }}">
<link rel="stylesheet" type="text/css" href="{{ asset('/build/beike/shop/default/css/design/app.css') }}">
@ -21,6 +23,10 @@
<body class="page-design">
<div class="design-box">
<div class="sidebar-edit-wrap" id="app" v-cloak>
<div class="design-head">
<div>保存</div>
<div>退出</div>
</div>
<div class="module-edit" v-if="form.modules.length > 0 && design.editType == 'module'">
<component
:is="editingModuleComponent"
@ -34,7 +40,7 @@
<el-col :span="12" v-for="(item, index) in source.modules" :key="index">
<div @click="addModuleButtonClicked(item.code)" class="module-list">
<div class="module-info">
<div class="icon"><img src="https://via.placeholder.com/100x100.png/dddddd" class="img-fluid"></div>
<div class="icon"><i class="iconfont" v-html="item.icon"></i></div>
<div class="name">@{{ item.name }}</div>
</div>
</div>
@ -96,7 +102,17 @@
methods: {
moduleUpdated() {
console.log('moduleUpdated')
}
},
addModuleButtonClicked(code) {
console.log(code)
},
// 编辑模块
editModuleButtonClicked(index) {
this.design.editingModuleIndex = index;
this.design.editType = 'module';
},
},
// 在实例初始化之后组件属性计算之前如data属性等
beforeCreate () {
@ -111,6 +127,13 @@
mounted () {
},
})
window.addEventListener('message', (event) => {
event.stopPropagation()
if (typeof(event.data.index) !== 'undefined') {
app.editModuleButtonClicked(event.data.index)
}
}, false)
</script>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -1,6 +1,50 @@
<template id="module-editor-slideshow-template">
<div>
<div><h6>slideshow-template</h6></div>
<div class="module-editor-row">设置</div>
<div class="module-edit-group">
<div class="module-edit-title">是否全屏</div>
<el-switch v-model="module.full"></el-switch>
</div>
<div class="module-editor-row">内容</div>
<div class="module-edit-group">
<div class="module-edit-title">选择图片</div>
<draggable
ghost-class="dragabble-ghost"
:list="module.images"
:options="{animation: 330}"
>
<div class="pb-images-selector" v-for="(item, index) in module.images" :key="index">
<div class="selector-head" @click="itemShow(index)">
<div class="left">
<el-tooltip class="icon-rank" effect="dark" content="上下拖动排序" placement="left">
<i class="el-icon-rank"></i>
</el-tooltip>
{{-- <img :src="thumbnail(item.image[{{ helper.current_language_id() }}], 40, 40)" class="img-responsive"> --}}
</div>
<div class="right">
<el-tooltip class="" effect="dark" content="删除" placement="left">
<div class="remove-item" @click.stop="removeImage(index)"><i class="iconfont">&#xe63a;</i></div>
</el-tooltip>
<i :class="'fa fa-angle-'+(item.show ? 'up' : 'down')"></i>
</div>
</div>
<div :class="'pb-images-list ' + (item.show ? 'active' : '')">
<div class="pb-images-top">
{{-- <pb-image-selector v-model="item.image"></pb-image-selector> --}}
<div class="tag">建议尺寸 1920 x 600</div>
</div>
{{-- <link-selector v-model="item.link"></link-selector> --}}
</div>
</div>
</draggable>
<div class="add-item">
<el-button type="primary" size="small" @click="addImage" icon="el-icon-circle-plus-outline">添加图片</el-button>
</div>
</div>
</div>
</template>
@ -17,7 +61,16 @@ Vue.component('module-editor-slideshow', {
data: function () {
return {
//
// full: true
}
},
watch: {
module: {
handler: function (val) {
this.$emit('on-changed', val);
},
deep: true
}
},
@ -26,7 +79,18 @@ Vue.component('module-editor-slideshow', {
},
methods: {
//
removeImage(index) {
this.module.images.splice(index, 1);
},
itemShow(index) {
this.module.images.find((e, key) => {if (index != key) return e.show = false});
this.module.images[index].show = !this.module.images[index].show;
},
addImage() {
this.module.images.find(e => e.show = false);
this.module.images.push({image: 'catalog/demo/slideshow/2.jpg', show: true, link: {type: 'product', value:''}});
}
}
});
</script>

View File

@ -1 +1,13 @@
<h1>slideshow</h1>
<section class="module-item" id="module-dasuybkdas">
<div class="module-edit">
<div class="edit-wrap">
<div class=""><i class="bi bi-chevron-down"></i></div>
<div class=""><i class="bi bi-chevron-up"></i></div>
<div class="delete"><i class="bi bi-x-lg"></i></div>
<div class="edit"><i class="bi bi-pencil-square"></i></div>
</div>
</div>
<div class="module-info">
<img src="{{ asset('image/default/banner.png') }}" class="img-fluid">
</div>
</section>

View File

@ -7,6 +7,13 @@
<x-dynamic-component :component="$render"/>
@endforeach
<script>
$(function() {
$(document).on('click', '.module-edit .edit', function(event) {
window.parent.postMessage({index: 0}, '*')
});
});
</script>
{{-- <section class="module-wrap mb-5"><img src="{{ asset('image/default/banner.png') }}" class="img-fluid"></section> --}}
{{-- @foreach ($categories as $category)
<a href="{{ shop_route('categories.show', $category) }}">{{ $category->description->name }}</a>

View File

@ -4,7 +4,7 @@
@section('content')
<div class="container">
<div class="container" id="checkout-app">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="#">Home</a></li>
@ -56,9 +56,6 @@
<div class="quantity-btns d-flex">
@include('shared.quantity', ['quantity' => '1'])
{{-- <div class="quantity-wrap">
<input class="form-control quantity-input" type="number" value="1">
</div> --}}
<button class="btn btn-outline-secondary ms-3 add-cart"><i class="bi bi-cart-fill me-1"></i>加入购物车</button>
<button class="btn btn-dark ms-3"><i class="bi bi-bag-fill me-1"></i>立即购买</button>
</div>
@ -100,6 +97,7 @@
layer.msg(res.message)
})
});
</script>
@endsection