简易模板精简

master
toesbieya 6 years ago
parent e4c2151603
commit 78ce11a336
  1. 51
      vue/template/src/component/Empty/DefaultEmptyImage.vue
  2. 40
      vue/template/src/component/Empty/index.vue
  3. 47
      vue/template/src/component/Empty/style.scss
  4. 24
      vue/template/src/component/abstract/Dialog/LoadingMask.vue
  5. 48
      vue/template/src/component/abstract/Dialog/index.vue
  6. 18
      vue/template/src/component/abstract/Dialog/style.scss
  7. 24
      vue/template/src/component/abstract/Form/index.vue
  8. 25
      vue/template/src/component/abstract/Form/item.vue
  9. 28
      vue/template/src/component/abstract/Pagination/index.vue
  10. 32
      vue/template/src/component/abstract/Table/index.vue
  11. 39
      vue/template/src/globalMethod/Guide/index.js
  12. 237
      vue/template/src/globalMethod/Guide/main.vue
  13. 70
      vue/template/src/globalMethod/Guide/style.scss
  14. 106
      vue/template/src/globalMethod/Guide/utils.js
  15. 32
      vue/template/src/globalMethod/SignautreBoard/index.js
  16. 161
      vue/template/src/globalMethod/SignautreBoard/main.vue
  17. 4
      vue/template/src/globalMethod/index.js
  18. 45
      vue/template/src/layout/component/Navbar/index.vue
  19. 10
      vue/template/src/router/module/example/child/globalMethod.js
  20. 31
      vue/template/src/util/tree.js
  21. 12
      vue/template/src/util/worker.js
  22. 64
      vue/template/src/view/example/globalMethod/guidePage.vue
  23. 31
      vue/template/src/view/example/globalMethod/signaturePage.vue

@ -1,51 +0,0 @@
<script type="text/jsx">
export default {
name: 'DefaultEmptyImage',
functional: true,
render() {
return (
<svg width="184" height="152" viewBox="0 0 184 152" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fillRule="evenodd">
<g transform="translate(24 31.67)">
<ellipse
fillOpacity=".8"
fill="#F5F5F7"
cx="67.797"
cy="106.89"
rx="67.797"
ry="12.668"
/>
<path
d="M122.034 69.674L98.109 40.229c-1.148-1.386-2.826-2.225-4.593-2.225h-51.44c-1.766 0-3.444.839-4.592 2.225L13.56 69.674v15.383h108.475V69.674z"
fill="#AEB8C2"
/>
<path
d="M101.537 86.214L80.63 61.102c-1.001-1.207-2.507-1.867-4.048-1.867H31.724c-1.54 0-3.047.66-4.048 1.867L6.769 86.214v13.792h94.768V86.214z"
fill="url(#linearGradient-1)"
transform="translate(13.56)"
/>
<path
d="M33.83 0h67.933a4 4 0 0 1 4 4v93.344a4 4 0 0 1-4 4H33.83a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4z"
fill="#F5F5F7"
/>
<path
d="M42.678 9.953h50.237a2 2 0 0 1 2 2V36.91a2 2 0 0 1-2 2H42.678a2 2 0 0 1-2-2V11.953a2 2 0 0 1 2-2zM42.94 49.767h49.713a2.262 2.262 0 1 1 0 4.524H42.94a2.262 2.262 0 0 1 0-4.524zM42.94 61.53h49.713a2.262 2.262 0 1 1 0 4.525H42.94a2.262 2.262 0 0 1 0-4.525zM121.813 105.032c-.775 3.071-3.497 5.36-6.735 5.36H20.515c-3.238 0-5.96-2.29-6.734-5.36a7.309 7.309 0 0 1-.222-1.79V69.675h26.318c2.907 0 5.25 2.448 5.25 5.42v.04c0 2.971 2.37 5.37 5.277 5.37h34.785c2.907 0 5.277-2.421 5.277-5.393V75.1c0-2.972 2.343-5.426 5.25-5.426h26.318v33.569c0 .617-.077 1.216-.221 1.789z"
fill="#DCE0E6"
/>
</g>
<path
d="M149.121 33.292l-6.83 2.65a1 1 0 0 1-1.317-1.23l1.937-6.207c-2.589-2.944-4.109-6.534-4.109-10.408C138.802 8.102 148.92 0 161.402 0 173.881 0 184 8.102 184 18.097c0 9.995-10.118 18.097-22.599 18.097-4.528 0-8.744-1.066-12.28-2.902z"
fill="#DCE0E6"
/>
<g transform="translate(149.65 15.383)" fill="#FFF">
<ellipse cx="20.654" cy="3.167" rx="2.849" ry="2.815"/>
<path d="M5.698 5.63H0L2.898.704zM9.259.704h4.985V5.63H9.259z"/>
</g>
</g>
</svg>
)
}
}
</script>

