Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
VueElementTemplate
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
黄瑜
VueElementTemplate
Commits
374fd3ff
Commit
374fd3ff
authored
Nov 01, 2017
by
Pan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feature:change theme online
parent
e8b34bbc
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
285 additions
and
99 deletions
+285
-99
webpack.dev.conf.js
build/webpack.dev.conf.js
+3
-1
webpack.prod.conf.js
build/webpack.prod.conf.js
+3
-1
index.vue
src/components/ThemePicker/index.vue
+145
-0
index.js
src/utils/index.js
+5
-0
Navbar.vue
src/views/layout/components/Navbar.vue
+94
-69
index.vue
src/views/theme/index.vue
+35
-28
No files found.
build/webpack.dev.conf.js
View file @
374fd3ff
...
@@ -6,6 +6,7 @@ var merge = require('webpack-merge')
...
@@ -6,6 +6,7 @@ var merge = require('webpack-merge')
var
baseWebpackConfig
=
require
(
'./webpack.base.conf'
)
var
baseWebpackConfig
=
require
(
'./webpack.base.conf'
)
var
HtmlWebpackPlugin
=
require
(
'html-webpack-plugin'
)
var
HtmlWebpackPlugin
=
require
(
'html-webpack-plugin'
)
var
FriendlyErrorsPlugin
=
require
(
'friendly-errors-webpack-plugin'
)
var
FriendlyErrorsPlugin
=
require
(
'friendly-errors-webpack-plugin'
)
var
dependencies
=
require
(
'../package.json'
).
dependencies
// add hot-reload related code to entry chunks
// add hot-reload related code to entry chunks
Object
.
keys
(
baseWebpackConfig
.
entry
).
forEach
(
function
(
name
)
{
Object
.
keys
(
baseWebpackConfig
.
entry
).
forEach
(
function
(
name
)
{
...
@@ -27,7 +28,8 @@ module.exports = merge(baseWebpackConfig, {
...
@@ -27,7 +28,8 @@ module.exports = merge(baseWebpackConfig, {
cache
:
true
,
cache
:
true
,
plugins
:
[
plugins
:
[
new
webpack
.
DefinePlugin
({
new
webpack
.
DefinePlugin
({
'process.env'
:
config
.
dev
.
env
'process.env'
:
config
.
dev
.
env
,
'DEPENDENCIES'
:
JSON
.
stringify
(
dependencies
)
}),
}),
// https://github.com/glenjamin/webpack-hot-middleware#installation--usage
// https://github.com/glenjamin/webpack-hot-middleware#installation--usage
new
webpack
.
HotModuleReplacementPlugin
(),
new
webpack
.
HotModuleReplacementPlugin
(),
...
...
build/webpack.prod.conf.js
View file @
374fd3ff
...
@@ -8,6 +8,7 @@ var CopyWebpackPlugin = require('copy-webpack-plugin')
...
@@ -8,6 +8,7 @@ var CopyWebpackPlugin = require('copy-webpack-plugin')
var
HtmlWebpackPlugin
=
require
(
'html-webpack-plugin'
)
var
HtmlWebpackPlugin
=
require
(
'html-webpack-plugin'
)
var
ExtractTextPlugin
=
require
(
'extract-text-webpack-plugin'
)
var
ExtractTextPlugin
=
require
(
'extract-text-webpack-plugin'
)
var
OptimizeCSSPlugin
=
require
(
'optimize-css-assets-webpack-plugin'
)
var
OptimizeCSSPlugin
=
require
(
'optimize-css-assets-webpack-plugin'
)
var
dependencies
=
require
(
'../package.json'
).
dependencies
var
env
=
config
.
build
[
process
.
env
.
env_config
+
'Env'
]
var
env
=
config
.
build
[
process
.
env
.
env_config
+
'Env'
]
...
@@ -33,7 +34,8 @@ var webpackConfig = merge(baseWebpackConfig, {
...
@@ -33,7 +34,8 @@ var webpackConfig = merge(baseWebpackConfig, {
new
webpack
.
optimize
.
ModuleConcatenationPlugin
(),
new
webpack
.
optimize
.
ModuleConcatenationPlugin
(),
// http://vuejs.github.io/vue-loader/en/workflow/production.html
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new
webpack
.
DefinePlugin
({
new
webpack
.
DefinePlugin
({
'process.env'
:
env
'process.env'
:
env
,
'DEPENDENCIES'
:
JSON
.
stringify
(
dependencies
)
}),
}),
new
webpack
.
optimize
.
UglifyJsPlugin
({
new
webpack
.
optimize
.
UglifyJsPlugin
({
compress
:
{
compress
:
{
...
...
src/components/ThemePicker/index.vue
0 → 100644
View file @
374fd3ff
<
template
>
<el-color-picker
class=
"theme-picker"
popper-class=
"theme-picker-dropdown"
v-model=
"theme"
></el-color-picker>
</
template
>
<
script
>
import
{
getVersion
}
from
'@/utils/index.js'
const
version
=
getVersion
(
'element-ui'
)
// element-ui version from package.json
const
ORIGINAL_THEME
=
'#409EFF'
// default color
export
default
{
data
()
{
return
{
chalk
:
''
,
// content of theme-chalk css
theme
:
ORIGINAL_THEME
}
},
watch
:
{
theme
(
val
,
oldVal
)
{
if
(
typeof
val
!==
'string'
)
return
const
themeCluster
=
this
.
getThemeCluster
(
val
.
replace
(
'#'
,
''
))
const
originalCluster
=
this
.
getThemeCluster
(
oldVal
.
replace
(
'#'
,
''
))
console
.
log
(
themeCluster
,
originalCluster
)
const
getHandler
=
(
variable
,
id
)
=>
{
return
()
=>
{
const
originalCluster
=
this
.
getThemeCluster
(
ORIGINAL_THEME
.
replace
(
'#'
,
''
))
const
newStyle
=
this
.
updateStyle
(
this
[
variable
],
originalCluster
,
themeCluster
)
let
styleTag
=
document
.
getElementById
(
id
)
if
(
!
styleTag
)
{
styleTag
=
document
.
createElement
(
'style'
)
styleTag
.
setAttribute
(
'id'
,
id
)
document
.
head
.
appendChild
(
styleTag
)
}
styleTag
.
innerText
=
newStyle
}
}
const
chalkHandler
=
getHandler
(
'chalk'
,
'chalk-style'
)
if
(
!
this
.
chalk
)
{
const
url
=
`https://unpkg.com/element-ui@
${
version
}
/lib/theme-chalk/index.css`
this
.
getCSSString
(
url
,
chalkHandler
,
'chalk'
)
}
else
{
chalkHandler
()
}
const
styles
=
[].
slice
.
call
(
document
.
querySelectorAll
(
'style'
))
.
filter
(
style
=>
{
const
text
=
style
.
innerText
return
new
RegExp
(
oldVal
,
'i'
).
test
(
text
)
&&
!
/Chalk Variables/
.
test
(
text
)
})
styles
.
forEach
(
style
=>
{
const
{
innerText
}
=
style
console
.
log
(
style
)
if
(
typeof
innerText
!==
'string'
)
return
style
.
innerText
=
this
.
updateStyle
(
innerText
,
originalCluster
,
themeCluster
)
})
this
.
$message
({
message
:
'换肤成功'
,
type
:
'success'
})
}
},
methods
:
{
updateStyle
(
style
,
oldCluster
,
newCluster
)
{
let
newStyle
=
style
oldCluster
.
forEach
((
color
,
index
)
=>
{
newStyle
=
newStyle
.
replace
(
new
RegExp
(
color
,
'ig'
),
newCluster
[
index
])
})
return
newStyle
},
getCSSString
(
url
,
callback
,
variable
)
{
const
xhr
=
new
XMLHttpRequest
()
xhr
.
onreadystatechange
=
()
=>
{
if
(
xhr
.
readyState
===
4
&&
xhr
.
status
===
200
)
{
this
[
variable
]
=
xhr
.
responseText
.
replace
(
/@font-face{
[^
}
]
+}/
,
''
)
callback
()
}
}
xhr
.
open
(
'GET'
,
url
)
xhr
.
send
()
},
getThemeCluster
(
theme
)
{
const
tintColor
=
(
color
,
tint
)
=>
{
let
red
=
parseInt
(
color
.
slice
(
0
,
2
),
16
)
let
green
=
parseInt
(
color
.
slice
(
2
,
4
),
16
)
let
blue
=
parseInt
(
color
.
slice
(
4
,
6
),
16
)
if
(
tint
===
0
)
{
// when primary color is in its rgb space
return
[
red
,
green
,
blue
].
join
(
','
)
}
else
{
red
+=
Math
.
round
(
tint
*
(
255
-
red
))
green
+=
Math
.
round
(
tint
*
(
255
-
green
))
blue
+=
Math
.
round
(
tint
*
(
255
-
blue
))
red
=
red
.
toString
(
16
)
green
=
green
.
toString
(
16
)
blue
=
blue
.
toString
(
16
)
return
`#
${
red
}${
green
}${
blue
}
`
}
}
const
shadeColor
=
(
color
,
shade
)
=>
{
let
red
=
parseInt
(
color
.
slice
(
0
,
2
),
16
)
let
green
=
parseInt
(
color
.
slice
(
2
,
4
),
16
)
let
blue
=
parseInt
(
color
.
slice
(
4
,
6
),
16
)
red
=
Math
.
round
((
1
-
shade
)
*
red
)
green
=
Math
.
round
((
1
-
shade
)
*
green
)
blue
=
Math
.
round
((
1
-
shade
)
*
blue
)
red
=
red
.
toString
(
16
)
green
=
green
.
toString
(
16
)
blue
=
blue
.
toString
(
16
)
return
`#
${
red
}${
green
}${
blue
}
`
}
const
clusters
=
[
theme
]
for
(
let
i
=
0
;
i
<=
9
;
i
++
)
{
clusters
.
push
(
tintColor
(
theme
,
Number
((
i
/
10
).
toFixed
(
2
))))
}
clusters
.
push
(
shadeColor
(
theme
,
0.1
))
return
clusters
}
}
}
</
script
>
<
style
>
.theme-picker
.el-color-picker__trigger
{
vertical-align
:
middle
;
}
.theme-picker-dropdown
.el-color-dropdown__link-btn
{
display
:
none
;
}
</
style
>
src/utils/index.js
View file @
374fd3ff
...
@@ -265,3 +265,8 @@ export function deepClone(source) {
...
@@ -265,3 +265,8 @@ export function deepClone(source) {
}
}
return
targetObj
return
targetObj
}
}
// get dependencies verison from package.json by webpack.DefinePlugin
export
function
getVersion
(
name
)
{
return
DEPENDENCIES
[
name
]
// eslint-disable-line
}
src/views/layout/components/Navbar.vue
View file @
374fd3ff
<
template
>
<
template
>
<el-menu
class=
"navbar"
mode=
"horizontal"
>
<el-menu
class=
"navbar"
mode=
"horizontal"
>
<hamburger
class=
"hamburger-container"
:toggleClick=
"toggleSideBar"
:isActive=
"sidebar.opened"
></hamburger>
<hamburger
class=
"hamburger-container"
:toggleClick=
"toggleSideBar"
:isActive=
"sidebar.opened"
></hamburger>
<levelbar></levelbar>
<levelbar></levelbar>
<error-log
v-if=
"log.length>0"
class=
"errLog-container"
:logsList=
"log"
></error-log>
<el-tooltip
class=
"item"
effect=
"dark"
content=
"全屏"
placement=
"bottom"
>
<div
class=
"right-menu"
>
<screenfull
class=
'screenfull'
></screenfull>
</el-tooltip>
<error-log
v-if=
"log.length>0"
class=
"errLog-container right-menu-item"
:logsList=
"log"
></error-log>
<el-dropdown
class=
"avatar-container"
trigger=
"click"
>
<div
class=
"avatar-wrapper"
>
<el-tooltip
effect=
"dark"
content=
"全屏"
placement=
"bottom"
>
<img
class=
"user-avatar"
:src=
"avatar+'?imageView2/1/w/80/h/80'"
>
<screenfull
class=
"screenfull right-menu-item"
></screenfull>
<i
class=
"el-icon-caret-bottom"
></i>
</el-tooltip>
</div>
<el-dropdown-menu
class=
"user-dropdown"
slot=
"dropdown"
>
<el-tooltip
effect=
"dark"
content=
"换肤"
placement=
"bottom"
>
<router-link
class=
'inlineBlock'
to=
"/"
>
<theme-picker
class=
"theme-switch right-menu-item"
></theme-picker>
<el-dropdown-item>
</el-tooltip>
首页
</el-dropdown-item>
<el-dropdown
class=
"avatar-container right-menu-item"
trigger=
"click"
>
</router-link>
<div
class=
"avatar-wrapper"
>
<a
target=
'_blank'
href=
"https://github.com/PanJiaChen/vue-element-admin/"
>
<img
class=
"user-avatar"
:src=
"avatar+'?imageView2/1/w/80/h/80'"
>
<el-dropdown-item>
<i
class=
"el-icon-caret-bottom"
></i>
项目地址
</div>
<el-dropdown-menu
class=
"user-dropdown"
slot=
"dropdown"
>
<router-link
class=
"inlineBlock"
to=
"/"
>
<el-dropdown-item>
首页
</el-dropdown-item>
</router-link>
<a
target=
'_blank'
href=
"https://github.com/PanJiaChen/vue-element-admin/"
>
<el-dropdown-item>
项目地址
</el-dropdown-item>
</a>
<el-dropdown-item
divided
>
<span
@
click=
"logout"
style=
"display:block;"
>
退出登录
</span>
</el-dropdown-item>
</el-dropdown-item>
</a>
</el-dropdown-menu>
<el-dropdown-item
divided
>
</el-dropdown>
<span
@
click=
"logout"
style=
"display:block;"
>
退出登录
</span>
</div>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-menu>
</el-menu>
</
template
>
</
template
>
<
script
>
<
script
>
import
{
mapGetters
}
from
'vuex'
import
{
mapGetters
}
from
'vuex'
import
Levelbar
from
'./Levelbar'
import
Levelbar
from
'./Levelbar'
import
Hamburger
from
'components/Hamburger'
import
Hamburger
from
'@/components/Hamburger'
import
Screenfull
from
'components/Screenfull'
import
ThemePicker
from
'@/components/ThemePicker'
import
ErrorLog
from
'components/ErrLog'
import
Screenfull
from
'@/components/Screenfull'
import
ErrorLog
from
'@/components/ErrLog'
import
errLogStore
from
'store/errLog'
import
errLogStore
from
'store/errLog'
export
default
{
export
default
{
components
:
{
components
:
{
Levelbar
,
Levelbar
,
Hamburger
,
Hamburger
,
ThemePicker
,
ErrorLog
,
ErrorLog
,
Screenfull
Screenfull
},
},
...
@@ -72,48 +89,56 @@ export default {
...
@@ -72,48 +89,56 @@ export default {
<
style
rel=
"stylesheet/scss"
lang=
"scss"
scoped
>
<
style
rel=
"stylesheet/scss"
lang=
"scss"
scoped
>
.navbar
{
.navbar
{
height
:
50px
;
height
:
50px
;
line-height
:
50px
;
line-height
:
50px
;
border-radius
:
0px
!
important
;
border-radius
:
0px
!
important
;
.hamburger-container
{
.hamburger-container
{
line-height
:
58px
;
line-height
:
58px
;
height
:
50px
;
height
:
50px
;
float
:
left
;
float
:
left
;
padding
:
0
10px
;
padding
:
0
10px
;
}
}
.errLog-container
{
.errLog-container
{
display
:
inline-block
;
display
:
inline-block
;
position
:
absolute
;
vertical-align
:
top
;
right
:
150px
;
}
}
.right-menu
{
.screenfull
{
float
:
right
;
position
:
absolute
;
height
:
100%
;
right
:
90px
;
&
:focus
{
top
:
16px
;
outline
:
none
;
height
:
20px
;
}
}
.right-menu-item
{
.avatar-container
{
display
:
inline-block
;
height
:
50px
;
margin
:
0
8px
;
display
:
inline-block
;
}
position
:
absolute
;
.screenfull
{
right
:
35px
;
height
:
20px
;
.avatar-wrapper
{
}
cursor
:
pointer
;
.theme-switch
{
margin-top
:
5px
;
vertical-align
:
15px
;
position
:
relative
;
}
.user-avatar
{
.avatar-container
{
width
:
40px
;
height
:
50px
;
height
:
40px
;
margin-right
:
30px
;
border-radius
:
10px
;
.avatar-wrapper
{
}
cursor
:
pointer
;
.el-icon-caret-bottom
{
margin-top
:
5px
;
position
:
absolute
;
position
:
relative
;
right
:
-20px
;
.user-avatar
{
top
:
25px
;
width
:
40px
;
font-size
:
12px
;
height
:
40px
;
}
border-radius
:
10px
;
}
}
}
.el-icon-caret-bottom
{
position
:
absolute
;
right
:
-20px
;
top
:
25px
;
font-size
:
12px
;
}
}
}
}
}
}
</
style
>
</
style
>
...
...
src/views/theme/index.vue
View file @
374fd3ff
...
@@ -12,13 +12,21 @@
...
@@ -12,13 +12,21 @@
</el-card>
</el-card>
<div
class=
"block"
>
<div
class=
"block"
>
<span
class=
"demonstration"
>
Button:
</span>
<el-button
type=
"primary"
>
成功按钮
</el-button>
<span
class=
"wrapper"
>
<el-button
type=
"success"
>
成功按钮
</el-button>
<el-button
type=
"success"
>
成功按钮
</el-button>
<el-button
type=
"warning"
>
警告按钮
</el-button>
<el-button
type=
"warning"
>
警告按钮
</el-button>
<el-button
type=
"danger"
>
危险按钮
</el-button>
<el-button
type=
"danger"
>
危险按钮
</el-button>
<el-button
type=
"info"
>
信息按钮
</el-button>
<el-button
type=
"info"
>
信息按钮
</el-button>
</span>
</div>
<div
class=
"block"
>
<el-button
type=
"primary"
icon=
"el-icon-edit"
></el-button>
<el-button
type=
"primary"
icon=
"el-icon-share"
></el-button>
<el-button
type=
"primary"
icon=
"el-icon-delete"
></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"
></i>
</el-button>
</div>
</div>
<div
class=
"block"
>
<div
class=
"block"
>
...
@@ -28,14 +36,15 @@
...
@@ -28,14 +36,15 @@
</div>
</div>
<div
class=
"block"
>
<div
class=
"block"
>
<el-alert
class=
'alert-item'
title=
"成功提示的文案"
type=
"success"
>
<el-radio-group
v-model=
"radio"
>
</el-alert>
<el-radio
:label=
"3"
>
Option A
</el-radio>
<el-alert
class=
'alert-item'
title=
"消息提示的文案"
type=
"info"
>
<el-radio
:label=
"6"
>
Option B
</el-radio>
</el-alert>
<el-radio
:label=
"9"
>
Option C
</el-radio>
<el-alert
class=
'alert-item'
title=
"警告提示的文案"
type=
"warning"
>
</el-radio-group>
</el-alert>
</div>
<el-alert
class=
'alert-item'
title=
"错误提示的文案"
type=
"error"
>
</el-alert>
<div
class=
"block"
>
<el-slider
v-model=
"slideValue"
></el-slider>
</div>
</div>
</div>
</div>
...
@@ -56,7 +65,9 @@ export default {
...
@@ -56,7 +65,9 @@ export default {
{
name
:
'Tag Three'
,
type
:
'success'
},
{
name
:
'Tag Three'
,
type
:
'success'
},
{
name
:
'Tag Four'
,
type
:
'warning'
},
{
name
:
'Tag Four'
,
type
:
'warning'
},
{
name
:
'Tag Five'
,
type
:
'danger'
}
{
name
:
'Tag Five'
,
type
:
'danger'
}
]
],
slideValue
:
50
,
radio
:
3
}
}
},
},
watch
:
{
watch
:
{
...
@@ -68,20 +79,16 @@ export default {
...
@@ -68,20 +79,16 @@ export default {
</
script
>
</
script
>
<
style
scoped
>
<
style
scoped
>
.box-card
{
.box-card
{
width
:
400px
;
width
:
400px
;
margin
:
20px
auto
;
margin
:
20px
auto
;
}
}
.block
{
padding
:
30px
24px
;
.block
{
}
padding
:
30px
24px
;
.alert-item
{
}
margin-bottom
:
10px
;
}
.tag-item
{
.tag-item
{
margin-right
:
15px
;
margin-right
:
15px
;
}
}
.link-title
{
margin-left
:
35px
;
}
</
style
>
</
style
>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment