Compare commits

...

4 Commits

Author SHA1 Message Date
laven-der
d48ea83378 feature:新增富文本编辑器插件功能入口,提供导出图片功能,全局loading配置 2020-06-11 16:31:07 +08:00
花裤衩
f14805d0cd [release] 4.3.0 2020-06-08 21:35:01 +08:00
花裤衩
c5abe7532c perf: change >>> ::v-deep 2020-06-08 20:42:55 +08:00
Cat73
534cd5bc26 chore: change node-sass to dart-sass (#3040) 2020-06-08 20:41:46 +08:00
13 changed files with 429 additions and 65 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "vue-element-admin", "name": "vue-element-admin",
"version": "4.2.2", "version": "4.3.0",
"description": "A magical vue admin. An out-of-box UI solution for enterprise applications. Newest development stack of vue. Lots of awesome features", "description": "A magical vue admin. An out-of-box UI solution for enterprise applications. Newest development stack of vue. Lots of awesome features",
"author": "Pan <panfree23@gmail.com>", "author": "Pan <panfree23@gmail.com>",
"license": "MIT", "license": "MIT",
@@ -89,12 +89,13 @@
"eslint": "5.15.3", "eslint": "5.15.3",
"eslint-plugin-vue": "5.2.2", "eslint-plugin-vue": "5.2.2",
"html-webpack-plugin": "3.2.0", "html-webpack-plugin": "3.2.0",
"html2canvas": "^1.0.0-rc.5",
"husky": "1.3.1", "husky": "1.3.1",
"lint-staged": "8.1.5", "lint-staged": "8.1.5",
"mockjs": "1.0.1-beta3", "mockjs": "1.0.1-beta3",
"node-sass": "^4.9.0",
"plop": "2.3.0", "plop": "2.3.0",
"runjs": "^4.3.2", "runjs": "^4.3.2",
"sass": "^1.26.2",
"sass-loader": "^7.1.0", "sass-loader": "^7.1.0",
"script-ext-html-webpack-plugin": "2.1.3", "script-ext-html-webpack-plugin": "2.1.3",
"serve-static": "^1.13.2", "serve-static": "^1.13.2",

View File

@@ -48,14 +48,18 @@ export default {
} }
</script> </script>
<style scoped> <style lang="scss" scoped>
.drag-select >>> .sortable-ghost { .drag-select {
opacity: .8; ::v-deep {
color: #fff!important; .sortable-ghost {
background: #42b983!important; opacity: .8;
} color: #fff !important;
background: #42b983 !important;
}
.drag-select >>> .el-tag { .el-tag {
cursor: pointer; cursor: pointer;
}
}
} }
</style> </style>

View File