@ -1,40 +0,0 @@
<script type="text/jsx">
/**
* 从ant-design-vue处拷贝
*/
import DefaultEmptyImage from "./DefaultEmptyImage"
export default {
name: "AEmpty",
functional: true,
props: {
description: String,
image: [String, Object],
imageStyle: [String, Object]
},
render(h, context) {
const {description = '暂无数据', image, imageStyle} = context.props
const prefixCls = 'ant-empty'
const cls = {[prefixCls]: true}
let imageNode = null
if (typeof image === 'string') {
imageNode = <img alt={description} src={image}/>
}
else imageNode = <DefaultEmptyImage/>
return (
<div class={cls} {...{on: context.listeners}}>
<div class={`${prefixCls}-image`} style={imageStyle}>{imageNode}</div>
{description && <p class={`${prefixCls}-description`}>{description}</p>}
{context.children && <div class={`${prefixCls}-footer`}>{context.children}</div>}
</div>
)
}
}
</script>
<style lang="scss" src="./style.scss"></style>

@ -1,47 +0,0 @@
.ant-empty {
padding: 20px;
margin: 0 8px;
font-size: 14px;
line-height: 22px;
text-align: center;
&-image {
height: 100px;
margin-bottom: 8px;
img {
height: 100%;
}
svg {
height: 100%;
margin: auto;
}
}
&-description {
margin: 0;
}
&-footer {
margin-top: 16px;
}
&-normal {
margin: 32px 0;
color: rgba(0, 0, 0, .25);
.ant-empty-image {
height: 40px;
}
}
&-small {
margin: 8px 0;
color: rgba(0, 0, 0, .25);
.ant-empty-image {
height: 35px;
}
}
}

@ -1,24 +0,0 @@
<script type="text/jsx">
export default {
name: "LoadingMask",
functional: true,
props: {show: Boolean},
render(h, context) {
if (context.props.show) {
return (
<div class="el-loading-mask">
<div class="el-loading-spinner">
<svg viewBox="25 25 50 50" class="circular">
<circle cx="50" cy="50" r="20" fill="none" class="path"/>
</svg>
<p>加载中...</p>
</div>
</div>
)
}
}
}
</script>

@ -1,48 +0,0 @@
<script type="text/jsx">
import cssVariables from '@/asset/style/variables.scss'
import LoadingMask from './LoadingMask'
export default {
name: "AbstractDialog",
functional: true,
props: {
value: Boolean,
loading: {type: Boolean, default: true},
width: {type: String, default: '30%'}
},
render(h, context) {
const {data, children, listeners, props: {value, loading, width}} = context
const onClose = function () {
return listeners.close ? () => listeners.close(false) : () => ({})
}()
return (
<el-dialog
v-drag-dialog
visible={value}
custom-class="abstract-dialog"
top={cssVariables.dialogTop}
width={width}
on-close={onClose}
{...data}
>
<div class="abstract-dialog-container">
<LoadingMask show={loading}/>
<el-scrollbar>
<div class="abstract-dialog-body">
{children}
</div>
<div style="margin-bottom: 17px"/>
</el-scrollbar>
</div>
</el-dialog>
)
}
}
</script>
<style lang="scss" src="./style.scss"></style>

@ -1,18 +0,0 @@
.abstract-dialog {
.el-dialog__body {
padding: 0;
}
.abstract-dialog-container {
position: relative;
width: 100%;
.abstract-dialog-body {
padding: 24px 24px 0
}
.el-form {
padding: 0;
}
}
}

@ -1,24 +0,0 @@
<script type="text/jsx">
export default {
name: "AbstractForm",
functional: true,
render(h, context) {
const {data, children} = context
return (
<el-form
ref="form"
label-position="right"
label-width="100px"
label-suffix=":"
size="small"
status-icon
{...data}
>
<el-row>{children}</el-row>
</el-form>
)
}
}
</script>

@ -1,25 +0,0 @@
<script type="text/jsx">
export default {
name: "AbstractFormItem",
functional: true,
props: {full: Boolean, thin: Boolean, label: String, prop: String},
render(h, context) {
const {full, thin, label, prop} = context.props
let props = {xs: 24, sm: 12, lg: 8}
if (full) props = {span: 24}
else if (thin) props.lg = 12
return (
<el-col {...{props}}>
<el-form-item label={label} prop={prop}>
{context.children}
</el-form-item>
</el-col>
)
}
}
</script>

@ -1,28 +0,0 @@
<script type="jsx">
export default {
name: "AbstractPagination",
functional: true,
props: {
model: {
type: Object,
default: () => ({total: 0, page: 1, pageSize: 15})
}
},
render(h, context) {
const {model: {total, page, pageSize}} = context.props
return (
<el-pagination
background
current-page={page}
page-size={pageSize}
total={total}
layout="total, prev, pager, next, jumper"
{...context.data}
/>
)
}
}
</script>

@ -1,32 +0,0 @@
<script type="text/jsx">
import Empty from "@/component/Empty"
export default {
name: "AbstractTable",
functional: true,
render(h, context) {
const {data, children} = context
if (!data.scopedSlots) {
data.scopedSlots = {}
}
if (!data.scopedSlots.empty) {
data.scopedSlots.empty = () => <Empty/>
}
return (
<el-table
ref="table"
current-row-key="id"
row-key="id"
highlight-current-row
{...data}
>
{children}
</el-table>
)
}
}
</script>

@ -1,39 +0,0 @@
import Vue from 'vue'
import Main from './main.vue'
import {mergeObj} from "@/util"
const GuideConstructor = Vue.extend(Main)
let instance
const defaultOptions = {
stageBackground: '#ffffff',
doneBtnText: '完成',
closeBtnText: '关闭',
nextBtnText: '下一步',
prevBtnText: '上一步',
}
const guide = function (steps, index, beforeExit) {
if (instance) instance.exit()
else {
instance = new GuideConstructor({data: {options: defaultOptions}})
instance.$mount()
document.body.appendChild(instance.$el)
}
instance.steps = steps
instance.beforeExit = beforeExit
this.$nextTick(() => instance.start(index))
}
guide.config = function (config) {
mergeObj(defaultOptions, config)
}
guide.exit = function (force) {
instance && instance.exit(force)
}
export default guide

@ -1,237 +0,0 @@
<template>
<div>
<el-popover ref="popover" :value="showPopover" trigger="manual">
<div class="guide-popover-container">
<div v-html="step.content"/>
<div class="guide-popover-action">
<div class="action-close">
<el-button size="mini" type="dashed" plain @click="exit">
{{ hasDone ? step.doneBtnText : step.closeBtnText }}
</el-button>
</div>
<div class="action-step">
<el-button v-if="showPrevBtn" class="prev-btn" size="mini" plain @click="previous">
{{ step.prevBtnText }}
</el-button>
<el-button v-if="showNextBtn" class="next-btn" size="mini" plain @click="next">
{{ step.nextBtnText }}
</el-button>
</div>
</div>
</div>
<div slot="reference" v-show="showStage" id="guide-stage" :style="stageStyle"/>
</el-popover>
<div v-if="showStage" id="guide-highlight-element-cover" :style="stageStyle" @click.prevent.stop/>
<div v-if="showOverlay" id="guide-overlay"/>
</div>
</template>
<script>
/**
* 由driver.js改造而来
*/
import {debounce, isEmpty, deepClone} from "@/util"
import {addHighlightClasses, getCalculatedPosition, removeHighlightClasses} from "./utils"
export default {
name: "Guide",
data() {
return {
steps: [],
options: {},
beforeExit: null,
isActive: false,
showStage: false,
showOverlay: false,
currentStep: 0,
moving: false,
stageStyle: '',
highlightedElement: null,
lastHighlightedElement: null
}
},
computed: {
showPopover() {
return !this.moving && this.showStage
},
showPrevBtn() {
return this.step.forceShowPrevBtn || this.currentStep > 0 && this.steps[this.currentStep - 1]
},
showNextBtn() {
return this.step.forceShowNextBtn || this.steps[this.currentStep + 1]
},
hasDone() {
return this.currentStep === this.steps.length - 1
},
step() {
if (!this.isActive || this.steps.length <= 0 || !this.steps[this.currentStep]) {
return {}
}
return {
...this.options,
...this.steps[this.currentStep],
index: this.currentStep
}
}
},
watch: {
isActive(v) {
document.body.classList[v ? 'add' : 'remove']('overflow-hidden')
}
},
methods: {
start(index = 0) {
if (!this.steps || this.steps.length === 0) throw new Error('请传入步骤')
if (index === 'last') index = this.steps.length - 1
else if (index === 'first') index = 0
if (index > this.steps.length - 1 || !this.steps[index]) {
console.error('error index:', index, 'error steps:', deepClone(this.steps))
throw new Error('起始步骤有误')
}
this.isActive = true
this.currentStep = index
this.showOverlay = false
this.showStage = false
this.$_highlight()
this.showOverlay = true
this.showStage = true
},
exit(force) {
if (!this.isActive) return
if (!force && this.beforeExit) {
const result = this.beforeExit(this.hasDone)
if (result && result.then) {
result.then(this.$_clear)
}
else result !== false && this.$_clear()
return
}
this.$_clear()
},
previous() {
if (!this.isActive || this.moving) return
this.moving = true
if (this.step.onPrevious) {
const result = this.step.onPrevious()
if (result && result.then) {
result.then(this.$_movePrevious, this.$_moveEnd)
}
else result ? this.$_movePrevious() : this.$_moveEnd()
}
else this.$_movePrevious()
},
next() {
if (!this.isActive || this.moving) return
this.moving = true
if (this.step.onNext) {
const result = this.step.onNext()
if (result && result.then) {
result.then(this.$_moveNext, this.$_moveEnd)
}
else result ? this.$_moveNext() : this.$_moveEnd()
}
else this.$_moveNext()
},
resize() {
if (!this.highlightedElement) return
this.$_setStageStyle(getCalculatedPosition(this.highlightedElement))
this.$nextTick(this.$refs.popover.updatePopper)
},
$_movePrevious() {
if (!this.isActive) return
this.currentStep--
this.$_highlight()
},
$_moveNext() {
if (!this.isActive) return
this.currentStep++
this.$_highlight()
},
$_moveEnd() {
this.$refs.popover.updatePopper()
this.moving = false
},
$_clear() {
if (!this.isActive) return
this.isActive = false
this.showOverlay = false
this.showStage = false
this.currentStep = 0
this.steps = []
this.beforeExit = null
this.highlightedElement && removeHighlightClasses(this.highlightedElement)
this.highlightedElement = null
this.lastHighlightedElement = null
},
$_highlight() {
if (isEmpty(this.step.element)) throw new Error(`step${this.currentStep}中element为空`)
const el = document.querySelector(this.step.element)
if (!el) throw new Error(`${this.step.element} 没有该元素`)
if (el === this.highlightedElement) return
this.highlightedElement && removeHighlightClasses(this.highlightedElement)
this.lastHighlightedElement = this.highlightedElement
this.highlightedElement = el
el.scrollIntoView({block: 'center'})
this.$_setStageStyle(getCalculatedPosition(el))
window.setTimeout(() => {
this.$_moveEnd()
this.step.onHighlighted && this.step.onHighlighted()
}, 300)
addHighlightClasses(el)
},
$_setStageStyle({top, left, right, bottom}) {
const width = right - left
const height = bottom - top
this.stageStyle =
`width:${width}px;` +
`height:${height}px;` +
`top:${top}px;` +
`left:${left}px;` +
`background-color:${this.step.stageBackground}`
}
},
mounted() {
this.resize = debounce(this.resize)
window.addEventListener('resize', this.resize)
this.$once('hook:beforeDestroy', () => {
window.removeEventListener('resize', this.resize)
})
}
}
</script>
<style lang="scss" src="./style.scss"></style>

@ -1,70 +0,0 @@
.guide-highlighted-element {
z-index: 1002 !important;
}
.guide-position-relative {
position: relative !important;
}
.guide-fix-stacking {
z-index: auto !important;
opacity: 1.0 !important;
transform: none !important;
filter: none !important;
perspective: none !important;
transform-style: flat !important;
will-change: unset !important;
}
.guide-popover-container {
min-width: 300px;
.guide-popover-action {
position: relative;
height: 100%;
width: 100%;
margin-top: 20px;
.action-close {
display: inline-block;
}
.action-step {
display: inline-block;
right: 0;
position: absolute;
.prev-btn {
position: absolute;
right: 90px;
}
}
}
}
#guide-stage {
position: absolute;
background: white;
transition: all 0.3s;
z-index: 1001 !important;
border-radius: 2px;
/*background: transparent !important;
outline: 5000px solid rgba(0, 0, 0, 0.75);*/
}
#guide-overlay {
background: black;
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
opacity: 0.75;
z-index: 1000 !important;
}
#guide-highlight-element-cover {
position: absolute;
background: transparent !important;
z-index: 1003 !important;
}

@ -1,106 +0,0 @@
const CLASS_HIGHLIGHTED_ELEMENT = 'guide-highlighted-element'
const CLASS_POSITION_RELATIVE = 'guide-position-relative'
const CLASS_FIX_STACKING_CONTEXT = 'guide-fix-stacking'
export function getStyleProperty(element, propertyName, prefixVendor = false) {
if (prefixVendor) {
const prefixes = ['', '-webkit-', '-ms-', 'moz-', '-o-']
for (let counter = 0; counter < prefixes.length; counter++) {
const prefixedProperty = prefixes[counter] + propertyName
const foundValue = getStyleProperty(element, prefixedProperty)
if (foundValue) return foundValue
}
return ''
}
let propertyValue = ''
if (element.currentStyle) {
propertyValue = element.currentStyle[propertyName]
}
else if (document.defaultView && document.defaultView.getComputedStyle) {
propertyValue =
document
.defaultView
.getComputedStyle(element, null)
.getPropertyValue(propertyName)
}
return propertyValue && propertyValue.toLowerCase ? propertyValue.toLowerCase() : propertyValue
}
export function removeHighlightClasses(element) {
element.classList.remove(CLASS_HIGHLIGHTED_ELEMENT)
element.classList.remove(CLASS_POSITION_RELATIVE)
const stackFixes = document.querySelectorAll(`.${CLASS_FIX_STACKING_CONTEXT}`)
for (let counter = 0; counter < stackFixes.length; counter++) {
stackFixes[counter].classList.remove(CLASS_FIX_STACKING_CONTEXT)
}
}
export function addHighlightClasses(element) {
element.classList.add(CLASS_HIGHLIGHTED_ELEMENT)
if (canMakeRelative(element)) {
element.classList.add(CLASS_POSITION_RELATIVE)
}
fixStackingContext(element)
}
export function getCalculatedPosition(element) {
const body = document.body
const documentElement = document.documentElement
const scrollTop = window.pageYOffset || documentElement.scrollTop || body.scrollTop
const scrollLeft = window.pageXOffset || documentElement.scrollLeft || body.scrollLeft
const elementRect = element.getBoundingClientRect()
return ({
top: elementRect.top + scrollTop,
left: elementRect.left + scrollLeft,
right: elementRect.left + scrollLeft + elementRect.width,
bottom: elementRect.top + scrollTop + elementRect.height,
})
}
function canMakeRelative(element) {
const currentPosition = getStyleProperty(element, 'position')
const avoidPositionsList = ['absolute', 'fixed', 'relative']
return avoidPositionsList.indexOf(currentPosition) === -1
}
function fixStackingContext(element) {
let parentNode = element.parentNode
while (parentNode) {
if (!parentNode.tagName || parentNode.tagName.toLowerCase() === 'body') {
break
}
const zIndex = getStyleProperty(parentNode, 'z-index')
const opacity = parseFloat(getStyleProperty(parentNode, 'opacity'))
const transform = getStyleProperty(parentNode, 'transform', true)
const transformStyle = getStyleProperty(parentNode, 'transform-style', true)
const transformBox = getStyleProperty(parentNode, 'transform-box', true)
const filter = getStyleProperty(parentNode, 'filter', true)
const perspective = getStyleProperty(parentNode, 'perspective', true)
if (
/[0-9]+/.test(zIndex)
|| opacity < 1
|| (transform && transform !== 'none')
|| (transformStyle && transformStyle !== 'flat')
|| (transformBox && transformBox !== 'border-box')
|| (filter && filter !== 'none')
|| (perspective && perspective !== 'none')
) {
parentNode.classList.add(CLASS_FIX_STACKING_CONTEXT)
}
parentNode = parentNode.parentNode
}
}

