no message

Former-commit-id: 0a96bb54e9270e451e59b72e00e35053a7c0e152
Former-commit-id: c250ba90da6546626b9831847630aae786c88344
Former-commit-id: c1182b1bdc6ea9b3934275286a93e2760a643bfe
This commit is contained in:
李杨
2018-01-14 22:51:12 +08:00
parent e667b66cf3
commit 173520d20e
210 changed files with 10281 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
<template>
<div class="container-component">
<!-- [card] 卡片容器 -->
<el-card v-if="type === 'card'">
<div v-if="$slots.header" slot="header">
<slot name="header"></slot>
</div>
<slot></slot>
</el-card>
<!-- [ghost] 隐形的容器 -->
<div v-if="type === 'ghost'">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
props: {
type: {
type: String,
required: false,
default: 'card'
}
}
}
</script>

View File

@@ -0,0 +1,102 @@
<template>
<span></span>
</template>
<script>
import CountUp from 'countup.js'
export default {
props: {
start: {
type: Number,
required: false,
default: 0
},
end: {
type: Number,
required: true
},
decimals: {
type: Number,
required: false,
default: 0
},
duration: {
type: Number,
required: false,
default: 2
},
options: {
type: Object,
required: false,
default () {
return {}
}
},
callback: {
type: Function,
required: false,
default: () => {}
}
},
data () {
return {
c: null
}
},
watch: {
end (value) {
if (this.c && this.c.update) {
this.c.update(value)
}
}
},
mounted () {
this.init()
},
methods: {
init () {
if (!this.c) {
this.c = new CountUp(
this.$el,
this.start,
this.end,
this.decimals,
this.duration,
this.options
)
this.c.start(() => {
this.callback(this.c)
})
}
},
destroy () {
this.c = null
}
},
beforeDestroy () {
this.destroy()
},
start (callback) {
if (this.c && this.c.start) {
this.c.start(() => {
callback && callback(this.c)
})
}
},
pauseResume () {
if (this.c && this.c.pauseResume) {
this.c.pauseResume()
}
},
reset () {
if (this.c && this.c.reset) {
this.c.reset()
}
},
update (newEndVal) {
if (this.c && this.c.update) {
this.c.update(newEndVal)
}
}
}
</script>

View File

@@ -0,0 +1,36 @@
<template>
<pre v-html="highlightHTML"></pre>
</template>
<script>
// https://highlightjs.org/usage/
// http://highlightjs.readthedocs.io/en/latest/api.html#configure-options
import highlight from 'highlight.js'
export default {
props: {
code: {
type: String,
required: false,
default: `console.log('Hello')`
}
},
data () {
return {
highlightHTML: ''
}
},
mounted () {
this.highlight()
},
watch: {
code () {
this.highlight()
}
},
methods: {
highlight () {
this.highlightHTML = highlight.highlightAuto(this.code).value
}
}
}
</script>

View File

@@ -0,0 +1,88 @@
<template>
<el-menu class="el-menu-demo" mode="horizontal">
<el-menu-item index="index" @click.native="active({name: 'index'})">首页</el-menu-item>
<el-menu-item
v-for="(item, index) in menu"
:key="index"
:index="String(index)"
@click.native="active(item)">
{{item.title}}
</el-menu-item>
</el-menu>
</template>
<script>
import { mapMutations } from 'vuex'
import { menu, router } from '@/router/menu/index.js'
export default {
data () {
return {
menu,
router
}
},
computed: {
// 当前路由的name
routeName () {
return this.$route.name
},
// 当前路由是否是顶级菜单
// 顶级菜单就是在顶栏里显示的菜单
// 二级菜单是在侧边栏显示的菜单
// 三级菜单是二级菜单展开的
routeIsTopLevel () {
return !!this.router.find(e => e.name === this.routeName)
},
// 不管当前路由是不是顶级菜单 都返回这个路由所属的顶级菜单对象的name
// 如果返回 undefined 代表这个路由不是在菜单里显示的路由
routeTopLevel () {
if (this.routeIsTopLevel) {
return this.routeName
} else {
const find = this.router.find(e => {
return e.children.find(child => {
return child.name === this.routeName
})
})
return find ? find.name : undefined
}
},
// 返回当前对象对应的顶级菜单 这个菜单可以在侧边栏菜单中直接使用
// 如果返回 undefined 代表这个路由没有对应的一级路由也就没有菜单
routeTopLevelMenu () {
if (this.routeTopLevel) {
return this.menu.find(e => e.name === this.routeTopLevel).children
} else {
return undefined
}
}
},
watch: {
routeName () {
this.doSetSideMenu()
}
},
mounted () {
this.doSetSideMenu()
},
methods: {
...mapMutations([
'setSideMenu'
]),
// 更新一次侧边栏
doSetSideMenu () {
if (this.routeTopLevelMenu) {
this.setSideMenu({
sideMenu: this.routeTopLevelMenu
})
}
},
// 跳转到某个路由
active (item) {
this.$router.push({
name: item.name
})
}
}
}
</script>

View File

@@ -0,0 +1,50 @@
<template>
<el-menu class="el-menu-vertical-demo" v-bind="elMenu">
<el-submenu
v-for="(menu, index) in sideMenu"
:key="index"
:index="`${menu.title}${index}`">
<template slot="title">
<i v-if="menu.icon" :class="'fa fa-' + menu.icon"></i>
<span slot="title">{{menu.title}}</span>
</template>
<el-menu-item
v-for="(menuItem, menuItemIndex) in menu.children"
:key="menuItemIndex"
:index="`${menuItem.name}${menuItemIndex}`"
@click.native="$router.push({name: menuItem.name})">
<i v-if="menu.icon" :class="'fa fa-' + menuItem.icon"></i>
{{menuItem.title}}
</el-menu-item>
</el-submenu>
</el-menu>
</template>
<script>
import { mapState } from 'vuex'
import { menu, router } from '@/router/menu/index.js'
export default {
data () {
return {
menu,
router,
elMenu: {
collapse: false,
uniqueOpened: true
}
}
},
computed: {
...mapState({
sideMenu: state => state.menu.sideMenu
})
}
}
</script>
<style lang="scss">
.el-menu-vertical-demo:not(.el-menu--collapse) {
width: 200px;
min-height: 400px;
}
</style>

View File

@@ -0,0 +1,37 @@
<template>
<el-container class="layout-main" :class="theme">
<el-header>
<HeaderMenu></HeaderMenu>
</el-header>
<el-container>
<el-aside style="width: 200px;">
<SiderMenu></SiderMenu>
</el-aside>
<el-main>
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</template>
<script>
import SiderMenu from '@/components/core/MainLayout/_siderMenu.vue'
import HeaderMenu from '@/components/core/MainLayout/_headerMenu.vue'
export default {
components: {
SiderMenu,
HeaderMenu
},
data () {
return {
theme: 'default'
}
}
}
</script>
<style lang="scss">
// 主题
@import '~@/assets/style/theme/default.scss';
</style>

View File

@@ -0,0 +1,78 @@
<template>
<div class="component-markdown">
<div class="spin-group" v-if="!markedHTML">
<div>正在加载</div>
</div>
<div class="markdown-body" v-html="markedHTML"></div>
</div>
</template>
<script>
import marked from 'marked'
import highlight from 'highlight.js'
export default {
props: {
url: {
type: String,
required: false,
default: ''
},
md: {
type: String,
required: false,
default: ''
}
},
data () {
return {
getReadmePublicPath: '',
markedHTML: ''
}
},
mounted () {
if (this.url) {
this.initWithUrl()
} else if (this.md) {
this.initWithMd()
} else {
console.log('not mounted init')
}
},
methods: {
// 使用 md 初始化
initWithMd () {
this.markedHTML = this.marked(this.md)
console.log(this.markedHTML)
},
// 使用 url 初始化
async initWithUrl () {
this.markedHTML = await this.getReadme(this.url)
},
// 从 url 加载原始数据
async getReadme (name) {
const { data } = await this.$axios.get(name)
return this.marked(data)
},
marked (data) {
return marked(data, {
highlight: (code) => highlight.highlightAuto(code).value
})
}
}
}
</script>
<style lang="scss">
@import '~@/assets/style/public.scss';
.component-markdown {
.spin-group {
height: 100px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
color: $color-primary;
}
}
</style>

View File

@@ -0,0 +1,110 @@
<template>
<div class="markdown-editor">
<textarea></textarea>
</div>
</template>
<script>
import SimpleMDE from 'simplemde'
import marked from 'marked'
export default {
name: 'markdown-editor',
props: {
value: String,
previewClass: String,
autoinit: {
type: Boolean,
default () {
return true
}
},
highlight: {
type: Boolean,
default () {
return false
}
},
sanitize: {
type: Boolean,
default () {
return false
}
},
configs: {
type: Object,
default () {
return {}
}
}
},
mounted () {
if (this.autoinit) this.initialize()
},
activated () {
const editor = this.simplemde
if (!editor) return
const isActive = editor.isSideBySideActive() || editor.isPreviewActive()
if (isActive) editor.toggleFullScreen()
},
methods: {
initialize () {
const configs = {
element: this.$el.firstElementChild,
initialValue: this.value,
renderingConfig: {}
}
Object.assign(configs, this.configs)
// 判断是否开启代码高亮
if (this.highlight) {
configs.renderingConfig.codeSyntaxHighlighting = true
}
// 设置是否渲染输入的html
marked.setOptions({ sanitize: this.sanitize })
// 实例化编辑器
this.simplemde = new SimpleMDE(configs)
// 添加自定义 previewClass
const className = this.previewClass || ''
this.addPreviewClass(className)
// 绑定事件
this.bindingEvents()
},
bindingEvents () {
this.simplemde.codemirror.on('change', () => {
this.$emit('input', this.simplemde.value())
})
},
addPreviewClass (className) {
const wrapper = this.simplemde.codemirror.getWrapperElement()
const preview = document.createElement('div')
wrapper.nextSibling.className += ` ${className}`
preview.className = `editor-preview ${className}`
wrapper.appendChild(preview)
}
},
destroyed () {
this.simplemde = null
},
watch: {
value (val) {
if (val === this.simplemde.value()) return
this.simplemde.value(val)
}
}
}
</script>
<style>
.markdown-editor .markdown-body {
padding: 0.5em
}
.markdown-editor .editor-preview-active, .markdown-editor .editor-preview-active-side {
display: block
}
</style>

View File

@@ -0,0 +1,45 @@
<template>
<div class="markdown-editor">
<textarea ref="mde"></textarea>
</div>
</template>
<script>
import SimpleMDE from 'simplemde'
export default {
data () {
return {
mde: null
}
},
mounted () {
this.init()
},
destroyed () {
this.mde = null
},
methods: {
init () {
this.mde = new SimpleMDE({
element: this.$refs.mde
})
}
}
}
</script>
<style lang="scss">
.markdown-editor {
.markdown-body {
padding: 0.5em;
}
}
.markdown-editor {
.editor-preview-active {
display: block;
}
.editor-preview-active-side {
display: block;
}
}
</style>