@@ -159,7 +159,7 @@ export default {
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
/deep/ .el-input__inner { ::v-deep .el-input__inner {
border-radius: 0; border-radius: 0;
border: 0; border: 0;
padding-left: 0; padding-left: 0;

View File

@@ -54,19 +54,24 @@ export default {
} }
</script> </script>
<style scoped> <style lang="scss" scoped>
.json-editor{ .json-editor {
height: 100%; height: 100%;
position: relative; position: relative;
}
.json-editor >>> .CodeMirror { ::v-deep {
height: auto; .CodeMirror {
min-height: 300px; height: auto;
} min-height: 300px;
.json-editor >>> .CodeMirror-scroll{ }
min-height: 300px;
} .CodeMirror-scroll {
.json-editor >>> .cm-s-rubyblue span.cm-string { min-height: 300px;
color: #F08047; }
.cm-s-rubyblue span.cm-string {
color: #F08047;
}
}
} }
</style> </style>

View File

@@ -1,6 +1,12 @@
<template> <template>
<div class="upload-container"> <div class="upload-container">
<el-button :style="{background:color,borderColor:color}" icon="el-icon-upload" size="mini" type="primary" @click=" dialogVisible=true"> <el-button
:style="{background:color,borderColor:color}"
icon="el-icon-upload"
size="mini"
type="primary"
@click=" dialogVisible=true"
>
upload upload
</el-button> </el-button>
<el-dialog :visible.sync="dialogVisible"> <el-dialog :visible.sync="dialogVisible">
@@ -15,14 +21,20 @@
action="https://httpbin.org/post" action="https://httpbin.org/post"
list-type="picture-card" list-type="picture-card"
> >
<el-button size="small" type="primary"> <el-button
size="small"
type="primary"
>
Click upload Click upload
</el-button> </el-button>
</el-upload> </el-upload>
<el-button @click="dialogVisible = false"> <el-button @click="dialogVisible = false">
Cancel Cancel
</el-button> </el-button>
<el-button type="primary" @click="handleSubmit"> <el-button
type="primary"
@click="handleSubmit"
>
Confirm Confirm
</el-button> </el-button>
</el-dialog> </el-dialog>
@@ -49,12 +61,16 @@ export default {
}, },
methods: { methods: {
checkAllSuccess() { checkAllSuccess() {
return Object.keys(this.listObj).every(item => this.listObj[item].hasSuccess) return Object.keys(this.listObj).every(
item => this.listObj[item].hasSuccess
)
}, },
handleSubmit() { handleSubmit() {
const arr = Object.keys(this.listObj).map(v => this.listObj[v]) const arr = Object.keys(this.listObj).map(v => this.listObj[v])
if (!this.checkAllSuccess()) { if (!this.checkAllSuccess()) {
this.$message('Please wait for all images to be uploaded successfully. If there is a network problem, please refresh the page and upload again!') this.$message(
'Please wait for all images to be uploaded successfully. If there is a network problem, please refresh the page and upload again!'
)
return return
} }
this.$emit('successCBK', arr) this.$emit('successCBK', arr)
@@ -92,7 +108,12 @@ export default {
const img = new Image() const img = new Image()
img.src = _URL.createObjectURL(file) img.src = _URL.createObjectURL(file)
img.onload = function() { img.onload = function() {
_self.listObj[fileName] = { hasSuccess: false, uid: file.uid, width: this.width, height: this.height } _self.listObj[fileName] = {
hasSuccess: false,
uid: file.uid,
width: this.width,
height: this.height
}
} }
resolve(true) resolve(true)
}) })
@@ -104,7 +125,7 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.editor-slide-upload { .editor-slide-upload {
margin-bottom: 20px; margin-bottom: 20px;
/deep/ .el-upload--picture-card { ::v-deep .el-upload--picture-card {
width: 100%; width: 100%;
} }
} }

View File

@@ -0,0 +1,234 @@
<template>
<div class="layout-container">
<div ref="list" class="layout-body">
<tinymce
v-model="content"
:menu="menu"
:height="height"
:new-event-list="eventList"
/>
</div>
<div class="util-component" style="display:none;">
<el-upload
:multiple="true"
:file-list="dataList.list"
:on-progress="uploadProgress"
:on-success="handleSuccess"
class="editor-slide-upload"
action="https://httpbin.org/post"
list-type="picture-card"
>
<el-button id="editorUploader" size="small" type="primary">
Click upload
</el-button>
</el-upload>
</div>
<div ref="imageWrapper" class="show-html" v-html="content" />
</div>
</template>
<script>
import Tinymce from './index'
import html2canvas from 'html2canvas'
import { Loading } from 'element-ui'
export default {
name: 'TinymceDemo',
components: { Tinymce },
data() {
return {
showPreviewDialog: false,
dataurl: '',
eventList: [
{
toolbarName: 'uploadImg',
tooltip: 'uploadImg',
text: 'uploadImg',
fn: (e, callback) => {
this.handleAdd('uploadImg', data => {
if (callback && typeof callback === 'function') {
callback(data)
}
})
}
},
// {
// toolbarName: 'uploadVideo',
// tooltip: 'uploadVideo',
// text: 'uploadVideo',
// fn: (e, callback) => {
// this.handleAdd('uploadVideo', data => {
// if (callback && typeof callback === 'function') {
// callback(data)
// }
// })
// }
// },
{
toolbarName: 'spreview',
tooltip: 'spreview',
text: 'spreview',
fn: (e, callback) => {
this.toImage()
}
}
],
isUpload: false,
dataList: {
list: [
{
url: ''
}
],
type: 'image',
setDom: v => `<a>${v.dom}</a>`
},
height: 700,
menu: {
file: { title: '文件', items: 'newdocument' },
edit: {
title: '编辑',
items: 'undo redo | cut copy paste pastetext | selectall'
},
insert: { title: '插入', items: 'link media | image hr' },
view: { title: '查看', items: 'visualaid' },
format: {
title: '格式',
items:
'bold italic underline strikethrough superscript subscript | formats | removeformat'
},
table: {
title: '表格',
items: 'inserttable tableprops deletetable | cell row column'
},
tools: { title: '工具', items: 'spellchecker code' }
},
loadingInstance: null,
content: `<h1 style="text-align: center;">测试demo!</h1>
<p>嗨</p>
<img class="img" src="https://ali-image-test.dabanjia.com/image/20200508/1588911589606_5140%24ban.jpg" width="200"/>
<p>枕着幸福在梦中微笑,清零生活的压力烦恼,阳光透过窗与你拥抱,伸伸懒腰迎接周末来到,问候源于无法按捺的心跳,愿你周末乐逍遥,生活更美妙!
周末来到,让烦恼跑光,让忧愁找不到,跟寂寞说再见,跟压力说拜拜,跟快乐说你好,牵着幸福的手,携上平安,开开心心的过周末!
每个人,都有一个世界;每首歌,都有一个故事;每一周,都有一个周末;每个人,都要一个愿望;我的愿望很现实:周末清晨,搅黄你的美梦!周末快乐!
</p>
`
}
},
computed: {
fileType() {
// 自定义配置上传组件支持的文件,需要对上传组件进行封装,制定文件规格
if (this.dataList.type === 'image') {
return 'png|jpe?g|gif|svg'
}
if (this.dataList.type === 'video') {
// 暂时只支持mp4
return 'mp4'
// return "mp4|webm|ogg|mp3|wav|flac|aac";
}
return ''
}
},
mounted() {
// 实时获取高度并减去padding值
this.height = this.$refs.list.clientHeight - 32
},
methods: {
toImage() {
var width = 330 // 获取dom 宽度
var height = this.$refs.imageWrapper.scrollHeight // 获取dom 高度
var canvas = document.createElement('canvas') // 创建一个canvas节点
var scale = 2 // 定义任意放大倍数 支持小数默认设置为2确保图片清晰度
canvas.width = width * scale * scale // 定义canvas 宽度 * 缩放
canvas.height = height * scale * scale // 定义canvas高度 *缩放
canvas.getContext('2d').scale(scale, scale) // 获取context,设置scale
var opts = {
tainttest: true, // 检测每张图片都已经加载完成
scale: scale, // 添加的scale 参数
useCORS: true,
canvas: canvas, // 自定义 canvas
logging: true, // 日志开关
width: width, // dom 原始宽度
height: height // dom 原始高度
}
html2canvas(this.$refs.imageWrapper, opts).then(canvas => {
const dataurl = canvas.toDataURL('image/png')
this.dataurl = dataurl
if (this.dataurl !== '') {
console.log(this.dataurl, '生成base64')
}
})
},
error(e) {
console.log(e)
},
handleAdd(key, callback) {
this.dataList.list[0].url = ''
this.isUpload = false
switch (key) {
case 'uploadImg':
this.dataList.type = 'image'
document.getElementById('editorUploader').click()
break
case 'uploadVideo':
this.dataList.type = 'video'
document.getElementById('editorUploader').click()
break
// 批量操作,可自定义所有操作
case 'selectImg':
break
case 'selectVideo':
break
}
const unWatch = this.$watch('isUpload', val => {
if (val && callback && typeof callback === 'function') {
callback(this.dataList)
// 取消监听
unWatch()
}
})
},
uploadProgress() {
this.loadingInstance = Loading.service({
lock: true,
text: '数据加载中,请稍后...',
background: 'rgba(0, 0, 0, 0.1)'
})
},
// 定义模板
handleSuccess(data, file) {
this.loadingInstance.close()
this.dataList.list[0].url = file.url
const { type } = this.dataList
if (type === 'image') {
this.dataList.setDom = v =>
`<img class="img-scale" src="${v.url}" width="200">`
}
if (type === 'video') {
// 自定义配置模板信息,宽高后期都可变成输入
this.dataList.setDom = v =>
`<p >
<video controls="controls" width="200" height="350" >
<source src="https://dev-saas.oss-cn-beijing.aliyuncs.com/056eb234fa9844b0b7ec3e13bd39faf7.mp4" type="video/mp4" />
<source src="${v.url}" type="video/mp4" />
</video>
</p>
`
}
this.isUpload = true
}
}
}
</script>
<style scoped>
.show-html {
position: fixed;
right: 40px;
top: 80px;
width: 330px;
padding: 16px;
background: #fff;
border: 1px solid goldenrod;
}
</style>

View File

@@ -1,8 +1,16 @@
<template> <template>
<div :class="{fullscreen:fullscreen}" class="tinymce-container" :style="{width:containerWidth}"> <div
:class="{ fullscreen: fullscreen }"
class="tinymce-container"
:style="{ width: containerWidth }"
>
<textarea :id="tinymceId" class="tinymce-textarea" /> <textarea :id="tinymceId" class="tinymce-textarea" />
<div class="editor-custom-btn-container"> <div class="editor-custom-btn-container">
<editorImage color="#1890ff" class="editor-upload-btn" @successCBK="imageSuccessCBK" /> <editorImage
color="#1890ff"
class="editor-upload-btn"
@successCBK="imageSuccessCBK"
/>
</div> </div>
</div> </div>
</template> </template>
@@ -18,7 +26,8 @@ import toolbar from './toolbar'
import load from './dynamicLoadScript' import load from './dynamicLoadScript'
// why use this cdn, detail see https://github.com/PanJiaChen/tinymce-all-in-one // why use this cdn, detail see https://github.com/PanJiaChen/tinymce-all-in-one
const tinymceCDN = 'https://cdn.jsdelivr.net/npm/tinymce-all-in-one@4.9.3/tinymce.min.js' const tinymceCDN =
'https://cdn.jsdelivr.net/npm/tinymce-all-in-one@4.9.3/tinymce.min.js'
export default { export default {
name: 'Tinymce', name: 'Tinymce',
@@ -27,7 +36,11 @@ export default {
id: { id: {
type: String, type: String,
default: function() { default: function() {
return 'vue-tinymce-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '') return (
'vue-tinymce-' +
+new Date() +
((Math.random() * 1000).toFixed(0) + '')
)
} }
}, },
value: { value: {
@@ -45,6 +58,13 @@ export default {
type: String, type: String,
default: 'file edit insert view format table' default: 'file edit insert view format table'
}, },
newEventList: {
type: Array,
required: false,
default() {
return []
}
},
height: { height: {
type: [Number, String], type: [Number, String],
required: false, required: false,
@@ -63,17 +83,18 @@ export default {
tinymceId: this.id, tinymceId: this.id,
fullscreen: false, fullscreen: false,
languageTypeList: { languageTypeList: {
'en': 'en', en: 'en',
'zh': 'zh_CN', zh: 'zh_CN',
'es': 'es_MX', es: 'es_MX',
'ja': 'ja' ja: 'ja'
} }
} }
}, },
computed: { computed: {
containerWidth() { containerWidth() {
const width = this.width const width = this.width
if (/^[\d]+(\.[\d]+)?$/.test(width)) { // matches `100`, `'100'` if (/^[\d]+(\.[\d]+)?$/.test(width)) {
// matches `100`, `'100'`
return `${width}px` return `${width}px`
} }
return width return width
@@ -83,7 +104,8 @@ export default {
value(val) { value(val) {
if (!this.hasChange && this.hasInit) { if (!this.hasChange && this.hasInit) {
this.$nextTick(() => this.$nextTick(() =>
window.tinymce.get(this.tinymceId).setContent(val || '')) window.tinymce.get(this.tinymceId).setContent(val || '')
)
} }
} }
}, },
@@ -104,7 +126,7 @@ export default {
methods: { methods: {
init() { init() {
// dynamic load tinymce from cdn // dynamic load tinymce from cdn
load(tinymceCDN, (err) => { load(tinymceCDN, err => {
if (err) { if (err) {
this.$message.error(err.message) this.$message.error(err.message)
return return
@@ -114,13 +136,39 @@ export default {
}, },
initTinymce() { initTinymce() {
const _this = this const _this = this
// 自定义事件列表
let newToolbar = []
let barStr = ''
const eventData = []
this.newEventList.map(itemData => {
const { toolbarName, tooltip, text, fn } = itemData
eventData.push({
data: {
tooltip,
text,
onclick: e => {
fn(e, data => {
// 当事件成功后触发回调函数
_this.dataSuccessCBK(data)
})
}
},
name: toolbarName
})
barStr += toolbarName + ' '
})
if (this.toolbar.length > 0) {
newToolbar = this.toolbar.concat(barStr)
} else {
newToolbar = toolbar.concat(barStr)
}
window.tinymce.init({ window.tinymce.init({
selector: `#${this.tinymceId}`, selector: `#${this.tinymceId}`,
language: this.languageTypeList['en'], language: this.languageTypeList['en'],
height: this.height, height: this.height,
body_class: 'panel-body ', body_class: 'panel-body ',
object_resizing: false, object_resizing: false,
toolbar: this.toolbar.length > 0 ? this.toolbar : toolbar, toolbar: newToolbar,
menubar: this.menubar, menubar: this.menubar,
plugins: plugins, plugins: plugins,
end_container_on_empty_block: true, end_container_on_empty_block: true,
@@ -144,8 +192,9 @@ export default {
}) })
}, },
setup(editor) { setup(editor) {
editor.on('FullscreenStateChanged', (e) => { eventData.map(item => {
_this.fullscreen = e.state console.log('-----', item)
editor.addButton(item.name, item.data)
}) })
}, },
// it will try to keep these URLs intact // it will try to keep these URLs intact
@@ -206,35 +255,63 @@ export default {
imageSuccessCBK(arr) { imageSuccessCBK(arr) {
const _this = this const _this = this
arr.forEach(v => { arr.forEach(v => {
window.tinymce.get(_this.tinymceId).insertContent(`<img class="wscnph" src="${v.url}" >`) window.tinymce
.get(_this.tinymceId)
.insertContent(`<img class="wscnph" src="${v.url}" >`)
}) })
},
dataSuccessCBK(dataList) {
const { type, list, setDom } = dataList
let newDom = ''
console.log(dataList)
const self = this
if (type === 'image') {
list.forEach(v => {
newDom = setDom(v)
window.tinymce.get(self.tinymceId).insertContent(newDom)
})
} else if (type === 'video') {
list.forEach(v => {
newDom = setDom(v)
window.tinymce.get(self.tinymceId).insertContent(newDom)
})
}
} }
} }
} }
</script> </script>
<style scoped> <style lang="scss" scoped>
.tinymce-container { .tinymce-container {
position: relative; position: relative;
line-height: normal; line-height: normal;
} }
.tinymce-container>>>.mce-fullscreen {
z-index: 10000; .tinymce-container {
::v-deep {
.mce-fullscreen {
z-index: 10000;
}
}
} }
.tinymce-textarea { .tinymce-textarea {
visibility: hidden; visibility: hidden;
z-index: -1; z-index: -1;
} }
.editor-custom-btn-container { .editor-custom-btn-container {
position: absolute; position: absolute;
right: 4px; right: 4px;
top: 4px; top: 4px;
/*z-index: 2005;*/ /*z-index: 2005;*/
} }
.fullscreen .editor-custom-btn-container { .fullscreen .editor-custom-btn-container {
z-index: 10000; z-index: 10000;
position: fixed; position: fixed;
} }
.editor-upload-btn { .editor-upload-btn {
display: inline-block; display: inline-block;
} }

View File

@@ -82,7 +82,7 @@ export default {
position: relative; position: relative;
overflow: hidden; overflow: hidden;
width: 100%; width: 100%;
/deep/ { ::v-deep {
.el-scrollbar__bar { .el-scrollbar__bar {
bottom: 0px; bottom: 0px;
} }

View File

@@ -1,8 +1,12 @@
import axios from 'axios' import axios from 'axios'
import { MessageBox, Message } from 'element-ui' import {
Message,
MessageBox,
Loading
} from 'element-ui'
import store from '@/store' import store from '@/store'
import { getToken } from '@/utils/auth' import { getToken } from '@/utils/auth'
var loadingInstance = null
// create an axios instance // create an axios instance
const service = axios.create({ const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
@@ -21,6 +25,12 @@ service.interceptors.request.use(
// please modify it according to the actual situation // please modify it according to the actual situation
config.headers['X-Token'] = getToken() config.headers['X-Token'] = getToken()
} }
console.log('------')
loadingInstance = Loading.service({
lock: true,
text: '数据加载中,请稍后...',
background: 'rgba(0, 0, 0, 0.1)'
})
return config return config
}, },
error => { error => {
@@ -43,6 +53,7 @@ service.interceptors.response.use(
* You can also judge the status by HTTP Status Code * You can also judge the status by HTTP Status Code
*/ */
response => { response => {
loadingInstance.close()
const res = response.data const res = response.data
// if the custom code is not 20000, it is judged as an error. // if the custom code is not 20000, it is judged as an error.
@@ -72,6 +83,7 @@ service.interceptors.response.use(
} }
}, },
error => { error => {
loadingInstance.close()
console.log('err' + error) // for debug console.log('err' + error) // for debug
Message({ Message({
message: error.message, message: error.message,

View File

@@ -2,34 +2,44 @@
<div class="components-container"> <div class="components-container">
<aside> <aside>
Rich text is a core feature of the management backend, but at the same time it is a place with lots of pits. In the process of selecting rich texts, I also took a lot of detours. The common rich texts on the market have been basically used, and I finally chose Tinymce. See the more detailed rich text comparison and introduction. Rich text is a core feature of the management backend, but at the same time it is a place with lots of pits. In the process of selecting rich texts, I also took a lot of detours. The common rich texts on the market have been basically used, and I finally chose Tinymce. See the more detailed rich text comparison and introduction.
<a target="_blank" class="link-type" href="https://panjiachen.github.io/vue-element-admin-site/component/rich-editor.html">Documentation</a> <a
target="_blank"
class="link-type"
href="https://panjiachen.github.io/vue-element-admin-site/component/rich-editor.html"
>Documentation</a>
</aside> </aside>
<div> <div>
<tinymce v-model="content" :height="300" /> <tinymce
v-model="content"
:height="300"
/>
</div> </div>
<div class="editor-content" v-html="content" />
</div> </div>
</template> </template>
<script> <script>
import Tinymce from '@/components/Tinymce' import Tinymce from '@/components/Tinymce/example'
export default { export default {
name: 'TinymceDemo', name: 'TinymceDemo',
components: { Tinymce }, components: { Tinymce },
data() { data() {
return { return {
content: content: `<h1 style="text-align: center;">测试demo!</h1>
`<h1 style="text-align: center;">Welcome to the TinyMCE demo!</h1><p style="text-align: center; font-size: 15px;"><img title="TinyMCE Logo" src="//www.tinymce.com/images/glyph-tinymce@2x.png" alt="TinyMCE Logo" width="110" height="97" /><ul> <p>嗨</p>
<li>Our <a href="//www.tinymce.com/docs/">documentation</a> is a great resource for learning how to configure TinyMCE.</li><li>Have a specific question? Visit the <a href="https://community.tinymce.com/forum/">Community Forum</a>.</li><li>We also offer enterprise grade support as part of <a href="https://tinymce.com/pricing">TinyMCE premium subscriptions</a>.</li> <img class="img" src="https://ali-image-test.dabanjia.com/image/20200508/1588911589606_5140%24ban.jpg" width="200"/>
</ul>` <p>枕着幸福在梦中微笑,清零生活的压力烦恼,阳光透过窗与你拥抱,伸伸懒腰迎接周末来到,问候源于无法按捺的心跳,愿你周末乐逍遥,生活更美妙!
周末来到,让烦恼跑光,让忧愁找不到,跟寂寞说再见,跟压力说拜拜,跟快乐说你好,牵着幸福的手,携上平安,开开心心的过周末!
每个人,都有一个世界;每首歌,都有一个故事;每一周,都有一个周末;每个人,都要一个愿望;我的愿望很现实:周末清晨,搅黄你的美梦!周末快乐!
</p>
`
} }
} }
} }
</script> </script>
<style scoped> <style scoped>
.editor-content{ .editor-content {
margin-top: 20px; margin-top: 20px;
} }
</style> </style>

View File

@@ -101,7 +101,7 @@ export default {
background-color: #fff; background-color: #fff;
margin: auto; margin: auto;
box-shadow: none!important; box-shadow: none!important;
/deep/ .pan-info { ::v-deep .pan-info {
box-shadow: none!important; box-shadow: none!important;
} }
} }

View File

@@ -277,7 +277,7 @@ export default {
} }
} }
.article-textarea /deep/ { .article-textarea ::v-deep {
textarea { textarea {
padding-right: 40px; padding-right: 40px;
resize: none; resize: none;

View File

@@ -91,7 +91,7 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.app-container { .app-container {
/deep/ .permission-alert { ::v-deep .permission-alert {
width: 320px; width: 320px;
margin-top: 15px; margin-top: 15px;
background-color: #f0f9eb; background-color: #f0f9eb;
@@ -100,10 +100,10 @@ export default {
border-radius: 4px; border-radius: 4px;
display: inline-block; display: inline-block;
} }
/deep/ .permission-sourceCode { ::v-deep .permission-sourceCode {
margin-left: 15px; margin-left: 15px;
} }
/deep/ .permission-tag { ::v-deep .permission-tag {
background-color: #ecf5ff; background-color: #ecf5ff;
} }
} }