@ -1,32 +0,0 @@
import Vue from 'vue'
import Main from './main.vue'
const Constructor = Vue.extend(Main)
let instance
const signature = function ({image, lineWidth = 6, lineColor = '#000000', onConfirm}) {
if (instance) instance.close()
else {
instance = new Constructor().$mount()
document.body.appendChild(instance.$el)
}
instance.image = image
instance.lineWidth = lineWidth
instance.lineColor = lineColor
instance.onConfirm = onConfirm
instance.init()
instance.visible = true
return instance
}
signature.close = function () {
if (instance) {
instance.close()
instance = null
}
}
export default signature

@ -1,161 +0,0 @@
<template>
<div v-show="visible" class="signature-board">
<canvas
ref="canvas"
@mousedown.prevent="drawStart"
@mousemove.prevent="drawMove"
@mouseup.prevent="drawEnd"
@touchstart.prevent="drawStart"
@touchmove.prevent="drawMove"
@touchend.prevent="drawEnd"
/>
<div class="signature-board__footer">
<el-button plain size="small" @click="clear"> </el-button>
<el-button plain size="small" @click="close"> </el-button>
<el-button size="small" type="primary" @click="confirm"> </el-button>
</div>
</div>
</template>
<script>
/*
* 突然发现没办法做到竖屏横屏都支持坑爹
* */
function getEventPoint(e) {
let x, y
if (['mousedown', 'mousemove'].includes(e.type)) {
x = e.clientX - e.target.offsetLeft
y = e.clientY - e.target.offsetTop
}
else {
x = e.changedTouches[0].clientX - e.target.offsetLeft
y = e.changedTouches[0].clientY - e.target.offsetTop
}
return {x, y}
}
export default {
name: 'SignatureBoard',
props: {
image: String,
lineWidth: Number,
lineColor: String,
onConfirm: Function
},
data() {
return {
visible: false,
drew: false,
drawing: false,
startX: 0,
startY: 0
}
},
methods: {
drawStart(e) {
const {x, y} = getEventPoint(e)
this.drew = true
this.drawing = true
this.startX = x
this.startY = y
this.ctx.strokeStyle = this.lineColor
this.ctx.lineWidth = this.lineWidth
},
drawMove(e) {
if (!this.drawing) return
const {x, y} = getEventPoint(e)
this.ctx.beginPath()
this.ctx.moveTo(this.startX, this.startY)
this.ctx.lineTo(x, y)
this.ctx.stroke()
this.ctx.closePath()
this.startY = y
this.startX = x
},
drawEnd() {
this.drawing = false
},
getBase64() {
if (!this.drew) return null
return this.$refs.canvas.toDataURL()
},
resize() {
const canvas = this.$refs.canvas
canvas.height = window.innerHeight
canvas.width = window.innerWidth
},
init() {
this.resize()
this.ctx = this.$refs.canvas.getContext('2d')
this.ctx.lineCap = 'round'
this.ctx.lineJoin = 'round'
if (this.image) {
let img = new Image()
img.src = this.image
img.onload = () => {
this.ctx.drawImage(img, 0, 0, img.width, img.height)
this.drew = true
img = null
}
}
},
clear() {
this.drew = false
this.drawing = false
this.$refs.canvas && (this.$refs.canvas.height = window.innerHeight)
},
close() {
this.visible = false
this.clear()
},
confirm() {
this.onConfirm && this.onConfirm(this.getBase64())
this.visible = false
}
},
mounted() {
window.addEventListener('resize', this.resize)
this.$once('hook:beforeDestroy', () => {
this.clear()
window.removeEventListener('resize', this.resize)
})
}
}
</script>
<style lang="scss">
.signature-board {
position: fixed;
background-color: #ffffff;
top: 0;
right: 0;
height: 100vh;
width: 100vw;
z-index: 100;
overflow: hidden;
&__footer {
position: absolute;
bottom: 20px;
right: 20px;
}
}
</style>

