首页编辑器优化
This commit is contained in:
parent
4489f28506
commit
39bc33d453
|
|
@ -36,7 +36,7 @@ class Editor extends Component
|
|||
'code' => 'slideshow',
|
||||
'sort' => 0,
|
||||
'name' => '幻灯片模块',
|
||||
'icon' => '',
|
||||
'icon' => '',
|
||||
];
|
||||
|
||||
return view('design.module.slideshow.editor.index', $data);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -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);
|
||||
}
|
||||
})();
|
||||
|
|
@ -20,3 +20,4 @@ $primary: #fd560f;
|
|||
@import './order-success';
|
||||
@import './page-account-order';
|
||||
@import './page-account-address';
|
||||
@import './home';
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 |
|
|
@ -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"></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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue