[release] 4.0.0 (#1291)
* fix[ExternalLink]: fixed bug when url include chinese #1182 * feature: support Spanish(#1196) * fix[MockJS]: fix bug with withCredentials after using mockjs (#1194) * 修复 Mock 导致请求丢失 Cookie 的问题 修复 Mock 导致 Cookie 丢失的问题,只有在 XHR.open() 周期时,自定义的 withCredentials 会被挂载,此时检查是否是未被拦截的 xhr,并挂载自定义的 withCredentials ,无则默认为 false * update readme * perf[tagsView]: refactor the moveToTarget function (#1195) * fix[tagsView]:fixed visited view move to currentTag * edit the scroll regular friendly * tweak * fix[tagsView]: fixed moveToCurrentTag bug * feature: add pagination component (#1213) * fix[TagsView]: fixed update tags title demo bug (#1223) * chore: temporary hack cssnano bug #1222 * [release] 3.9.2 * chore: restore the hack of cssnano bug https://github.com/cssnano/cssnano/issues/643 * add an example of sort data by table (#1236) * feature: add drag select component (#1249) * feat: perfect migrate to @vue/cli-service, upgrade vue babel version (#1267) * feat: perfect migrate to @vue/cli-service, upgrade vue babel version 1. update to @vue/cli-service@3.0.5, @babel/core@7.0.0 2. use vue-cli service replace config file in build/ and config/ 3. upgrade vue and babel configuration 4. solve the svg-sprite config problem #980 refs: #932 #1087 #980 #1056 * fix: fix breadcrumb dependency * fix: fix index template and static assets load with vue-cli 3 * fix: fix import driver.js in guide page * refactor(mock): mak mock api compatible with both web-view and webpack server 1. 把 Mockjs 功能移到 server 端中间件,同时也兼容前端直接劫持 XHR 2. dev 环境下默认作为 express 中间件通过 webpack server 提供 mock api 3. prod 构建时,默认在前端用 Mockjs 劫持 XHR benefits: - dev 开发调试时能直接看到 XHR 请求,方便调试网络,能和后端对接联调 - 避开在开发时因为 Mockjs 引起的网络 bug - prod 构建时劫持 XHR,保证本项目的 Github Pages preview 能正常显示 (逻辑和 error-log 一样) - 前后台使用的 mock 是同一份代码,不会增加维护负担 ref: [#562](https://github.com/PanJiaChen/vue-element-admin/issues/562#issuecomment-378116233) * update requires the lowest version of node * add favicon * fix(TreeTable): fix `Array.prototype.concat` on custom-tree-table page * update * add test * fix bug * fix[Charts]: fixed charts resize mixins bug #1285 (#1290) * perf[Tinymce]: add searchreplace plugin * perf[avatar]:minimize the selected area of avatar on the mobile phone when user clicked avatar (#1304) * refine css * fix[DragSelect]: fixed querySelectorAll bug * perf[DragSelect]: add $listeners * fix link * fix[Breadcurmb]: fixed pathCompile bug * fix[Breadcurmb]: fixed router-link bug * perf[style]: use webpack alias instead of hard code src path (#1338) * perf[style]: use webpack alias instead of hard code src path * add sponsors * fix import path bug * update vue-router to fixed url path for non ascii urls #1362 * fix[Pagination]: apply PageSizes property to el-pagination (#1355) Apply PageSizes property to el-pagination * update dependence * add tui.editor (#1374) * tweak * add preview * fix return back bug * update guide page * fix[Tinymce]: fixed fullScreen bug #1400 * feat[Breadcrumb]: add hide Breadcrumb option #1442 * perf: use WeChat 7.0 new version icon color * refactor[login]: refactor login page style * perf[ScrollPane]: refine moveToTarget code (#1460) * feature[PDF]: add PDF demo (#1469) * perf[v-permission]: refine v-permission demo * perf[Sidebar]: refine sidebar store #1473 (#1474) * refine: GetUserInfo error message * fix typo (#1505) * perf: add sidebar width to variables.scss (#1494) * tweak * fix[ThemePicker]: fixed bug when oldVal is null (#1517) * update README.md * fix[Breadcrumb]: fixed eslint error (#1521) * fix[DndList]: fixed drag bug (#1527) https://github.com/PanJiaChen/vue-element-admin/issues/1524 * pref[Hamburger]: refactor Hamburger component (#1528) * 美化侧栏菜单切换按钮 * tweak * perf[Login Form]: optimize eye icon style (#1545) * optimiz: eye icon style for login form * change eye-open svg * perf[Sticky]: export reset method (#1550) * perf[Sticky]: refine width default value * perf[utils]: refine parseTime function (#1546) * 优化 parseTime 修复传入的时间戳是字符串类型,不能转换时间的问题 例:parseTime("1548221490638") * Update index.js * perf[UploadExcel]: optimized code (#1552) * perf: adjust the import order to make it more elegant #1537 * perf[Sidebar]: use sass variables in vue template * perf[Style]: optimize the sidebar style to make it better to set (#1568) * perf[SizeSelect]: add default size option (#1566) * fix[SIdebar]: fixed bug in mobile #1567 (#1569) * perf: fixed eslint errors * perf[Lang]: make up for miss keywords * perf: optimize some code * perf[Navbar]: refactor navbar style * perf[Login]: refine css * feature[Navbar]: add header-search component(#1591) * fix[Screenfull]: fix screenfull click bug * perf[Screenfull]: refactor screenfull component * fix[Screenfull]: fix screenfull bug (#1603) * fix typo * fearure[TagsView]: add affix option (#1577) * perf[utils]: optimize code * perf[utils]: optimizate variable name * perf[Navbar]: add scroll bar when the subMenu is too long (#1619) * perf[ThemePicker]: refine updateStyle function (#554) * theme replacing should cut tons of irrelevant css * perf[ResizeHandler]: optimized the judgment of isMobile (#1633) perf[ResizeHandler]: optimized the judgment of isMobile * fix[Sidebar]: fixed infinite loop bug(#1333) * fixed infinite loop Bug when in hasOneShowingChild Edit the onlyOneChild * tweak * fix[Sidebar]: data should return a object * perf[Sidebar]: optimize code logic (#1349) * fix[TagsView]: fixed refresh affixed-tag bug (#1653) * perf[utils.js]: refactor byteLength function (#1650) * perf[TagsView]: refine code * perf[TagsView]: set the scrollPane as a business component (#1660) * fix[DragTable]: support multiple drag-table (#1666) * perf[Tree-Table]: refactor tree-table * perf[Tree-Table]: organize the structure and add documentation (#1673) * fix[Sidebar]: fixed nested router hover bug * update version * set preserveWhitespace * lint code * fix jest test case * update config * bump * remove empty file * docs: add link * fix[Sidebar]: fixed collapse animation problem (#1690) * fix[Tree-Table]: fixed update item data bug (#1692) * fix[Waves-Directive]: fixed v-waves does not support update (#1705) * update husky * rm cli-plugin-eslint * add settings (#1707) * refine settings * fix[utils]: fixed param2Obj not decoding plus sign (#1712) * feature[Directive]: add auto-height table directive (#1702) * fix bug * feature[Permission]: add role permission management page (#1605) * feature[Excel]: support export merged header export (#1718) * feature[Excel]: add export merge header excel demo * lint * refine theme color * add role mock * tweak mock * fix[Excel]: fixed export merge-header excel bug * refine code * add ThemePicker to setting * fix[HeaderSearch]: fixed bug in vue2.6+ (#1733) * fix[Sticky]: fixed bug when set stickyTop * perf[Sticky]: refine demo * refine code * tweak mock * vuex add namespaced * fix[Excel]: fixed export bug (#1736) * rm * refactor permission * perf[ThemePicker]: add predefine (#1743) * fix[Utils]: fixed deepClone error msg (#1748) * feature: add fixedHeader settings * fix style in mobile * fix chore * perf[Eslint]: update eslint rules * feature: add create template (#1762) * add comment * update vue.config.js * feature: add sidebar logo (#1767) * rm * perf settings * bump * refine script and css * update * refine settings * refine config * update docs * refine * rm * fix jest * add theme setting * dump vue-cli * perf: remove redundant code * update element-ui * fix sticky demo bug * docs * fixed password input bug * refine login form css * remove tree-table * update version * mock error * refine layout name * refine
This commit is contained in:
@@ -3,11 +3,15 @@
|
||||
<el-tabs v-model="activeName">
|
||||
<el-tab-pane label="use clipboard directly" name="directly">
|
||||
<el-input v-model="inputData" placeholder="Please input" style="width:400px;max-width:100%;" />
|
||||
<el-button type="primary" icon="document" @click="handleCopy(inputData,$event)">copy</el-button>
|
||||
<el-button type="primary" icon="document" @click="handleCopy(inputData,$event)">
|
||||
copy
|
||||
</el-button>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="use clipboard by v-directive" name="v-directive">
|
||||
<el-input v-model="inputData" placeholder="Please input" style="width:400px;max-width:100%;" />
|
||||
<el-button v-clipboard:copy="inputData" v-clipboard:success="clipboardSuccess" type="primary" icon="document">copy</el-button>
|
||||
<el-button v-clipboard:copy="inputData" v-clipboard:success="clipboardSuccess" type="primary" icon="document">
|
||||
copy
|
||||
</el-button>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
|
@@ -25,8 +25,12 @@
|
||||
<label class="label" for="durationInput">duration:
|
||||
<input v-model.number="setDuration" type="number" name="durationInput">
|
||||
</label>
|
||||
<div class="startBtn example-btn" @click="start">开始</div>
|
||||
<div class="pause-resume-btn example-btn" @click="pauseResume">暂停/恢复</div>
|
||||
<div class="startBtn example-btn" @click="start">
|
||||
Start
|
||||
</div>
|
||||
<div class="pause-resume-btn example-btn" @click="pauseResume">
|
||||
pause/resume
|
||||
</div>
|
||||
<br>
|
||||
<label class="label" for="decimalsInput">decimals:
|
||||
<input v-model.number="setDecimals" type="number" name="decimalsInput">
|
||||
@@ -41,11 +45,9 @@
|
||||
<input v-model="setSuffix" name="suffixInput">
|
||||
</label>
|
||||
</div>
|
||||
<code>
|
||||
<count-to :start-val='{{ _startVal }}' :end-val='{{ _endVal }}' :duration='{{ _duration }}'
|
||||
<code><count-to :start-val='{{ _startVal }}' :end-val='{{ _endVal }}' :duration='{{ _duration }}'
|
||||
:decimals='{{ _decimals }}' :separator='{{ _separator }}' :prefix='{{ _prefix }}' :suffix='{{ _suffix }}'
|
||||
:autoplay=false>
|
||||
</code>
|
||||
:autoplay=false></code>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@@ -1,6 +1,8 @@
|
||||
<template>
|
||||
<div class="components-container">
|
||||
<el-button type="primary" @click="dialogTableVisible = true">open a Drag Dialog</el-button>
|
||||
<el-button type="primary" @click="dialogTableVisible = true">
|
||||
open a Drag Dialog
|
||||
</el-button>
|
||||
<el-dialog v-el-drag-dialog :visible.sync="dialogTableVisible" title="Shipping address" @dragDialog="handleDrag">
|
||||
<el-select ref="select" v-model="value" placeholder="请选择">
|
||||
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
|
||||
|
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="components-container board">
|
||||
<Kanban :key="1" :list="list1" :options="options" class="kanban todo" header-text="Todo" />
|
||||
<Kanban :key="2" :list="list2" :options="options" class="kanban working" header-text="Working" />
|
||||
<Kanban :key="3" :list="list3" :options="options" class="kanban done" header-text="Done" />
|
||||
<Kanban :key="1" :list="list1" :group="group" class="kanban todo" header-text="Todo" />
|
||||
<Kanban :key="2" :list="list2" :group="group" class="kanban working" header-text="Working" />
|
||||
<Kanban :key="3" :list="list3" :group="group" class="kanban done" header-text="Done" />
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
@@ -15,9 +15,7 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
options: {
|
||||
group: 'mission'
|
||||
},
|
||||
group: 'mission',
|
||||
list1: [
|
||||
{ name: 'Mission', id: 1 },
|
||||
{ name: 'Mission', id: 2 },
|
||||
|
@@ -1,14 +1,14 @@
|
||||
<template>
|
||||
<div class="components-container">
|
||||
|
||||
<el-drag-select v-model="value" style="width:500px;" multiple placeholder="请选择">
|
||||
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-drag-select>
|
||||
|
||||
<div style="margin-top:30px;">
|
||||
<el-tag v-for="item of value" :key="item" style="margin-right:15px;">{{ item }}</el-tag>
|
||||
<el-tag v-for="item of value" :key="item" style="margin-right:15px;">
|
||||
{{ item }}
|
||||
</el-tag>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@@ -1,6 +1,10 @@
|
||||
<template>
|
||||
<div class="components-container">
|
||||
<code>JsonEditor is base on <a href="https://github.com/codemirror/CodeMirror" target="_blank">CodeMirrorr</a> , lint base on json-lint </code>
|
||||
<code>Json-Editor is base on <a href="https://github.com/codemirror/CodeMirror" target="_blank">CodeMirrorr</a>. Lint
|
||||
base on <a
|
||||
href="https://github.com/codemirror/CodeMirror/blob/master/addon/lint/json-lint.js"
|
||||
target="_blank"
|
||||
>json-lint</a>.</code>
|
||||
<div class="editor-container">
|
||||
<json-editor ref="jsonEditor" v-model="value" />
|
||||
</div>
|
||||
|
@@ -1,41 +1,51 @@
|
||||
<template>
|
||||
<div class="components-container">
|
||||
|
||||
<code>Markdown is based on
|
||||
<a href="https://github.com/nhnent/tui.editor" target="_blank">tui.editor</a> ,Simply encapsulated in Vue.
|
||||
<a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/feature/component/markdown-editor.html">
|
||||
<a href="https://github.com/nhnent/tui.editor" target="_blank">tui.editor</a> ,simply wrapped with Vue.
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://panjiachen.github.io/vue-element-admin-site/feature/component/markdown-editor.html"
|
||||
>
|
||||
Documentation </a>
|
||||
</code>
|
||||
|
||||
<div class="editor-container">
|
||||
<el-tag class="tag-title">Basic:</el-tag>
|
||||
<markdown-editor v-model="content" height="300px" />
|
||||
<el-tag class="tag-title">
|
||||
Basic:
|
||||
</el-tag>
|
||||
<markdown-editor v-model="content1" height="300px" />
|
||||
</div>
|
||||
|
||||
<div class="editor-container">
|
||||
<el-tag class="tag-title">Markdown Mode:</el-tag>
|
||||
<markdown-editor ref="markdownEditor" v-model="content" :options="{hideModeSwitch:true,previewStyle:'tab'}" height="200px" />
|
||||
<el-tag class="tag-title">
|
||||
Markdown Mode:
|
||||
</el-tag>
|
||||
<markdown-editor ref="markdownEditor" v-model="content2" :options="{hideModeSwitch:true,previewStyle:'tab'}" height="200px" />
|
||||
</div>
|
||||
|
||||
<div class="editor-container">
|
||||
<el-tag class="tag-title">Customize Toolbar:</el-tag>
|
||||
<markdown-editor
|
||||
ref="markdownEditor"
|
||||
v-model="content"
|
||||
:options="{ toolbarItems: ['heading','bold','italic']}"
|
||||
<el-tag class="tag-title">
|
||||
Customize Toolbar:
|
||||
</el-tag>
|
||||
<markdown-editor v-model="content3" :options="{ toolbarItems: ['heading','bold','italic']}" />
|
||||
</div>
|
||||
|
||||
<div class="editor-container">
|
||||
<el-tag class="tag-title">
|
||||
I18n:
|
||||
</el-tag>
|
||||
<el-alert
|
||||
:closable="false"
|
||||
title="You can change the language of the admin system to see the effect"
|
||||
type="success"
|
||||
/>
|
||||
<markdown-editor ref="markdownEditor" v-model="content4" :language="language" height="300px" />
|
||||
</div>
|
||||
|
||||
<div class="editor-container">
|
||||
<el-tag class="tag-title">I18n:</el-tag>
|
||||
<el-alert :closable="false" title="You can change the language of the admin system to see the effect" type="success" />
|
||||
<markdown-editor v-model="content" :language="language" height="300px" />
|
||||
</div>
|
||||
|
||||
<el-button style="margin-top:80px;" type="primary" icon="el-icon-document" @click="getHtml">Get HTML</el-button>
|
||||
<!-- eslint-disable-next-line -->
|
||||
<el-button style="margin-top:80px;" type="primary" icon="el-icon-document" @click="getHtml">
|
||||
Get HTML
|
||||
</el-button>
|
||||
<div v-html="html" />
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -55,7 +65,10 @@ export default {
|
||||
components: { MarkdownEditor },
|
||||
data() {
|
||||
return {
|
||||
content: content,
|
||||
content1: content,
|
||||
content2: content,
|
||||
content3: content,
|
||||
content4: content,
|
||||
html: '',
|
||||
languageTypeList: {
|
||||
'en': 'en_US',
|
||||
|
@@ -7,22 +7,34 @@
|
||||
</div>
|
||||
<div style="margin-bottom:50px;">
|
||||
<el-col :span="4" class="text-center">
|
||||
<router-link class="pan-btn blue-btn" to="/documentation/index">Documentation</router-link>
|
||||
<router-link class="pan-btn blue-btn" to="/documentation/index">
|
||||
Documentation
|
||||
</router-link>
|
||||
</el-col>
|
||||
<el-col :span="4" class="text-center">
|
||||
<router-link class="pan-btn light-blue-btn" to="/icon/index">Icons</router-link>
|
||||
<router-link class="pan-btn light-blue-btn" to="/icon/index">
|
||||
Icons
|
||||
</router-link>
|
||||
</el-col>
|
||||
<el-col :span="4" class="text-center">
|
||||
<router-link class="pan-btn pink-btn" to="/excel/export-excel">Excel</router-link>
|
||||
<router-link class="pan-btn pink-btn" to="/excel/export-excel">
|
||||
Excel
|
||||
</router-link>
|
||||
</el-col>
|
||||
<el-col :span="4" class="text-center">
|
||||
<router-link class="pan-btn green-btn" to="/table/complex-table">Table</router-link>
|
||||
<router-link class="pan-btn green-btn" to="/table/complex-table">
|
||||
Table
|
||||
</router-link>
|
||||
</el-col>
|
||||
<el-col :span="4" class="text-center">
|
||||
<router-link class="pan-btn tiffany-btn" to="/example/create">Form</router-link>
|
||||
<router-link class="pan-btn tiffany-btn" to="/example/create">
|
||||
Form
|
||||
</router-link>
|
||||
</el-col>
|
||||
<el-col :span="4" class="text-center">
|
||||
<router-link class="pan-btn yellow-btn" to="/theme/index">Theme</router-link>
|
||||
<router-link class="pan-btn yellow-btn" to="/theme/index">
|
||||
Theme
|
||||
</router-link>
|
||||
</el-col>
|
||||
</div>
|
||||
</el-card>
|
||||
@@ -37,7 +49,9 @@
|
||||
<div style="height:100px;">
|
||||
<el-form :model="demo" :rules="demoRules">
|
||||
<el-form-item prop="title">
|
||||
<md-input v-model="demo.title" icon="search" name="title" placeholder="输入标题">标题</md-input>
|
||||
<md-input v-model="demo.title" icon="search" name="title" placeholder="输入标题">
|
||||
标题
|
||||
</md-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
@@ -63,7 +77,9 @@
|
||||
<span>水波纹 waves v-directive</span>
|
||||
</div>
|
||||
<div class="component-item">
|
||||
<el-button v-waves type="primary">水波纹效果</el-button>
|
||||
<el-button v-waves type="primary">
|
||||
水波纹效果
|
||||
</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<sticky class-name="sub-navbar">
|
||||
<sticky :z-index="10" class-name="sub-navbar">
|
||||
<el-dropdown trigger="click">
|
||||
<el-button plain>
|
||||
Platform<i class="el-icon-caret-bottom el-icon--right" />
|
||||
@@ -20,7 +20,9 @@
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown" class="no-padding no-border" style="width:300px">
|
||||
<el-input v-model="url" placeholder="Please enter the content">
|
||||
<template slot="prepend">Url</template>
|
||||
<template slot="prepend">
|
||||
Url
|
||||
</template>
|
||||
</el-input>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
|
@@ -7,7 +7,6 @@
|
||||
<div>
|
||||
<tinymce v-model="content" :height="300" />
|
||||
</div>
|
||||
<!-- eslint-disable-next-line -->
|
||||
<div class="editor-content" v-html="content" />
|
||||
</div>
|
||||
</template>
|
||||
|
@@ -61,14 +61,14 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" >
|
||||
<style lang="scss" >
|
||||
.box-card-component{
|
||||
.el-card__header {
|
||||
padding: 0px!important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
<style lang="scss" scoped>
|
||||
.box-card-component {
|
||||
.box-card-header {
|
||||
position: relative;
|
||||
|
@@ -6,7 +6,9 @@
|
||||
<svg-icon icon-class="peoples" class-name="card-panel-icon" />
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div class="card-panel-text">New Visits</div>
|
||||
<div class="card-panel-text">
|
||||
New Visits
|
||||
</div>
|
||||
<count-to :start-val="0" :end-val="102400" :duration="2600" class="card-panel-num" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -17,7 +19,9 @@
|
||||
<svg-icon icon-class="message" class-name="card-panel-icon" />
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div class="card-panel-text">Messages</div>
|
||||
<div class="card-panel-text">
|
||||
Messages
|
||||
</div>
|
||||
<count-to :start-val="0" :end-val="81212" :duration="3000" class="card-panel-num" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -28,7 +32,9 @@
|
||||
<svg-icon icon-class="money" class-name="card-panel-icon" />
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div class="card-panel-text">Purchases</div>
|
||||
<div class="card-panel-text">
|
||||
Purchases
|
||||
</div>
|
||||
<count-to :start-val="0" :end-val="9280" :duration="3200" class="card-panel-num" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -39,7 +45,9 @@
|
||||
<svg-icon icon-class="shopping" class-name="card-panel-icon" />
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div class="card-panel-text">Shoppings</div>
|
||||
<div class="card-panel-text">
|
||||
Shoppings
|
||||
</div>
|
||||
<count-to :start-val="0" :end-val="13600" :duration="3600" class="card-panel-num" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -62,7 +70,7 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
<style lang="scss" scoped>
|
||||
.panel-group {
|
||||
margin-top: 18px;
|
||||
.card-panel-col{
|
||||
|
@@ -21,7 +21,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchList } from '@/api/transaction'
|
||||
import { transactionList } from '@/api/remoteSearch'
|
||||
|
||||
export default {
|
||||
filters: {
|
||||
@@ -46,7 +46,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
fetchData() {
|
||||
fetchList().then(response => {
|
||||
transactionList().then(response => {
|
||||
this.list = response.data.items.slice(0, 8)
|
||||
})
|
||||
}
|
||||
|
@@ -1,6 +1,5 @@
|
||||
<template>
|
||||
<div class="dashboard-editor-container">
|
||||
|
||||
<github-corner style="position: absolute; top: 0px; border: 0; right: 0;" />
|
||||
|
||||
<panel-group @handleSetLineChartData="handleSetLineChartData" />
|
||||
@@ -38,7 +37,6 @@
|
||||
<box-card />
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -98,7 +96,7 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
<style lang="scss" scoped>
|
||||
.dashboard-editor-container {
|
||||
padding: 32px;
|
||||
background-color: rgb(240, 242, 245);
|
||||
|
@@ -40,7 +40,7 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
<style lang="scss" scoped>
|
||||
.emptyGif {
|
||||
display: block;
|
||||
width: 45%;
|
||||
|
@@ -29,7 +29,7 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
<style lang="scss" scoped>
|
||||
.documentation-container {
|
||||
margin: 50px;
|
||||
.document-btn {
|
||||
|
@@ -1,18 +1,26 @@
|
||||
<template>
|
||||
<div class="errPage-container">
|
||||
<el-button icon="arrow-left" class="pan-back-btn" @click="back">返回</el-button>
|
||||
<el-button icon="arrow-left" class="pan-back-btn" @click="back">
|
||||
返回
|
||||
</el-button>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<h1 class="text-jumbo text-ginormous">Oops!</h1>
|
||||
<h1 class="text-jumbo text-ginormous">
|
||||
Oops!
|
||||
</h1>
|
||||
gif来源<a href="https://zh.airbnb.com/" target="_blank">airbnb</a> 页面
|
||||
<h2>你没有权限去该页面</h2>
|
||||
<h6>如有不满请联系你领导</h6>
|
||||
<ul class="list-unstyled">
|
||||
<li>或者你可以去:</li>
|
||||
<li class="link-type">
|
||||
<router-link to="/dashboard">回首页</router-link>
|
||||
<router-link to="/dashboard">
|
||||
回首页
|
||||
</router-link>
|
||||
</li>
|
||||
<li class="link-type">
|
||||
<a href="https://www.taobao.com/">随便看看</a>
|
||||
</li>
|
||||
<li class="link-type"><a href="https://www.taobao.com/">随便看看</a></li>
|
||||
<li><a href="#" @click.prevent="dialogVisible=true">点我看图</a></li>
|
||||
</ul>
|
||||
</el-col>
|
||||
@@ -50,7 +58,7 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
<style lang="scss" scoped>
|
||||
.errPage-container {
|
||||
width: 800px;
|
||||
max-width: 100%;
|
||||
|
@@ -8,14 +8,22 @@
|
||||
<img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404">
|
||||
</div>
|
||||
<div class="bullshit">
|
||||
<div class="bullshit__oops">OOPS!</div>
|
||||
<div class="bullshit__oops">
|
||||
OOPS!
|
||||
</div>
|
||||
<div class="bullshit__info">
|
||||
版权所有
|
||||
<a class="link-type" href="https://wallstreetcn.com" target="_blank">华尔街见闻</a>
|
||||
</div>
|
||||
<div class="bullshit__headline">{{ message }}</div>
|
||||
<div class="bullshit__info">请检查您输入的网址是否正确,请点击以下按钮返回主页或者发送错误报告</div>
|
||||
<router-link to="/" class="bullshit__return-home">返回首页</router-link>
|
||||
<div class="bullshit__headline">
|
||||
{{ message }}
|
||||
</div>
|
||||
<div class="bullshit__info">
|
||||
请检查您输入的网址是否正确,请点击以下按钮返回主页或者发送错误报告
|
||||
</div>
|
||||
<router-link to="/" class="bullshit__return-home">
|
||||
返回首页
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -33,7 +41,7 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
<style lang="scss" scoped>
|
||||
.wscn-http404-container{
|
||||
transform: translate(-50%,-50%);
|
||||
position: absolute;
|
||||
|
@@ -1,20 +1,20 @@
|
||||
<template>
|
||||
<div class="createPost-container">
|
||||
<el-form ref="postForm" :model="postForm" :rules="rules" class="form-container">
|
||||
|
||||
<sticky :class-name="'sub-navbar '+postForm.status">
|
||||
<sticky :z-index="10" :class-name="'sub-navbar '+postForm.status">
|
||||
<CommentDropdown v-model="postForm.comment_disabled" />
|
||||
<PlatformDropdown v-model="postForm.platforms" />
|
||||
<SourceUrlDropdown v-model="postForm.source_uri" />
|
||||
<el-button v-loading="loading" style="margin-left: 10px;" type="success" @click="submitForm">
|
||||
发布
|
||||
</el-button>
|
||||
<el-button v-loading="loading" type="warning" @click="draftForm">草稿</el-button>
|
||||
<el-button v-loading="loading" type="warning" @click="draftForm">
|
||||
草稿
|
||||
</el-button>
|
||||
</sticky>
|
||||
|
||||
<div class="createPost-main-container">
|
||||
<el-row>
|
||||
|
||||
<Warning />
|
||||
|
||||
<el-col :span="24">
|
||||
@@ -71,7 +71,6 @@
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -82,7 +81,7 @@ import MDinput from '@/components/MDinput'
|
||||
import Sticky from '@/components/Sticky' // 粘性header组件
|
||||
import { validURL } from '@/utils/validate'
|
||||
import { fetchArticle } from '@/api/article'
|
||||
import { userSearch } from '@/api/remoteSearch'
|
||||
import { searchUser } from '@/api/remoteSearch'
|
||||
import Warning from './Warning'
|
||||
import { CommentDropdown, PlatformDropdown, SourceUrlDropdown } from './Dropdown'
|
||||
|
||||
@@ -187,7 +186,7 @@ export default {
|
||||
setTagsViewTitle() {
|
||||
const title = this.lang === 'zh' ? '编辑文章' : 'Edit Article'
|
||||
const route = Object.assign({}, this.tempRoute, { title: `${title}-${this.postForm.id}` })
|
||||
this.$store.dispatch('updateVisitedView', route)
|
||||
this.$store.dispatch('tagsView/updateVisitedView', route)
|
||||
},
|
||||
submitForm() {
|
||||
this.postForm.display_time = parseInt(this.display_time / 1000)
|
||||
@@ -226,7 +225,7 @@ export default {
|
||||
this.postForm.status = 'draft'
|
||||
},
|
||||
getRemoteUserList(query) {
|
||||
userSearch(query).then(response => {
|
||||
searchUser(query).then(response => {
|
||||
if (!response.data.items) return
|
||||
this.userListOptions = response.data.items.map(v => v.name)
|
||||
})
|
||||
@@ -235,7 +234,7 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
<style lang="scss" scoped>
|
||||
@import "~@/styles/mixin.scss";
|
||||
.createPost-container {
|
||||
position: relative;
|
||||
|
@@ -1,6 +1,5 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
|
||||
<el-table v-loading="listLoading" :data="list" border fit highlight-current-row style="width: 100%">
|
||||
<el-table-column align="center" label="ID" width="80">
|
||||
<template slot-scope="scope">
|
||||
@@ -28,13 +27,14 @@
|
||||
|
||||
<el-table-column class-name="status-col" label="Status" width="110">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="scope.row.status | statusFilter">{{ scope.row.status }}</el-tag>
|
||||
<el-tag :type="scope.row.status | statusFilter">
|
||||
{{ scope.row.status }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column min-width="300px" label="Title">
|
||||
<template slot-scope="scope">
|
||||
|
||||
<router-link :to="'/example/edit/'+scope.row.id" class="link-type">
|
||||
<span>{{ scope.row.title }}</span>
|
||||
</router-link>
|
||||
@@ -44,14 +44,15 @@
|
||||
<el-table-column align="center" label="Actions" width="120">
|
||||
<template slot-scope="scope">
|
||||
<router-link :to="'/example/edit/'+scope.row.id">
|
||||
<el-button type="primary" size="small" icon="el-icon-edit">Edit</el-button>
|
||||
<el-button type="primary" size="small" icon="el-icon-edit">
|
||||
Edit
|
||||
</el-button>
|
||||
</router-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" />
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@@ -2,8 +2,12 @@
|
||||
<div style="display:inline-block;">
|
||||
<label class="radio-label">Cell Auto-Width: </label>
|
||||
<el-radio-group v-model="autoWidth">
|
||||
<el-radio :label="true" border>True</el-radio>
|
||||
<el-radio :label="false" border>False</el-radio>
|
||||
<el-radio :label="true" border>
|
||||
True
|
||||
</el-radio>
|
||||
<el-radio :label="false" border>
|
||||
False
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</template>
|
||||
|
@@ -1,12 +1,13 @@
|
||||
<template>
|
||||
<!-- $t is vue-i18n global function to translate lang -->
|
||||
<div class="app-container">
|
||||
|
||||
<div>
|
||||
<FilenameOption v-model="filename" />
|
||||
<AutoWidthOption v-model="autoWidth" />
|
||||
<BookTypeOption v-model="bookType" />
|
||||
<el-button :loading="downloadLoading" style="margin:0 0 20px 20px;" type="primary" icon="document" @click="handleDownload">{{ $t('excel.export') }} Excel</el-button>
|
||||
<el-button :loading="downloadLoading" style="margin:0 0 20px 20px;" type="primary" icon="document" @click="handleDownload">
|
||||
{{ $t('excel.export') }} Excel
|
||||
</el-button>
|
||||
<a href="https://panjiachen.github.io/vue-element-admin-site/feature/component/excel.html" target="_blank" style="margin-left:15px;">
|
||||
<el-tag type="info">Documentation</el-tag>
|
||||
</a>
|
||||
|
@@ -2,7 +2,9 @@
|
||||
<div class="app-container">
|
||||
<!-- $t is vue-i18n global function to translate lang -->
|
||||
<el-input v-model="filename" :placeholder="$t('excel.placeholder')" style="width:340px;" prefix-icon="el-icon-document" />
|
||||
<el-button :loading="downloadLoading" style="margin-bottom:20px" type="primary" icon="document" @click="handleDownload">{{ $t('excel.selectedExport') }}</el-button>
|
||||
<el-button :loading="downloadLoading" style="margin-bottom:20px" type="primary" icon="document" @click="handleDownload">
|
||||
{{ $t('excel.selectedExport') }}
|
||||
</el-button>
|
||||
<a href="https://panjiachen.github.io/vue-element-admin-site/feature/component/excel.html" target="_blank" style="margin-left:15px;">
|
||||
<el-tag type="info">Documentation</el-tag>
|
||||
</a>
|
||||
|
@@ -5,7 +5,9 @@
|
||||
<a href="https://github.com/kamranahmedse/driver.js" target="_blank">driver.js.
|
||||
</a>
|
||||
</p>
|
||||
<el-button icon="el-icon-question" type="primary" @click.prevent.stop="guide">{{ $t('guide.button') }}</el-button>
|
||||
<el-button icon="el-icon-question" type="primary" @click.prevent.stop="guide">
|
||||
{{ $t('guide.button') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@@ -7,11 +7,19 @@
|
||||
</div>
|
||||
<div>
|
||||
<el-radio-group v-model="lang" size="small">
|
||||
<el-radio label="zh" border>简体中文</el-radio>
|
||||
<el-radio label="en" border>English</el-radio>
|
||||
<el-radio label="es" border>Español</el-radio>
|
||||
<el-radio label="zh" border>
|
||||
简体中文
|
||||
</el-radio>
|
||||
<el-radio label="en" border>
|
||||
English
|
||||
</el-radio>
|
||||
<el-radio label="es" border>
|
||||
Español
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
<el-tag style="margin-top:15px;display:block;" type="info">{{ $t('i18nView.note') }}</el-tag>
|
||||
<el-tag style="margin-top:15px;display:block;" type="info">
|
||||
{{ $t('i18nView.note') }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
@@ -31,12 +39,24 @@
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="block">
|
||||
<el-button class="item-btn" size="small">{{ $t('i18nView.default') }}</el-button>
|
||||
<el-button class="item-btn" size="small" type="primary">{{ $t('i18nView.primary') }}</el-button>
|
||||
<el-button class="item-btn" size="small" type="success">{{ $t('i18nView.success') }}</el-button>
|
||||
<el-button class="item-btn" size="small" type="info">{{ $t('i18nView.info') }}</el-button>
|
||||
<el-button class="item-btn" size="small" type="warning">{{ $t('i18nView.warning') }}</el-button>
|
||||
<el-button class="item-btn" size="small" type="danger">{{ $t('i18nView.danger') }}</el-button>
|
||||
<el-button class="item-btn" size="small">
|
||||
{{ $t('i18nView.default') }}
|
||||
</el-button>
|
||||
<el-button class="item-btn" size="small" type="primary">
|
||||
{{ $t('i18nView.primary') }}
|
||||
</el-button>
|
||||
<el-button class="item-btn" size="small" type="success">
|
||||
{{ $t('i18nView.success') }}
|
||||
</el-button>
|
||||
<el-button class="item-btn" size="small" type="info">
|
||||
{{ $t('i18nView.info') }}
|
||||
</el-button>
|
||||
<el-button class="item-btn" size="small" type="warning">
|
||||
{{ $t('i18nView.warning') }}
|
||||
</el-button>
|
||||
<el-button class="item-btn" size="small" type="danger">
|
||||
{{ $t('i18nView.danger') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12" :xs="24">
|
||||
@@ -90,7 +110,7 @@ export default {
|
||||
},
|
||||
set(lang) {
|
||||
this.$i18n.locale = lang
|
||||
this.$store.dispatch('setLanguage', lang)
|
||||
this.$store.dispatch('app/setLanguage', lang)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@@ -1,71 +0,0 @@
|
||||
<template>
|
||||
<div :class="classObj" class="app-wrapper">
|
||||
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
|
||||
<sidebar class="sidebar-container" />
|
||||
<div class="main-container">
|
||||
<navbar />
|
||||
<tags-view />
|
||||
<app-main />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Navbar, Sidebar, AppMain, TagsView } from './components'
|
||||
import ResizeMixin from './mixin/ResizeHandler'
|
||||
|
||||
export default {
|
||||
name: 'Layout',
|
||||
components: {
|
||||
Navbar,
|
||||
Sidebar,
|
||||
AppMain,
|
||||
TagsView
|
||||
},
|
||||
mixins: [ResizeMixin],
|
||||
computed: {
|
||||
sidebar() {
|
||||
return this.$store.state.app.sidebar
|
||||
},
|
||||
device() {
|
||||
return this.$store.state.app.device
|
||||
},
|
||||
classObj() {
|
||||
return {
|
||||
hideSidebar: !this.sidebar.opened,
|
||||
openSidebar: this.sidebar.opened,
|
||||
withoutAnimation: this.sidebar.withoutAnimation,
|
||||
mobile: this.device === 'mobile'
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleClickOutside() {
|
||||
this.$store.dispatch('closeSideBar', { withoutAnimation: false })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
@import "~@/styles/mixin.scss";
|
||||
.app-wrapper {
|
||||
@include clearfix;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
&.mobile.openSidebar{
|
||||
position: fixed;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
.drawer-bg {
|
||||
background: #000;
|
||||
opacity: 0.3;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
z-index: 999;
|
||||
}
|
||||
</style>
|
@@ -1,34 +0,0 @@
|
||||
<template>
|
||||
<section class="app-main">
|
||||
<transition name="fade-transform" mode="out-in">
|
||||
<keep-alive :include="cachedViews">
|
||||
<router-view :key="key" />
|
||||
</keep-alive>
|
||||
</transition>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AppMain',
|
||||
computed: {
|
||||
cachedViews() {
|
||||
return this.$store.state.tagsView.cachedViews
|
||||
},
|
||||
key() {
|
||||
return this.$route.fullPath
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.app-main {
|
||||
/*84 = navbar + tags-view = 50 +34 */
|
||||
min-height: calc(100vh - 84px);
|
||||
width: 100%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
|
@@ -1,172 +0,0 @@
|
||||
<template>
|
||||
<div class="navbar">
|
||||
<hamburger :toggle-click="toggleSideBar" :is-active="sidebar.opened" class="hamburger-container" />
|
||||
|
||||
<breadcrumb class="breadcrumb-container" />
|
||||
|
||||
<div class="right-menu">
|
||||
<template v-if="device!=='mobile'">
|
||||
<search class="right-menu-item" />
|
||||
|
||||
<error-log class="errLog-container right-menu-item hover-effect" />
|
||||
|
||||
<screenfull class="right-menu-item hover-effect" />
|
||||
|
||||
<el-tooltip :content="$t('navbar.size')" effect="dark" placement="bottom">
|
||||
<size-select class="right-menu-item hover-effect" />
|
||||
</el-tooltip>
|
||||
|
||||
<lang-select class="right-menu-item hover-effect" />
|
||||
|
||||
<el-tooltip :content="$t('navbar.theme')" effect="dark" placement="bottom">
|
||||
<theme-picker class="right-menu-item hover-effect" />
|
||||
</el-tooltip>
|
||||
</template>
|
||||
|
||||
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
|
||||
<div class="avatar-wrapper">
|
||||
<img :src="avatar+'?imageView2/1/w/80/h/80'" class="user-avatar">
|
||||
<i class="el-icon-caret-bottom" />
|
||||
</div>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<router-link to="/">
|
||||
<el-dropdown-item>
|
||||
{{ $t('navbar.dashboard') }}
|
||||
</el-dropdown-item>
|
||||
</router-link>
|
||||
<a target="_blank" href="https://github.com/PanJiaChen/vue-element-admin/">
|
||||
<el-dropdown-item>
|
||||
{{ $t('navbar.github') }}
|
||||
</el-dropdown-item>
|
||||
</a>
|
||||
<el-dropdown-item divided>
|
||||
<span style="display:block;" @click="logout">{{ $t('navbar.logOut') }}</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import Breadcrumb from '@/components/Breadcrumb'
|
||||
import Hamburger from '@/components/Hamburger'
|
||||
import ErrorLog from '@/components/ErrorLog'
|
||||
import Screenfull from '@/components/Screenfull'
|
||||
import SizeSelect from '@/components/SizeSelect'
|
||||
import LangSelect from '@/components/LangSelect'
|
||||
import ThemePicker from '@/components/ThemePicker'
|
||||
import Search from '@/components/HeaderSearch'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Breadcrumb,
|
||||
Hamburger,
|
||||
ErrorLog,
|
||||
Screenfull,
|
||||
SizeSelect,
|
||||
LangSelect,
|
||||
ThemePicker,
|
||||
Search
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'sidebar',
|
||||
'name',
|
||||
'avatar',
|
||||
'device'
|
||||
])
|
||||
},
|
||||
methods: {
|
||||
toggleSideBar() {
|
||||
this.$store.dispatch('toggleSideBar')
|
||||
},
|
||||
logout() {
|
||||
this.$store.dispatch('LogOut').then(() => {
|
||||
location.reload()// In order to re-instantiate the vue-router object to avoid bugs
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.navbar {
|
||||
height: 50px;
|
||||
overflow: hidden;
|
||||
|
||||
.hamburger-container {
|
||||
line-height: 46px;
|
||||
height: 100%;
|
||||
float: left;
|
||||
cursor: pointer;
|
||||
transition: background .3s;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, .025)
|
||||
}
|
||||
}
|
||||
|
||||
.breadcrumb-container {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.errLog-container {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.right-menu {
|
||||
float: right;
|
||||
height: 100%;
|
||||
line-height: 50px;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.right-menu-item {
|
||||
display: inline-block;
|
||||
padding: 0 8px;
|
||||
height: 100%;
|
||||
font-size: 18px;
|
||||
color: #5a5e66;
|
||||
vertical-align: text-bottom;
|
||||
|
||||
&.hover-effect {
|
||||
cursor: pointer;
|
||||
transition: background .3s;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, .025)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.avatar-container {
|
||||
margin-right: 30px;
|
||||
|
||||
.avatar-wrapper {
|
||||
margin-top: 5px;
|
||||
position: relative;
|
||||
|
||||
.user-avatar {
|
||||
cursor: pointer;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.el-icon-caret-bottom {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
right: -20px;
|
||||
top: 25px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,26 +0,0 @@
|
||||
export default {
|
||||
computed: {
|
||||
device() {
|
||||
return this.$store.state.app.device
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// In order to fix the click on menu on the ios device will trigger the mouseleave bug
|
||||
// https://github.com/PanJiaChen/vue-element-admin/issues/1135
|
||||
this.fixBugIniOS()
|
||||
},
|
||||
methods: {
|
||||
fixBugIniOS() {
|
||||
const $subMenu = this.$refs.subMenu
|
||||
if ($subMenu) {
|
||||
const handleMouseleave = $subMenu.handleMouseleave
|
||||
$subMenu.handleMouseleave = (e) => {
|
||||
if (this.device === 'mobile') {
|
||||
return
|
||||
}
|
||||
handleMouseleave(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
<script>
|
||||
export default {
|
||||
name: 'MenuItem',
|
||||
functional: true,
|
||||
props: {
|
||||
icon: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
render(h, context) {
|
||||
const { icon, title } = context.props
|
||||
const vnodes = []
|
||||
|
||||
if (icon) {
|
||||
vnodes.push(<svg-icon icon-class={icon}/>)
|
||||
}
|
||||
|
||||
if (title) {
|
||||
vnodes.push(<span slot='title'>{(title)}</span>)
|
||||
}
|
||||
return vnodes
|
||||
}
|
||||
}
|
||||
</script>
|
@@ -1,36 +0,0 @@
|
||||
|
||||
<template>
|
||||
<!-- eslint-disable vue/require-component-is -->
|
||||
<component v-bind="linkProps(to)">
|
||||
<slot />
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { isExternal } from '@/utils/validate'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
to: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
linkProps(url) {
|
||||
if (isExternal(url)) {
|
||||
return {
|
||||
is: 'a',
|
||||
href: url,
|
||||
target: '_blank',
|
||||
rel: 'noopener'
|
||||
}
|
||||
}
|
||||
return {
|
||||
is: 'router-link',
|
||||
to: url
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@@ -1,97 +0,0 @@
|
||||
<template>
|
||||
<div v-if="!item.hidden" class="menu-wrapper">
|
||||
|
||||
<template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
|
||||
<app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
|
||||
<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">
|
||||
<item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="generateTitle(onlyOneChild.meta.title)" />
|
||||
</el-menu-item>
|
||||
</app-link>
|
||||
</template>
|
||||
|
||||
<el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>
|
||||
<template slot="title">
|
||||
<item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="generateTitle(item.meta.title)" />
|
||||
</template>
|
||||
<sidebar-item
|
||||
v-for="child in item.children"
|
||||
:key="child.path"
|
||||
:is-nest="true"
|
||||
:item="child"
|
||||
:base-path="resolvePath(child.path)"
|
||||
class="nest-menu"
|
||||
/>
|
||||
</el-submenu>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import path from 'path'
|
||||
import { generateTitle } from '@/utils/i18n'
|
||||
import { isExternal } from '@/utils/validate'
|
||||
import Item from './Item'
|
||||
import AppLink from './Link'
|
||||
import FixiOSBug from './FixiOSBug'
|
||||
|
||||
export default {
|
||||
name: 'SidebarItem',
|
||||
components: { Item, AppLink },
|
||||
mixins: [FixiOSBug],
|
||||
props: {
|
||||
// route object
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
isNest: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
basePath: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
// To fix https://github.com/PanJiaChen/vue-admin-template/issues/237
|
||||
// TODO: refactor with render function
|
||||
this.onlyOneChild = null
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
hasOneShowingChild(children = [], parent) {
|
||||
const showingChildren = children.filter(item => {
|
||||
if (item.hidden) {
|
||||
return false
|
||||
} else {
|
||||
// Temp set(will be used if only has one showing child)
|
||||
this.onlyOneChild = item
|
||||
return true
|
||||
}
|
||||
})
|
||||
|
||||
// When there is only one child router, the child router is displayed by default
|
||||
if (showingChildren.length === 1) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Show parent if there are no child router to display
|
||||
if (showingChildren.length === 0) {
|
||||
this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
},
|
||||
resolvePath(routePath) {
|
||||
if (isExternal(routePath)) {
|
||||
return routePath
|
||||
}
|
||||
return path.resolve(this.basePath, routePath)
|
||||
},
|
||||
|
||||
generateTitle
|
||||
}
|
||||
}
|
||||
</script>
|
@@ -1,37 +0,0 @@
|
||||
<template>
|
||||
<el-scrollbar wrap-class="scrollbar-wrapper">
|
||||
<el-menu
|
||||
:default-active="$route.path"
|
||||
:collapse="isCollapse"
|
||||
:background-color="variables.menuBg"
|
||||
:text-color="variables.menuText"
|
||||
:active-text-color="variables.menuActiveText"
|
||||
:collapse-transition="false"
|
||||
mode="vertical"
|
||||
>
|
||||
<sidebar-item v-for="route in permission_routes" :key="route.path" :item="route" :base-path="route.path" />
|
||||
</el-menu>
|
||||
</el-scrollbar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import SidebarItem from './SidebarItem'
|
||||
import variables from '@/styles/variables.scss'
|
||||
|
||||
export default {
|
||||
components: { SidebarItem },
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'permission_routes',
|
||||
'sidebar'
|
||||
]),
|
||||
variables() {
|
||||
return variables
|
||||
},
|
||||
isCollapse() {
|
||||
return !this.sidebar.opened
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@@ -1,85 +0,0 @@
|
||||
<template>
|
||||
<el-scrollbar ref="scrollContainer" :vertical="false" class="scroll-container" @wheel.native.prevent="handleScroll">
|
||||
<slot />
|
||||
</el-scrollbar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const tagAndTagSpacing = 4 // tagAndTagSpacing
|
||||
|
||||
export default {
|
||||
name: 'ScrollPane',
|
||||
data() {
|
||||
return {
|
||||
left: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
scrollWrapper() {
|
||||
return this.$refs.scrollContainer.$refs.wrap
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleScroll(e) {
|
||||
const eventDelta = e.wheelDelta || -e.deltaY * 40
|
||||
const $scrollWrapper = this.scrollWrapper
|
||||
$scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4
|
||||
},
|
||||
moveToTarget(currentTag) {
|
||||
const $container = this.$refs.scrollContainer.$el
|
||||
const $containerWidth = $container.offsetWidth
|
||||
const $scrollWrapper = this.scrollWrapper
|
||||
const tagList = this.$parent.$refs.tag
|
||||
|
||||
let firstTag = null
|
||||
let lastTag = null
|
||||
|
||||
// find first tag and last tag
|
||||
if (tagList.length > 0) {
|
||||
firstTag = tagList[0]
|
||||
lastTag = tagList[tagList.length - 1]
|
||||
}
|
||||
|
||||
if (firstTag === currentTag) {
|
||||
$scrollWrapper.scrollLeft = 0
|
||||
} else if (lastTag === currentTag) {
|
||||
$scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth
|
||||
} else {
|
||||
// find preTag and nextTag
|
||||
const currentIndex = tagList.findIndex(item => item === currentTag)
|
||||
const prevTag = tagList[currentIndex - 1]
|
||||
const nextTag = tagList[currentIndex + 1]
|
||||
|
||||
// the tag's offsetLeft after of nextTag
|
||||
const afterNextTagOffsetLeft = nextTag.$el.offsetLeft + nextTag.$el.offsetWidth + tagAndTagSpacing
|
||||
|
||||
// the tag's offsetLeft before of prevTag
|
||||
const beforePrevTagOffsetLeft = prevTag.$el.offsetLeft - tagAndTagSpacing
|
||||
|
||||
if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) {
|
||||
$scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth
|
||||
} else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) {
|
||||
$scrollWrapper.scrollLeft = beforePrevTagOffsetLeft
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.scroll-container {
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
/deep/ {
|
||||
.el-scrollbar__bar {
|
||||
bottom: 0px;
|
||||
}
|
||||
.el-scrollbar__wrap {
|
||||
height: 49px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,284 +0,0 @@
|
||||
<template>
|
||||
<div class="tags-view-container">
|
||||
<scroll-pane ref="scrollPane" class="tags-view-wrapper">
|
||||
<router-link
|
||||
v-for="tag in visitedViews"
|
||||
ref="tag"
|
||||
:key="tag.path"
|
||||
:class="isActive(tag)?'active':''"
|
||||
:to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
|
||||
tag="span"
|
||||
class="tags-view-item"
|
||||
@click.middle.native="closeSelectedTag(tag)"
|
||||
@contextmenu.prevent.native="openMenu(tag,$event)"
|
||||
>
|
||||
{{ generateTitle(tag.title) }}
|
||||
<span v-if="!tag.meta.affix" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" />
|
||||
</router-link>
|
||||
</scroll-pane>
|
||||
<ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
|
||||
<li @click="refreshSelectedTag(selectedTag)">{{ $t('tagsView.refresh') }}</li>
|
||||
<li v-if="!(selectedTag.meta&&selectedTag.meta.affix)" @click="closeSelectedTag(selectedTag)">
|
||||
{{ $t('tagsView.close') }}
|
||||
</li>
|
||||
<li @click="closeOthersTags">{{ $t('tagsView.closeOthers') }}</li>
|
||||
<li @click="closeAllTags(selectedTag)">{{ $t('tagsView.closeAll') }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ScrollPane from './ScrollPane'
|
||||
import { generateTitle } from '@/utils/i18n'
|
||||
import path from 'path'
|
||||
|
||||
export default {
|
||||
components: { ScrollPane },
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
top: 0,
|
||||
left: 0,
|
||||
selectedTag: {},
|
||||
affixTags: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
visitedViews() {
|
||||
return this.$store.state.tagsView.visitedViews
|
||||
},
|
||||
routes() {
|
||||
return this.$store.state.permission.routes
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.addTags()
|
||||
this.moveToCurrentTag()
|
||||
},
|
||||
visible(value) {
|
||||
if (value) {
|
||||
document.body.addEventListener('click', this.closeMenu)
|
||||
} else {
|
||||
document.body.removeEventListener('click', this.closeMenu)
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initTags()
|
||||
this.addTags()
|
||||
},
|
||||
methods: {
|
||||
generateTitle, // generateTitle by vue-i18n
|
||||
isActive(route) {
|
||||
return route.path === this.$route.path
|
||||
},
|
||||
filterAffixTags(routes, basePath = '/') {
|
||||
let tags = []
|
||||
routes.forEach(route => {
|
||||
if (route.meta && route.meta.affix) {
|
||||
const tagPath = path.resolve(basePath, route.path)
|
||||
tags.push({
|
||||
fullPath: tagPath,
|
||||
path: tagPath,
|
||||
name: route.name,
|
||||
meta: { ...route.meta }
|
||||
})
|
||||
}
|
||||
if (route.children) {
|
||||
const tempTags = this.filterAffixTags(route.children, route.path)
|
||||
if (tempTags.length >= 1) {
|
||||
tags = [...tags, ...tempTags]
|
||||
}
|
||||
}
|
||||
})
|
||||
return tags
|
||||
},
|
||||
initTags() {
|
||||
const affixTags = this.affixTags = this.filterAffixTags(this.routes)
|
||||
for (const tag of affixTags) {
|
||||
// Must have tag name
|
||||
if (tag.name) {
|
||||
this.$store.dispatch('addVisitedView', tag)
|
||||
}
|
||||
}
|
||||
},
|
||||
addTags() {
|
||||
const { name } = this.$route
|
||||
if (name) {
|
||||
this.$store.dispatch('addView', this.$route)
|
||||
}
|
||||
return false
|
||||
},
|
||||
moveToCurrentTag() {
|
||||
const tags = this.$refs.tag
|
||||
this.$nextTick(() => {
|
||||
for (const tag of tags) {
|
||||
if (tag.to.path === this.$route.path) {
|
||||
this.$refs.scrollPane.moveToTarget(tag)
|
||||
// when query is different then update
|
||||
if (tag.to.fullPath !== this.$route.fullPath) {
|
||||
this.$store.dispatch('updateVisitedView', this.$route)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
refreshSelectedTag(view) {
|
||||
this.$store.dispatch('delCachedView', view).then(() => {
|
||||
const { fullPath } = view
|
||||
this.$nextTick(() => {
|
||||
this.$router.replace({
|
||||
path: '/redirect' + fullPath
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
closeSelectedTag(view) {
|
||||
this.$store.dispatch('delView', view).then(({ visitedViews }) => {
|
||||
if (this.isActive(view)) {
|
||||
this.toLastView(visitedViews)
|
||||
}
|
||||
})
|
||||
},
|
||||
closeOthersTags() {
|
||||
this.$router.push(this.selectedTag)
|
||||
this.$store.dispatch('delOthersViews', this.selectedTag).then(() => {
|
||||
this.moveToCurrentTag()
|
||||
})
|
||||
},
|
||||
closeAllTags(view) {
|
||||
this.$store.dispatch('delAllViews').then(({ visitedViews }) => {
|
||||
if (this.affixTags.some(tag => tag.path === view.path)) {
|
||||
return
|
||||
}
|
||||
this.toLastView(visitedViews)
|
||||
})
|
||||
},
|
||||
toLastView(visitedViews) {
|
||||
const latestView = visitedViews.slice(-1)[0]
|
||||
if (latestView) {
|
||||
this.$router.push(latestView)
|
||||
} else {
|
||||
// You can set another route
|
||||
this.$router.push('/')
|
||||
}
|
||||
},
|
||||
openMenu(tag, e) {
|
||||
const menuMinWidth = 105
|
||||
const offsetLeft = this.$el.getBoundingClientRect().left // container margin left
|
||||
const offsetWidth = this.$el.offsetWidth // container width
|
||||
const maxLeft = offsetWidth - menuMinWidth // left boundary
|
||||
const left = e.clientX - offsetLeft + 15 // 15: margin right
|
||||
|
||||
if (left > maxLeft) {
|
||||
this.left = maxLeft
|
||||
} else {
|
||||
this.left = left
|
||||
}
|
||||
|
||||
this.top = e.clientY
|
||||
this.visible = true
|
||||
this.selectedTag = tag
|
||||
},
|
||||
closeMenu() {
|
||||
this.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.tags-view-container {
|
||||
height: 34px;
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #d8dce5;
|
||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 0 3px 0 rgba(0, 0, 0, .04);
|
||||
.tags-view-wrapper {
|
||||
.tags-view-item {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
border: 1px solid #d8dce5;
|
||||
color: #495060;
|
||||
background: #fff;
|
||||
padding: 0 8px;
|
||||
font-size: 12px;
|
||||
margin-left: 5px;
|
||||
margin-top: 4px;
|
||||
&:first-of-type {
|
||||
margin-left: 15px;
|
||||
}
|
||||
&:last-of-type {
|
||||
margin-right: 15px;
|
||||
}
|
||||
&.active {
|
||||
background-color: #42b983;
|
||||
color: #fff;
|
||||
border-color: #42b983;
|
||||
&::before {
|
||||
content: '';
|
||||
background: #fff;
|
||||
display: inline-block;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.contextmenu {
|
||||
margin: 0;
|
||||
background: #fff;
|
||||
z-index: 100;
|
||||
position: absolute;
|
||||
list-style-type: none;
|
||||
padding: 5px 0;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #333;
|
||||
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);
|
||||
li {
|
||||
margin: 0;
|
||||
padding: 7px 16px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: #eee;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss">
|
||||
//reset element css of el-icon-close
|
||||
.tags-view-wrapper {
|
||||
.tags-view-item {
|
||||
.el-icon-close {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
vertical-align: 2px;
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
transition: all .3s cubic-bezier(.645, .045, .355, 1);
|
||||
transform-origin: 100% 50%;
|
||||
&:before {
|
||||
transform: scale(.6);
|
||||
display: inline-block;
|
||||
vertical-align: -3px;
|
||||
}
|
||||
&:hover {
|
||||
background-color: #b4bccc;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,4 +0,0 @@
|
||||
export { default as Navbar } from './Navbar'
|
||||
export { default as Sidebar } from './Sidebar/index.vue'
|
||||
export { default as TagsView } from './TagsView/index.vue'
|
||||
export { default as AppMain } from './AppMain'
|
@@ -1,40 +0,0 @@
|
||||
import store from '@/store'
|
||||
|
||||
const { body } = document
|
||||
const WIDTH = 992 // refer to Bootstrap's responsive design
|
||||
|
||||
export default {
|
||||
watch: {
|
||||
$route(route) {
|
||||
if (this.device === 'mobile' && this.sidebar.opened) {
|
||||
store.dispatch('closeSideBar', { withoutAnimation: false })
|
||||
}
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
window.addEventListener('resize', this.resizeHandler)
|
||||
},
|
||||
mounted() {
|
||||
const isMobile = this.isMobile()
|
||||
if (isMobile) {
|
||||
store.dispatch('toggleDevice', 'mobile')
|
||||
store.dispatch('closeSideBar', { withoutAnimation: true })
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isMobile() {
|
||||
const rect = body.getBoundingClientRect()
|
||||
return rect.width - 1 < WIDTH
|
||||
},
|
||||
resizeHandler() {
|
||||
if (!document.hidden) {
|
||||
const isMobile = this.isMobile()
|
||||
store.dispatch('toggleDevice', isMobile ? 'mobile' : 'desktop')
|
||||
|
||||
if (isMobile) {
|
||||
store.dispatch('closeSideBar', { withoutAnimation: true })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,10 +1,15 @@
|
||||
<script>
|
||||
export default {
|
||||
name: 'AuthRedirect',
|
||||
name: 'Authredirect',
|
||||
created() {
|
||||
const hash = window.location.search.slice(1)
|
||||
window.opener.location.href = window.location.origin + '/login#' + hash
|
||||
window.close()
|
||||
if (window.localStorage) {
|
||||
window.localStorage.setItem('x-admin-oauth-code', hash)
|
||||
window.close()
|
||||
}
|
||||
},
|
||||
render: function(h) {
|
||||
return h() // avoid warning message
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div class="login-container">
|
||||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on" label-position="left">
|
||||
|
||||
<div class="title-container">
|
||||
<h3 class="title">
|
||||
{{ $t('login.title') }}
|
||||
@@ -27,6 +28,7 @@
|
||||
<svg-icon icon-class="password" />
|
||||
</span>
|
||||
<el-input
|
||||
:key="passwordType"
|
||||
ref="password"
|
||||
v-model="loginForm.password"
|
||||
:type="passwordType"
|
||||
@@ -119,7 +121,7 @@ export default {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// window.addEventListener('hashchange', this.afterQRScan)
|
||||
// window.addEventListener('storage', this.afterQRScan)
|
||||
},
|
||||
mounted() {
|
||||
if (this.loginForm.username === '') {
|
||||
@@ -129,7 +131,7 @@ export default {
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
// window.removeEventListener('hashchange', this.afterQRScan)
|
||||
// window.removeEventListener('storage', this.afterQRScan)
|
||||
},
|
||||
methods: {
|
||||
showPwd() {
|
||||
@@ -146,88 +148,90 @@ export default {
|
||||
this.$refs.loginForm.validate(valid => {
|
||||
if (valid) {
|
||||
this.loading = true
|
||||
this.$store.dispatch('LoginByUsername', this.loginForm).then(() => {
|
||||
this.loading = false
|
||||
this.$router.push({ path: this.redirect || '/' })
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
this.$store.dispatch('user/login', this.loginForm)
|
||||
.then(() => {
|
||||
this.$router.push({ path: this.redirect || '/' })
|
||||
this.loading = false
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
} else {
|
||||
console.log('error submit!!')
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
afterQRScan() {
|
||||
// const hash = window.location.hash.slice(1)
|
||||
// const hashObj = getQueryObject(hash)
|
||||
// const originUrl = window.location.origin
|
||||
// history.replaceState({}, '', originUrl)
|
||||
// const codeMap = {
|
||||
// wechat: 'code',
|
||||
// tencent: 'code'
|
||||
// }
|
||||
// const codeName = hashObj[codeMap[this.auth_type]]
|
||||
// if (!codeName) {
|
||||
// alert('第三方登录失败')
|
||||
// } else {
|
||||
// this.$store.dispatch('LoginByThirdparty', codeName).then(() => {
|
||||
// this.$router.push({ path: '/' })
|
||||
// })
|
||||
// }
|
||||
}
|
||||
// afterQRScan() {
|
||||
// if (e.key === 'x-admin-oauth-code') {
|
||||
// const code = getQueryObject(e.newValue)
|
||||
// const codeMap = {
|
||||
// wechat: 'code',
|
||||
// tencent: 'code'
|
||||
// }
|
||||
// const type = codeMap[this.auth_type]
|
||||
// const codeName = code[type]
|
||||
// if (codeName) {
|
||||
// this.$store.dispatch('LoginByThirdparty', codeName).then(() => {
|
||||
// this.$router.push({ path: this.redirect || '/' })
|
||||
// })
|
||||
// } else {
|
||||
// alert('第三方登录失败')
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss">
|
||||
/* 修复input 背景不协调 和光标变色 */
|
||||
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
|
||||
<style lang="scss">
|
||||
/* 修复input 背景不协调 和光标变色 */
|
||||
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
|
||||
|
||||
$bg:#283443;
|
||||
$light_gray:#eee;
|
||||
$cursor: #fff;
|
||||
$bg:#283443;
|
||||
$light_gray:#fff;
|
||||
$cursor: #fff;
|
||||
|
||||
@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
|
||||
.login-container .el-input input{
|
||||
color: $cursor;
|
||||
&::first-line {
|
||||
color: $light_gray;
|
||||
}
|
||||
}
|
||||
@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
|
||||
.login-container .el-input input {
|
||||
color: $cursor;
|
||||
}
|
||||
}
|
||||
|
||||
/* reset element-ui css */
|
||||
.login-container {
|
||||
.el-input {
|
||||
display: inline-block;
|
||||
/* reset element-ui css */
|
||||
.login-container {
|
||||
.el-input {
|
||||
display: inline-block;
|
||||
height: 47px;
|
||||
width: 85%;
|
||||
|
||||
input {
|
||||
background: transparent;
|
||||
border: 0px;
|
||||
-webkit-appearance: none;
|
||||
border-radius: 0px;
|
||||
padding: 12px 5px 12px 15px;
|
||||
color: $light_gray;
|
||||
height: 47px;
|
||||
width: 85%;
|
||||
input {
|
||||
background: transparent;
|
||||
border: 0px;
|
||||
-webkit-appearance: none;
|
||||
border-radius: 0px;
|
||||
padding: 12px 5px 12px 15px;
|
||||
color: $light_gray;
|
||||
height: 47px;
|
||||
caret-color: $cursor;
|
||||
&:-webkit-autofill {
|
||||
box-shadow: 0 0 0px 1000px $bg inset !important;
|
||||
-webkit-text-fill-color: $cursor !important;
|
||||
}
|
||||
caret-color: $cursor;
|
||||
|
||||
&:-webkit-autofill {
|
||||
box-shadow: 0 0 0px 1000px $bg inset !important;
|
||||
-webkit-text-fill-color: $cursor !important;
|
||||
}
|
||||
}
|
||||
.el-form-item {
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
border-radius: 5px;
|
||||
color: #454545;
|
||||
}
|
||||
}
|
||||
|
||||
.el-form-item {
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
border-radius: 5px;
|
||||
color: #454545;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
<style lang="scss" scoped>
|
||||
$bg:#2d3a4b;
|
||||
$dark_gray:#889aa4;
|
||||
$light_gray:#eee;
|
||||
@@ -237,6 +241,7 @@ $light_gray:#eee;
|
||||
width: 100%;
|
||||
background-color: $bg;
|
||||
overflow: hidden;
|
||||
|
||||
.login-form {
|
||||
position: relative;
|
||||
width: 520px;
|
||||
@@ -245,16 +250,19 @@ $light_gray:#eee;
|
||||
margin: 0 auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tips {
|
||||
font-size: 14px;
|
||||
color: #fff;
|
||||
margin-bottom: 10px;
|
||||
|
||||
span {
|
||||
&:first-of-type {
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.svg-container {
|
||||
padding: 6px 5px 6px 15px;
|
||||
color: $dark_gray;
|
||||
@@ -262,8 +270,10 @@ $light_gray:#eee;
|
||||
width: 30px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.title-container {
|
||||
position: relative;
|
||||
|
||||
.title {
|
||||
font-size: 26px;
|
||||
color: $light_gray;
|
||||
@@ -271,15 +281,17 @@ $light_gray:#eee;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.set-language {
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
font-size:18px;
|
||||
font-size: 18px;
|
||||
right: 0px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.show-pwd {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
@@ -289,10 +301,17 @@ $light_gray:#eee;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.thirdparty-button {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 6px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 470px) {
|
||||
.thirdparty-button {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -35,7 +35,7 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
<style lang="scss" scoped>
|
||||
.social-signup-container {
|
||||
margin: 20px 0;
|
||||
.sign-btn {
|
||||
|
@@ -1,12 +1,13 @@
|
||||
<template>
|
||||
<div v-loading.fullscreen.lock="fullscreenLoading" class="main-article" element-loading-text="Efforts to generate PDF">
|
||||
<div class="article__heading">
|
||||
<div class="article__heading__title"> {{ article.title }}</div>
|
||||
<div class="article__heading__title">
|
||||
{{ article.title }}
|
||||
</div>
|
||||
</div>
|
||||
<div style="color: #ccc;">
|
||||
This article is from Evan You on <a target="_blank" href="https://medium.com/the-vue-point/plans-for-the-next-iteration-of-vue-js-777ffea6fabf">medium</a>
|
||||
</div>
|
||||
<!-- eslint-disable-next-line -->
|
||||
<div ref="content" class="node-article-content" v-html="article.content" />
|
||||
</div>
|
||||
</template>
|
||||
@@ -41,7 +42,7 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss">
|
||||
<style lang="scss">
|
||||
@mixin clearfix {
|
||||
&:before {
|
||||
display: table;
|
||||
|
@@ -2,7 +2,9 @@
|
||||
<div class="app-container">
|
||||
<code style="margin-top:15px;">{{ $t('pdf.tips') }}</code>
|
||||
<router-link target="_blank" to="/pdf/download">
|
||||
<el-button type="primary">Click to download PDF</el-button>
|
||||
<el-button type="primary">
|
||||
Click to download PDF
|
||||
</el-button>
|
||||
</router-link>
|
||||
</div>
|
||||
</template>
|
||||
|
@@ -1,6 +1,8 @@
|
||||
<template>
|
||||
<div>
|
||||
<div style="margin-bottom:15px;">{{ $t('permission.roles') }}: {{ roles }}</div>
|
||||
<div style="margin-bottom:15px;">
|
||||
{{ $t('permission.roles') }}: {{ roles }}
|
||||
</div>
|
||||
{{ $t('permission.switchRoles') }}:
|
||||
<el-radio-group v-model="switchRoles">
|
||||
<el-radio-button label="editor" />
|
||||
@@ -20,7 +22,7 @@ export default {
|
||||
return this.roles[0]
|
||||
},
|
||||
set(val) {
|
||||
this.$store.dispatch('ChangeRoles', val).then(() => {
|
||||
this.$store.dispatch('user/changeRoles', val).then(() => {
|
||||
this.$emit('change')
|
||||
})
|
||||
}
|
||||
|
@@ -7,7 +7,9 @@
|
||||
Only
|
||||
<el-tag class="permission-tag" size="small">admin</el-tag> can see this
|
||||
</span>
|
||||
<el-tag v-permission="['admin']" class="permission-sourceCode" type="info">v-permission="['admin']"</el-tag>
|
||||
<el-tag v-permission="['admin']" class="permission-sourceCode" type="info">
|
||||
v-permission="['admin']"
|
||||
</el-tag>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@@ -15,7 +17,9 @@
|
||||
Only
|
||||
<el-tag class="permission-tag" size="small">editor</el-tag> can see this
|
||||
</span>
|
||||
<el-tag v-permission="['editor']" class="permission-sourceCode" type="info">v-permission="['editor']"</el-tag>
|
||||
<el-tag v-permission="['editor']" class="permission-sourceCode" type="info">
|
||||
v-permission="['editor']"
|
||||
</el-tag>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@@ -24,7 +28,9 @@
|
||||
<el-tag class="permission-tag" size="small">admin</el-tag> and
|
||||
<el-tag class="permission-tag" size="small">editor</el-tag> can see this
|
||||
</span>
|
||||
<el-tag v-permission="['admin','editor']" class="permission-sourceCode" type="info">v-permission="['admin','editor']"</el-tag>
|
||||
<el-tag v-permission="['admin','editor']" class="permission-sourceCode" type="info">
|
||||
v-permission="['admin','editor']"
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -37,17 +43,23 @@
|
||||
<el-tabs type="border-card" style="width:550px;">
|
||||
<el-tab-pane v-if="checkPermission(['admin'])" label="Admin">
|
||||
Admin can see this
|
||||
<el-tag class="permission-sourceCode" type="info">v-if="checkPermission(['admin'])"</el-tag>
|
||||
<el-tag class="permission-sourceCode" type="info">
|
||||
v-if="checkPermission(['admin'])"
|
||||
</el-tag>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane v-if="checkPermission(['editor'])" label="Editor">
|
||||
Editor can see this
|
||||
<el-tag class="permission-sourceCode" type="info">v-if="checkPermission(['editor'])"</el-tag>
|
||||
<el-tag class="permission-sourceCode" type="info">
|
||||
v-if="checkPermission(['editor'])"
|
||||
</el-tag>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane v-if="checkPermission(['admin','editor'])" label="Admin-OR-Editor">
|
||||
Both admin or editor can see this
|
||||
<el-tag class="permission-sourceCode" type="info">v-if="checkPermission(['admin','editor'])"</el-tag>
|
||||
<el-tag class="permission-sourceCode" type="info">
|
||||
v-if="checkPermission(['admin','editor'])"
|
||||
</el-tag>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
@@ -77,7 +89,7 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
<style lang="scss" scoped>
|
||||
.app-container {
|
||||
/deep/ .permission-alert {
|
||||
width: 320px;
|
||||
|
@@ -1,21 +1,33 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-button type="primary" @click="handleAddRole">{{ $t('permission.addRole') }}</el-button>
|
||||
<el-button type="primary" @click="handleAddRole">
|
||||
{{ $t('permission.addRole') }}
|
||||
</el-button>
|
||||
|
||||
<el-table :data="rolesList" style="width: 100%;margin-top:30px;" border>
|
||||
<el-table-column align="center" label="Role Key" width="220">
|
||||
<template slot-scope="scope">{{ scope.row.key }}</template>
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.key }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="Role Name" width="220">
|
||||
<template slot-scope="scope">{{ scope.row.name }}</template>
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.name }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="header-center" label="Description">
|
||||
<template slot-scope="scope">{{ scope.row.description }}</template>
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.description }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="Operations">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="primary" size="small" @click="handleEdit(scope)">{{ $t('permission.editPermission') }}</el-button>
|
||||
<el-button type="danger" size="small" @click="handleDelete(scope)">{{ $t('permission.delete') }}</el-button>
|
||||
<el-button type="primary" size="small" @click="handleEdit(scope)">
|
||||
{{ $t('permission.editPermission') }}
|
||||
</el-button>
|
||||
<el-button type="danger" size="small" @click="handleDelete(scope)">
|
||||
{{ $t('permission.delete') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -38,12 +50,15 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div style="text-align:right;">
|
||||
<el-button type="danger" @click="dialogVisible=false">{{ $t('permission.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="confirmRole">{{ $t('permission.confirm') }}</el-button>
|
||||
<el-button type="danger" @click="dialogVisible=false">
|
||||
{{ $t('permission.cancel') }}
|
||||
</el-button>
|
||||
<el-button type="primary" @click="confirmRole">
|
||||
{{ $t('permission.confirm') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -173,7 +188,7 @@ export default {
|
||||
type: 'warning'
|
||||
})
|
||||
.then(async() => {
|
||||
await deleteRole(row.id)
|
||||
await deleteRole(row.key)
|
||||
this.rolesList.splice($index, 1)
|
||||
this.$message({
|
||||
type: 'success',
|
||||
@@ -215,7 +230,7 @@ export default {
|
||||
}
|
||||
} else {
|
||||
const { data } = await addRole(this.role)
|
||||
this.role.key = data
|
||||
this.role.key = data.key
|
||||
this.rolesList.push(this.role)
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,9 @@
|
||||
<template>
|
||||
<el-upload :data="dataObj" :multiple="true" :before-upload="beforeUpload" action="https://upload.qbox.me" drag>
|
||||
<i class="el-icon-upload" />
|
||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
<div class="el-upload__text">
|
||||
将文件拖到此处,或<em>点击上传</em>
|
||||
</div>
|
||||
</el-upload>
|
||||
</template>
|
||||
|
||||
|
@@ -42,7 +42,7 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
<style lang="scss" scoped>
|
||||
.icons-container {
|
||||
margin: 10px 20px 0;
|
||||
overflow: hidden;
|
||||
|
@@ -1,6 +1,5 @@
|
||||
<template>
|
||||
<el-table :data="list" border fit highlight-current-row style="width: 100%">
|
||||
|
||||
<el-table-column
|
||||
v-loading="loading"
|
||||
align="center"
|
||||
@@ -51,7 +50,6 @@
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</template>
|
||||
|
||||
|
@@ -11,10 +11,18 @@
|
||||
<el-select v-model="listQuery.sort" style="width: 140px" class="filter-item" @change="handleFilter">
|
||||
<el-option v-for="item in sortOptions" :key="item.key" :label="item.label" :value="item.key" />
|
||||
</el-select>
|
||||
<el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">{{ $t('table.search') }}</el-button>
|
||||
<el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-edit" @click="handleCreate">{{ $t('table.add') }}</el-button>
|
||||
<el-button v-waves :loading="downloadLoading" class="filter-item" type="primary" icon="el-icon-download" @click="handleDownload">{{ $t('table.export') }}</el-button>
|
||||
<el-checkbox v-model="showReviewer" class="filter-item" style="margin-left:15px;" @change="tableKey=tableKey+1">{{ $t('table.reviewer') }}</el-checkbox>
|
||||
<el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">
|
||||
{{ $t('table.search') }}
|
||||
</el-button>
|
||||
<el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-edit" @click="handleCreate">
|
||||
{{ $t('table.add') }}
|
||||
</el-button>
|
||||
<el-button v-waves :loading="downloadLoading" class="filter-item" type="primary" icon="el-icon-download" @click="handleDownload">
|
||||
{{ $t('table.export') }}
|
||||
</el-button>
|
||||
<el-checkbox v-model="showReviewer" class="filter-item" style="margin-left:15px;" @change="tableKey=tableKey+1">
|
||||
{{ $t('table.reviewer') }}
|
||||
</el-checkbox>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
@@ -27,7 +35,7 @@
|
||||
style="width: 100%;"
|
||||
@sort-change="sortChange"
|
||||
>
|
||||
<el-table-column :label="$t('table.id')" prop="id" sortable="custom" align="center" width="65">
|
||||
<el-table-column :label="$t('table.id')" prop="id" sortable="custom" align="center" width="80">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.id }}</span>
|
||||
</template>
|
||||
@@ -66,12 +74,16 @@
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.status')" class-name="status-col" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="scope.row.status | statusFilter">{{ scope.row.status }}</el-tag>
|
||||
<el-tag :type="scope.row.status | statusFilter">
|
||||
{{ scope.row.status }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.actions')" align="center" width="230" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="primary" size="mini" @click="handleUpdate(scope.row)">{{ $t('table.edit') }}</el-button>
|
||||
<el-button type="primary" size="mini" @click="handleUpdate(scope.row)">
|
||||
{{ $t('table.edit') }}
|
||||
</el-button>
|
||||
<el-button v-if="scope.row.status!='published'" size="mini" type="success" @click="handleModifyStatus(scope.row,'published')">
|
||||
{{ $t('table.publish') }}
|
||||
</el-button>
|
||||
@@ -113,8 +125,12 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogFormVisible = false">{{ $t('table.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">{{ $t('table.confirm') }}</el-button>
|
||||
<el-button @click="dialogFormVisible = false">
|
||||
{{ $t('table.cancel') }}
|
||||
</el-button>
|
||||
<el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">
|
||||
{{ $t('table.confirm') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
@@ -127,7 +143,6 @@
|
||||
<el-button type="primary" @click="dialogPvVisible = false">{{ $t('table.confirm') }}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@@ -2,7 +2,6 @@
|
||||
<div class="app-container">
|
||||
<!-- Note that row-key is necessary to get a correct row order. -->
|
||||
<el-table ref="dragTable" v-loading="listLoading" :data="list" row-key="id" border fit highlight-current-row style="width: 100%">
|
||||
|
||||
<el-table-column align="center" label="ID" width="65">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.id }}</span>
|
||||
@@ -41,7 +40,9 @@
|
||||
|
||||
<el-table-column class-name="status-col" label="Status" width="110">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="scope.row.status | statusFilter">{{ scope.row.status }}</el-tag>
|
||||
<el-tag :type="scope.row.status | statusFilter">
|
||||
{{ scope.row.status }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
@@ -50,12 +51,14 @@
|
||||
<svg-icon class="drag-handler" icon-class="drag" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
<!-- $t is vue-i18n global function to translate lang (lang in @/lang) -->
|
||||
<div class="show-d">{{ $t('table.dragTips1') }} : {{ oldList }}</div>
|
||||
<div class="show-d">{{ $t('table.dragTips2') }} : {{ newList }}</div>
|
||||
|
||||
<div class="show-d">
|
||||
{{ $t('table.dragTips1') }} : {{ oldList }}
|
||||
</div>
|
||||
<div class="show-d">
|
||||
{{ $t('table.dragTips2') }} : {{ newList }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -93,17 +96,16 @@ export default {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
async getList() {
|
||||
this.listLoading = true
|
||||
fetchList(this.listQuery).then(response => {
|
||||
this.list = response.data.items
|
||||
this.total = response.data.total
|
||||
this.listLoading = false
|
||||
this.oldList = this.list.map(v => v.id)
|
||||
this.newList = this.oldList.slice()
|
||||
this.$nextTick(() => {
|
||||
this.setSort()
|
||||
})
|
||||
const { data } = await fetchList(this.listQuery)
|
||||
this.list = data.items
|
||||
this.total = data.total
|
||||
this.listLoading = false
|
||||
this.oldList = this.list.map(v => v.id)
|
||||
this.newList = this.oldList.slice()
|
||||
this.$nextTick(() => {
|
||||
this.setSort()
|
||||
})
|
||||
},
|
||||
setSort() {
|
||||
|
@@ -1,11 +1,16 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
|
||||
<div class="filter-container">
|
||||
<el-checkbox-group v-model="checkboxVal">
|
||||
<el-checkbox label="apple">apple</el-checkbox>
|
||||
<el-checkbox label="banana">banana</el-checkbox>
|
||||
<el-checkbox label="orange">orange</el-checkbox>
|
||||
<el-checkbox label="apple">
|
||||
apple
|
||||
</el-checkbox>
|
||||
<el-checkbox label="banana">
|
||||
banana
|
||||
</el-checkbox>
|
||||
<el-checkbox label="orange">
|
||||
orange
|
||||
</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</div>
|
||||
|
||||
@@ -17,7 +22,6 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@@ -1,9 +1,13 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div style="margin:0 0 5px 20px">{{ $t('table.dynamicTips1') }}</div>
|
||||
<div style="margin:0 0 5px 20px">
|
||||
{{ $t('table.dynamicTips1') }}
|
||||
</div>
|
||||
<fixed-thead />
|
||||
|
||||
<div style="margin:30px 0 5px 20px">{{ $t('table.dynamicTips2') }}</div>
|
||||
<div style="margin:30px 0 5px 20px">
|
||||
{{ $t('table.dynamicTips2') }}
|
||||
</div>
|
||||
<unfixed-thead />
|
||||
</div>
|
||||
</template>
|
||||
|
@@ -1,11 +1,16 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
|
||||
<div class="filter-container">
|
||||
<el-checkbox-group v-model="formThead">
|
||||
<el-checkbox label="apple">apple</el-checkbox>
|
||||
<el-checkbox label="banana">banana</el-checkbox>
|
||||
<el-checkbox label="orange">orange</el-checkbox>
|
||||
<el-checkbox label="apple">
|
||||
apple
|
||||
</el-checkbox>
|
||||
<el-checkbox label="banana">
|
||||
banana
|
||||
</el-checkbox>
|
||||
<el-checkbox label="orange">
|
||||
orange
|
||||
</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</div>
|
||||
|
||||
@@ -17,7 +22,6 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@@ -1,8 +1,6 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
|
||||
<el-table v-loading="listLoading" :data="list" border fit highlight-current-row style="width: 100%">
|
||||
|
||||
<el-table-column align="center" label="ID" width="80">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.id }}</span>
|
||||
@@ -29,7 +27,9 @@
|
||||
|
||||
<el-table-column class-name="status-col" label="Status" width="110">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="scope.row.status | statusFilter">{{ scope.row.status }}</el-tag>
|
||||
<el-tag :type="scope.row.status | statusFilter">
|
||||
{{ scope.row.status }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
@@ -37,7 +37,9 @@
|
||||
<template slot-scope="scope">
|
||||
<template v-if="scope.row.edit">
|
||||
<el-input v-model="scope.row.title" class="edit-input" size="small" />
|
||||
<el-button class="cancel-btn" size="small" icon="el-icon-refresh" type="warning" @click="cancelEdit(scope.row)">cancel</el-button>
|
||||
<el-button class="cancel-btn" size="small" icon="el-icon-refresh" type="warning" @click="cancelEdit(scope.row)">
|
||||
cancel
|
||||
</el-button>
|
||||
</template>
|
||||
<span v-else>{{ scope.row.title }}</span>
|
||||
</template>
|
||||
@@ -45,11 +47,14 @@
|
||||
|
||||
<el-table-column align="center" label="Actions" width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-button v-if="scope.row.edit" type="success" size="small" icon="el-icon-circle-check-outline" @click="confirmEdit(scope.row)">Ok</el-button>
|
||||
<el-button v-else type="primary" size="small" icon="el-icon-edit" @click="scope.row.edit=!scope.row.edit">Edit</el-button>
|
||||
<el-button v-if="scope.row.edit" type="success" size="small" icon="el-icon-circle-check-outline" @click="confirmEdit(scope.row)">
|
||||
Ok
|
||||
</el-button>
|
||||
<el-button v-else type="primary" size="small" icon="el-icon-edit" @click="scope.row.edit=!scope.row.edit">
|
||||
Edit
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
@@ -83,17 +88,16 @@ export default {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
async getList() {
|
||||
this.listLoading = true
|
||||
fetchList(this.listQuery).then(response => {
|
||||
const items = response.data.items
|
||||
this.list = items.map(v => {
|
||||
this.$set(v, 'edit', false) // https://vuejs.org/v2/guide/reactivity.html
|
||||
v.originalTitle = v.title // will be used when user click the cancel botton
|
||||
return v
|
||||
})
|
||||
this.listLoading = false
|
||||
const { data } = await fetchList(this.listQuery)
|
||||
const items = data.items
|
||||
this.list = items.map(v => {
|
||||
this.$set(v, 'edit', false) // https://vuejs.org/v2/guide/reactivity.html
|
||||
v.originalTitle = v.title // will be used when user click the cancel botton
|
||||
return v
|
||||
})
|
||||
this.listLoading = false
|
||||
},
|
||||
cancelEdit(row) {
|
||||
row.title = row.originalTitle
|
||||
|
@@ -14,18 +14,30 @@
|
||||
</el-card>
|
||||
|
||||
<div class="block">
|
||||
<el-button type="primary">Primary</el-button>
|
||||
<el-button type="success">Success</el-button>
|
||||
<el-button type="info">Info</el-button>
|
||||
<el-button type="warning">Warning</el-button>
|
||||
<el-button type="danger">Danger</el-button>
|
||||
<el-button type="primary">
|
||||
Primary
|
||||
</el-button>
|
||||
<el-button type="success">
|
||||
Success
|
||||
</el-button>
|
||||
<el-button type="info">
|
||||
Info
|
||||
</el-button>
|
||||
<el-button type="warning">
|
||||
Warning
|
||||
</el-button>
|
||||
<el-button type="danger">
|
||||
Danger
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<div class="block">
|
||||
<el-button type="primary" icon="el-icon-edit" />
|
||||
<el-button type="primary" icon="el-icon-share" />
|
||||
<el-button type="primary" icon="el-icon-delete" />
|
||||
<el-button type="primary" icon="el-icon-search">Search</el-button>
|
||||
<el-button type="primary" icon="el-icon-search">
|
||||
Search
|
||||
</el-button>
|
||||
<el-button type="primary">
|
||||
Upload
|
||||
<i class="el-icon-upload el-icon-right" />
|
||||
@@ -40,16 +52,21 @@
|
||||
|
||||
<div class="block">
|
||||
<el-radio-group v-model="radio">
|
||||
<el-radio :label="3">Option A</el-radio>
|
||||
<el-radio :label="6">Option B</el-radio>
|
||||
<el-radio :label="9">Option C</el-radio>
|
||||
<el-radio :label="3">
|
||||
Option A
|
||||
</el-radio>
|
||||
<el-radio :label="6">
|
||||
Option B
|
||||
</el-radio>
|
||||
<el-radio :label="9">
|
||||
Option C
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
|
||||
<div class="block">
|
||||
<el-slider v-model="slideValue" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@@ -1,51 +0,0 @@
|
||||
const data = [
|
||||
{
|
||||
name: '1',
|
||||
timeLine: 100,
|
||||
children: [
|
||||
{
|
||||
name: '1-1',
|
||||
timeLine: 20
|
||||
},
|
||||
{
|
||||
name: '1-2',
|
||||
timeLine: 60,
|
||||
children: [
|
||||
{
|
||||
name: '1-2-1',
|
||||
timeLine: 35
|
||||
},
|
||||
{
|
||||
name: '1-2-2',
|
||||
timeLine: 25
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '2',
|
||||
timeLine: 80,
|
||||
children: [
|
||||
{
|
||||
name: '2-1',
|
||||
timeLine: 30
|
||||
},
|
||||
{
|
||||
name: '2-2',
|
||||
timeLine: 50
|
||||
},
|
||||
{
|
||||
name: '2-3',
|
||||
timeLine: 60
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '3',
|
||||
timeLine: 40
|
||||
}
|
||||
]
|
||||
|
||||
export default data
|
||||
|
@@ -1,158 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="app-container">
|
||||
|
||||
<el-button type="primary" size="small" style="margin:0 0 20px 0;">
|
||||
<a href="https://github.com/PanJiaChen/vue-element-admin/tree/master/src/components/TreeTable" target="_blank">Documentation</a>
|
||||
</el-button>
|
||||
|
||||
<tree-table
|
||||
ref="TreeTable"
|
||||
:data="tableData"
|
||||
:default-expand-all="true"
|
||||
:columns="columns"
|
||||
border
|
||||
default-children="children"
|
||||
@selection-change="selectChange"
|
||||
>
|
||||
|
||||
<template slot="selection">
|
||||
<el-table-column type="selection" align="center" width="55" />
|
||||
</template>
|
||||
|
||||
<template slot="pre-column">
|
||||
<el-table-column type="expand" width="55">
|
||||
<template>
|
||||
<el-tag type="info">
|
||||
Here is just a placeholder slot, you can display anything.
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
|
||||
<template slot="timeline" slot-scope="{scope}">
|
||||
|
||||
<el-tooltip :content="scope.row.timeLine+'ms'" effect="dark" placement="left">
|
||||
<div class="processContainer">
|
||||
<div
|
||||
:style="{ width:(scope.row.timeLine||0) * 3+'px',
|
||||
background:scope.row.timeLine>50?'rgba(233,0,0,.5)':'rgba(0,0,233,0.5)',
|
||||
marginLeft:scope.row._level * 50+'px' }"
|
||||
class="process"
|
||||
>
|
||||
<span style="display:inline-block" />
|
||||
</div>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
|
||||
</template>
|
||||
|
||||
<template slot="append" slot-scope="{scope}">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="primary"
|
||||
@click="addMenuItem(scope.row,'brother')"
|
||||
>Append Brother
|
||||
</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="primary"
|
||||
@click="addMenuItem(scope.row,'children')"
|
||||
>Append Child
|
||||
</el-button>
|
||||
</template>
|
||||
<template slot="operation" slot-scope="{scope}">
|
||||
<el-button size="mini" type="success" @click="editItem(scope.row)">Edit</el-button>
|
||||
<el-button size="mini" type="danger" @click="deleteItem(scope.row)">Delete</el-button>
|
||||
</template>
|
||||
</tree-table>
|
||||
</div>
|
||||
|
||||
<el-dialog :visible.sync="dialogFormVisible" title="Edit">
|
||||
<el-form :model="tempItem" label-width="100px" style="width:600px">
|
||||
<el-form-item label="Name">
|
||||
<el-input v-model.trim="tempItem.name" placeholder="Name" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogFormVisible = false">Cancel</el-button>
|
||||
<el-button type="primary" @click="updateItem">Confirm</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TreeTable from '@/components/TreeTable'
|
||||
import data from './data.js'
|
||||
|
||||
export default {
|
||||
components: { TreeTable },
|
||||
data() {
|
||||
return {
|
||||
tableData: [],
|
||||
tempItem: {},
|
||||
dialogFormVisible: false,
|
||||
columns: [
|
||||
{
|
||||
label: 'Name',
|
||||
key: 'name',
|
||||
expand: true
|
||||
},
|
||||
{
|
||||
label: 'Timeline',
|
||||
key: 'timeline'
|
||||
},
|
||||
{
|
||||
label: 'Append',
|
||||
key: 'append',
|
||||
width: 300
|
||||
},
|
||||
{
|
||||
label: 'Operation',
|
||||
key: 'operation',
|
||||
width: 160
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getData()
|
||||
},
|
||||
methods: {
|
||||
getData() {
|
||||
this.tableData = data
|
||||
},
|
||||
editItem(row) {
|
||||
this.tempItem = Object.assign({}, row)
|
||||
this.dialogFormVisible = true
|
||||
},
|
||||
async updateItem() {
|
||||
await this.$refs.TreeTable.updateTreeNode(this.tempItem)
|
||||
this.dialogFormVisible = false
|
||||
},
|
||||
addMenuItem(row, type) {
|
||||
if (type === 'children') {
|
||||
this.$refs.TreeTable.addChild(row, { name: 'child', timeLine: this.randomNum() })
|
||||
}
|
||||
|
||||
if (type === 'brother') {
|
||||
this.$refs.TreeTable.addBrother(row, { name: 'brother', timeLine: this.randomNum() })
|
||||
}
|
||||
},
|
||||
deleteItem(row) {
|
||||
this.$refs.TreeTable.delete(row)
|
||||
},
|
||||
selectChange(val) {
|
||||
console.log(val)
|
||||
},
|
||||
randomNum() {
|
||||
// return 1~100
|
||||
const max = 100
|
||||
const min = 1
|
||||
return Math.floor(Math.random() * (max - min + 1) + min)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@@ -1,80 +0,0 @@
|
||||
|
||||
const data = [
|
||||
{
|
||||
id: 0,
|
||||
event: 'Event-0',
|
||||
timeLine: 50
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
event: 'Event-1',
|
||||
timeLine: 100,
|
||||
children: [
|
||||
{
|
||||
id: 2,
|
||||
event: 'Event-2',
|
||||
timeLine: 10
|
||||
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
event: 'Event-3',
|
||||
timeLine: 90,
|
||||
children: [
|
||||
{
|
||||
id: 4,
|
||||
event: 'Event-4',
|
||||
timeLine: 5
|
||||
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
event: 'Event-5',
|
||||
timeLine: 10
|
||||
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
event: 'Event-6',
|
||||
timeLine: 75,
|
||||
|
||||
children: [
|
||||
{
|
||||
id: 7,
|
||||
event: 'Event-7',
|
||||
timeLine: 50,
|
||||
|
||||
children: [
|
||||
{
|
||||
id: 71,
|
||||
event: 'Event-7-1',
|
||||
timeLine: 25
|
||||
|
||||
},
|
||||
{
|
||||
id: 72,
|
||||
event: 'Event-7-2',
|
||||
timeLine: 5
|
||||
|
||||
},
|
||||
{
|
||||
id: 73,
|
||||
event: 'Event-7-3',
|
||||
timeLine: 20
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
event: 'Event-8',
|
||||
timeLine: 25
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
export default data
|
@@ -1,128 +0,0 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
|
||||
<div style="margin-bottom:20px;">
|
||||
|
||||
<el-button type="primary" size="small" class="option-item">
|
||||
<a href="https://github.com/PanJiaChen/vue-element-admin/tree/master/src/components/TreeTable" target="_blank">Documentation</a>
|
||||
</el-button>
|
||||
|
||||
<div class="option-item">
|
||||
<el-tag>Expand All</el-tag>
|
||||
<el-switch
|
||||
v-model="defaultExpandAll"
|
||||
active-color="#13ce66"
|
||||
inactive-color="#ff4949"
|
||||
@change="reset"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="option-item">
|
||||
<el-tag>Show Checkbox</el-tag>
|
||||
<el-switch
|
||||
v-model="showCheckbox"
|
||||
active-color="#13ce66"
|
||||
inactive-color="#ff4949"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<tree-table :key="key" :default-expand-all="defaultExpandAll" :data="data" :columns="columns" border>
|
||||
<template slot="scope" slot-scope="{scope}">
|
||||
<el-tag>level: {{ scope.row._level }}</el-tag>
|
||||
<el-tag>expand: {{ scope.row._expand }}</el-tag>
|
||||
<el-tag>select: {{ scope.row._select }}</el-tag>
|
||||
</template>
|
||||
<template slot="operation" slot-scope="{scope}">
|
||||
<el-button type="primary" size="" @click="click(scope)">Click</el-button>
|
||||
</template>
|
||||
</tree-table>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import treeTable from '@/components/TreeTable'
|
||||
import data from './data'
|
||||
|
||||
export default {
|
||||
name: 'TreeTableDemo',
|
||||
components: { treeTable },
|
||||
data() {
|
||||
return {
|
||||
defaultExpandAll: false,
|
||||
showCheckbox: true,
|
||||
key: 1,
|
||||
columns: [
|
||||
{
|
||||
label: 'Checkbox',
|
||||
checkbox: true
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
key: 'id',
|
||||
expand: true
|
||||
},
|
||||
{
|
||||
label: 'Event',
|
||||
key: 'event',
|
||||
width: 200,
|
||||
align: 'left'
|
||||
},
|
||||
{
|
||||
label: 'Scope',
|
||||
key: 'scope'
|
||||
},
|
||||
{
|
||||
label: 'Operation',
|
||||
key: 'operation'
|
||||
}
|
||||
],
|
||||
data: data
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
showCheckbox(val) {
|
||||
if (val) {
|
||||
this.columns.unshift({
|
||||
label: 'Checkbox',
|
||||
checkbox: true
|
||||
})
|
||||
} else {
|
||||
this.columns.shift()
|
||||
}
|
||||
this.reset()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
reset() {
|
||||
++this.key
|
||||
},
|
||||
click(scope) {
|
||||
console.log(scope)
|
||||
|
||||
const row = scope.row
|
||||
const message = Object.keys(row)
|
||||
.map(i => {
|
||||
return `<p>${i}: ${row[i]}</p>`
|
||||
})
|
||||
.join('')
|
||||
|
||||
this.$notify({
|
||||
title: 'Success',
|
||||
dangerouslyUseHTMLString: true,
|
||||
message: message,
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.option-item{
|
||||
display: inline-block;
|
||||
margin-right: 15px;
|
||||
}
|
||||
</style>
|
@@ -2,7 +2,9 @@
|
||||
<div class="app-container">
|
||||
<!-- $t is vue-i18n global function to translate lang -->
|
||||
<el-input v-model="filename" :placeholder="$t('zip.placeholder')" style="width:300px;" prefix-icon="el-icon-document" />
|
||||
<el-button :loading="downloadLoading" style="margin-bottom:20px;" type="primary" icon="document" @click="handleDownload">{{ $t('zip.export') }} zip</el-button>
|
||||
<el-button :loading="downloadLoading" style="margin-bottom:20px;" type="primary" icon="document" @click="handleDownload">
|
||||
{{ $t('zip.export') }} zip
|
||||
</el-button>
|
||||
<el-table v-loading="listLoading" :data="list" element-loading-text="拼命加载中" border fit highlight-current-row>
|
||||
<el-table-column align="center" label="ID" width="95">
|
||||
<template slot-scope="scope">
|
||||
@@ -51,12 +53,11 @@ export default {
|
||||
this.fetchData()
|
||||
},
|
||||
methods: {
|
||||
fetchData() {
|
||||
async fetchData() {
|
||||
this.listLoading = true
|
||||
fetchList().then(response => {
|
||||
this.list = response.data.items
|
||||
this.listLoading = false
|
||||
})
|
||||
const { data } = await fetchList()
|
||||
this.list = data.items
|
||||
this.listLoading = false
|
||||
},
|
||||
handleDownload() {
|
||||
this.downloadLoading = true
|
||||
|
Reference in New Issue
Block a user