@ -1,11 +1,7 @@
import Guide from './Guide'
import ImageViewer from './ImageViewer'
import Verify from './Verify'
import Signature from './SignautreBoard'
export default function (Vue) {
Vue.prototype.$guide = Guide
Vue.prototype.$image = ImageViewer
Vue.prototype.$verify = Verify
Vue.prototype.$signature = Signature
}

@ -16,28 +16,6 @@ export default {
components: {HeadMenu, Logo},
data() {
return {
guideSteps: [
{
element: '.setting-btn.navbar-item',
content: '这是个性设置按钮,可以根据自己喜好进行一些设置',
},
{
element: '.navbar .el-dropdown.navbar-item',
content: '这是用户中心',
},
{
element: '.tags-view-container',
content: `<p>这是tab栏,可以右键tab页进行相关操作</p>
<p>ctrl + 可以进行tab页的左右切换</p>
<p>当tab过多时通过鼠标滚轮来滚动</p>
<p>双击可以关闭</p>`,
},
]
}
},
computed: {
...mapState('user', ['avatar', 'name', 'prepareLogout']),
@ -65,20 +43,9 @@ export default {
methods: {
command(command) {
switch (command) {
case 'user':
const path = '/user'
this.$route.path !== path && this.$router.push(path)
break
case 'guide':
this.$guide(this.guideSteps)
break
case 'logout':
if (!this.prepareLogout) {
elConfirm('确认退出?')
.then(() => this.$store.dispatch('user/logout'))
}
break
if (!this.prepareLogout) {
elConfirm('确认退出?')
.then(() => this.$store.dispatch('user/logout'))
}
},
@ -129,12 +96,6 @@ export default {
class={navbarGetters.theme}
visible-arrow={false}
>
<el-dropdown-item icon="el-icon-user" command="user">
个人中心
</el-dropdown-item>
<el-dropdown-item class="hidden-xs" icon="el-icon-guide" command="guide">
新手指引
</el-dropdown-item>
<el-dropdown-item icon="el-icon-switch-button" command="logout">
退出登录
</el-dropdown-item>

@ -7,21 +7,11 @@ export default {
component: 'example/globalMethod/message',
meta: {title: '消息提示'}
},
{
path: 'guide',
component: 'example/globalMethod/guide',
meta: {title: '导航'}
},
{
path: 'imageViewer',
component: 'example/globalMethod/imageViewer',
meta: {title: '图片预览'}
},
{
path: 'signature',
component: 'example/globalMethod/signature',
meta: {title: '手写签名'}
},
{
path: 'verify',
component: 'example/globalMethod/verify',

@ -1,5 +1,4 @@
import {deepClone} from "@/util"
import {createWorker} from '@/util/worker'
const DEFAULT_PROPS = {
id: 'id',
@ -226,33 +225,3 @@ export function getNodesByBfs(node) {
return nodes
}
//借助worker生成树
export function createTreeByWorker(list) {
return new Promise(resolve => {
const worker = createWorker(workerTree, list, ({data}) => {
resolve(data)
worker.terminate()
})
})
}
function workerTree() {
function createTree(list, rootSign = 0, idKey = 'id', pidKey = 'pid', childrenKey = 'children') {
if (!list || list.length <= 0) return []
let info = {}
list.forEach(i => {
i[childrenKey] = []
info[i[idKey]] = i
})
return list.filter(node => {
const key = node[pidKey]
info[key] && info[key][childrenKey].push(node)
return key === rootSign
})
}
self.addEventListener('message', ({data}) => {
self.postMessage(createTree(data))
})
}

@ -1,12 +0,0 @@
export function createWorker(func, data, callback) {
const blob = new Blob(['(' + func.toString() + ')()'])
const url = window.URL.createObjectURL(blob)
const worker = new Worker(url)
worker.onmessage = callback
worker.postMessage(data)
window.URL.revokeObjectURL(url)
return worker
}

@ -1,64 +0,0 @@
<template>
<div>
<div class="tip-row">
基于driver.js改造的用户导航
</div>
<div>
<el-button plain @click="onClick">开始导航</el-button>
</div>
<div id="example-guide-step1" class="example-guide-step">我是步骤1</div>
<div id="example-guide-step2" class="example-guide-step">我是步骤2</div>
<div id="example-guide-step3" class="example-guide-step">我是步骤3</div>
<div id="example-guide-step4" class="example-guide-step">我是步骤4</div>
<div id="example-guide-step5" class="example-guide-step">我是步骤5</div>
</div>
</template>
<script>
import {elSuccess, elConfirm} from "@/util/message"
export default {
name: "guidePage",
methods: {
onClick() {
this.$guide([
{
element: '#example-guide-step1',
content: 'onNext钩子示例',
onNext: () => elConfirm('确认进行下一步吗?', false)
},
{
element: '#example-guide-step2',
content: 'onPrevious钩子展示',
onPrevious: () => elConfirm('确认回到上一步吗?', false)
},
{
element: '#example-guide-step3',
content: 'onHighlighted钩子示例',
onHighlighted: () => elSuccess('到达第三步!')
},
{
element: '#example-guide-step4',
content: `<h1>内容可以是html字符串</h1><img src="https://dss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=4018557288,1217151095&fm=26&gp=0.jpg">`,
},
{
element: '#example-guide-step5',
content: '最后一步',
},
])
}
}
}
</script>
<style scoped>
.example-guide-step {
margin-top: 50px;
height: 200px;
width: 300px;
background-color: blueviolet;
}
</style>

@ -1,31 +0,0 @@
<template>
<div>
<div class="tip-row">
搞了个手写签名竖屏横屏不可兼得
</div>
<div>
<img :src="src" style="width: 100%;height: 500px;object-fit: contain">
</div>
<el-button plain @click="signature">点击签名</el-button>
</div>
</template>
<script>
export default {
name: 'signaturePage',
data() {
return {
src: null
}
},
methods: {
signature() {
this.$signature({
image: this.src, onConfirm: img => this.src = img
})
}
}
}
</script>
Loading…
Cancel
Save