editor修改样式 vue_手摸手Electron + Vue实战教程(三)
系列文章:
- 手摸手Electron + Vue實戰教程(一)
- 手摸手Electron + Vue實戰教程(二)
上一篇我們已經完成了左側菜單欄的基本樣式功能,這一篇我們就主要來開發右側的Markdown編輯區域,即文件編輯組件FileEdit
?需求分析
有道云筆記截圖我們從截圖里可以看到,右側區域主要是由標題欄和內容編輯區組成,其中標題欄的右側還包含了一排操作按鈕,在這里我們就先把這一排按鈕忽略了,先把主要功能開發完畢再考慮迭代優化。
所以我們的最終需要實現的需求其實很簡單,就是「標題欄 + Markdown編輯區 = 右側區域」,標題欄支持修改輸入,Markdown區支持編輯操作和預覽模式,同時也支持單欄和雙欄切換,當然還有必不可少的全屏操作。
FileEdit組件開發
我們先在組件目錄components下新建組件FileEdit,組件分為上下兩部分:
<template>
??<div?class="content-edit">
????//?標題區域
????//?編輯區
??div>
template>
<script>export?default?{name:?'FileEdit'
}script>
<style?lang="less"?scoped>style>
組件的頂部直接使用element組件el-input,我們需要稍微修改一點樣式:
<el-input?class="file-title"?v-model="currentTitle"?placeholder="請輸入標題"?/>.file-title {
padding-left: 5px;
height: 56px;
line-height: 56px;
font-size: 18px;
font-weight: 500;
/deep/ .el-input__inner {
height: inherit;
line-height: inherit;
font-weight: inherit;
border: none;
}
}
mavon-editor
Markdown的編輯區,我們可以直接選用第三方的插件包mavon-edito,3.9k star也算是比較火的一個開源Markdown編輯器了,詳細說明大家可以看一下官方文檔:https://github.com/hinesboy/mavonEditor
這里先來安裝引入一下mavon-editor,我習慣使用yarn,大家可以根據自己喜好使用npm也木有任何問題:
yarn?add?mavon-editor安裝完后在插件目錄plugin里新建文件mavonEditor.js引入依賴包:
/*?*?@Description:?markdown?編輯器插件
?*?@Author:?sufen
?*?@Date:?2020-05-30?16:31:31
?*?@LastEditTime:?2020-06-02?11:01:31
?*?@LastEditors:?sufen
?*/
import?Vue?from?'vue'
import?mavonEditor?from?'mavon-editor'
import?'mavon-editor/dist/css/index.css'
Vue.use(mavonEditor)
在main.js中引入我們剛編寫好的mavonEditor.js就算完成全部引入了:
import?Vue?from?'vue'import?App?from?'./App.vue'
import?router?from?'./router'
import?store?from?'./store'
import?'@/plugin/element-ui'
import?'@/plugin/fortawesome'
import?'@/plugin/mavonEditor'
Vue.config.productionTip?=?false
new?Vue({
??router,
??store,
??render:?h?=>?h(App)
}).$mount('#app')
Attrs 和 Listeners
現在我們可以在組件里引入編輯器了:
<mavon-editor?v-bind="$attrs"?v-on="$listeners"?class="markdown-wrapper"?/>.markdown-wrapper {
height: calc(100vh - 56px);
&.fullscreen {
height: 100vh;
}
}
不知道大家之前有沒有使用過$attrs和$listeners,它絕對是二次封裝組件、寫高階組件的神器。
這兩個屬性是vue 2.4版本之后提供的,在我們平時寫業務的時候免不了需要對一些第三方組件進行二次封裝。比如我們現在就需要基于mavon-editor封裝一個帶有業務特性的組件,添加了el-input輸入框,將一些業務邏輯封裝在其中。
在mavon-editor的文檔中我們可以看到組件支持二三十個配置參數,我們可以適當的挑選幾個參數通過props來傳遞,但如果哪天別人用你的業務組件的時候覺得你的參數少了,那就只能改你封裝的組件了,亦或是哪天第三方組件加入了新參數,這個時候你又該怎么辦?
其實FileEdit組件就是基于mavon-editor做了一些簡單的業務封裝,加入了一個標題輸入框,它只是一個充當中間人的組件,負責傳遞數據而已,那么這個時候我們可以使用v-bind="$attrs":傳遞所有屬性、v-on="$listeners"傳遞所有方法:
最后在Home.vue中使用我們的FileEdit組件:
.sync
這個也是vue 2.3.0+之后新加的一個語法糖,平時在封裝組件的時候很好用的一個語法糖,它的實現機制和v-model是一樣的。我們可以先看下官方文檔:https://cn.vuejs.org/v2/guide/components-custom-events.html#sync-%E4%BF%AE%E9%A5%B0%E7%AC%A6
“在有些情況下,我們可能需要對一個prop進行“雙向綁定”。不幸的是,真正的雙向綁定會帶來維護上的問題,因為子組件可以變更父組件,且在父組件和子組件都沒有明顯的變更來源。”
示例代碼:
會被擴展為:
<file-edit?:title="title"?@update:title="val?=>?title?=?val"/>當子組件需要更新 title 的值時,它需要顯式地觸發一個更新事件:
this.$emit('update:title',?newValue)單向數據流
所有的 prop 都使得其父子 prop 之間形成了一個單向下行綁定:父級 prop 的更新會向下流動到子組件中,但是反過來則不行。這樣會防止從子組件意外變更父級組件的狀態,從而導致你的應用的數據流向難以理解。
額外的,每次父級組件發生變更時,子組件中所有的 prop 都將會刷新為最新的值。這意味著你不應該在一個子組件內部改變 prop。如果你這樣做了,Vue 會在瀏覽器的控制臺中發出警告。
以上為 vue 官方的對于單向數據流的解釋,大家可以在官網詳細看看:https://cn.vuejs.org/v2/guide/components-props.html
因為單向數據流的原因,我們組件內的標題欄組件el-input不能直接v-model綁定 props 傳遞過來的title值,我們需要在 data 中定義一個currentTitle,用以綁定v-model="currentTitle"。
聯系上文的.sync,我們還需要監聽currentTitle的值,實時更新 props 傳遞過來的值title:
至此,我們的FileEdit組件就暫時告一段落了,這篇基本都是一些 vue 組件封裝的小技巧,希望能夠對大家有些許幫助,下面貼出我們組件的完整代碼和 Home.vue 頁面調用組件代碼:
<template>
??<div?class="content-edit">
????<el-input?class="file-title"?v-model="currentTitle"?placeholder="請輸入標題"?/>
????<mavon-editor?v-bind="$attrs"?v-on="$listeners"?class="markdown-wrapper"?/>
??div>
template>
<script>export?default?{name:?'FileEdit',props:?{title:?String
??},
??data()?{return?{currentTitle:?this.title
????}
??},watch:?{
????currentTitle(newValue)?{this.$emit('update:title',?newValue)
????}
??}
}script>
<style?lang="less"?scoped>
.content-edit?{
??.file-title?{
????padding-left:?5px;
????height:?56px;
????line-height:?56px;
????font-size:?18px;
????font-weight:?500;
????/deep/?.el-input__inner?{
??????height:?inherit;
??????line-height:?inherit;
??????font-weight:?inherit;
??????border:?none;
????}
??}
??.markdown-wrapper?{
????height:?calc(100vh?-?56px);
????&.fullscreen?{
??????height:?100vh;
????}
??}
}
style>
<template>
??<div?class="app-wrapper">
????<div?class="sidebar-container">
??????<file-search?v-model="searchTitle"?/>
??????<file-list?:fileList="fileList"?/>
????div>
????<div?class="main-container">
??????<file-editv-model="fileItem.content":title.sync="fileItem.title":boxShadow="false":subfield="false":shortCut="false"
????????@change="onSubmit"
??????/>
????div>
??div>
template>
<script>import?FileSearch?from?'@/components/FileSearch'import?FileList?from?'@/components/FileList'import?FileEdit?from?'@/components/FileEdit'export?default?{name:?'Home',components:?{?FileSearch,?FileList,?FileEdit?},
??data()?{return?{searchTitle:?'',fileList:?[
????????{?id:?1,?title:?'文件名?1',?time:?'2020-06-21'?},
????????{?id:?2,?title:?'文件名?2',?time:?'2020-06-21'?},
????????{?id:?3,?title:?'文件名?3',?time:?'2020-06-21'?},
????????{?id:?4,?title:?'文件名?4',?time:?'2020-06-21'?},
????????{?id:?5,?title:?'文件名?5',?time:?'2020-06-21'?},
????????{?id:?6,?title:?'文件名?6',?time:?'2020-06-21'?},
????????{?id:?1,?title:?'文件名?1',?time:?'2020-06-21'?},
????????{?id:?2,?title:?'文件名?2',?time:?'2020-06-21'?},
????????{?id:?3,?title:?'文件名?3',?time:?'2020-06-21'?},
????????{?id:?4,?title:?'文件名?4',?time:?'2020-06-21'?},
????????{?id:?5,?title:?'文件名?5',?time:?'2020-06-21'?},
????????{?id:?6,?title:?'文件名?6',?time:?'2020-06-21'?}
??????],fileItem:?{title:?'手摸手Electron?+?Vue實戰教程(三)',content:?''
??????}
????}
??},methods:?{
????onSubmit(value)?{console.log(value)console.log(this.fileItem)
????}
??}
}script>
<style?lang="less"?scoped>
.app-wrapper?{
??display:?flex;
??.sidebar-container?{
????width:?300px;
????height:?100vh;
????border-right:?1px?solid?#eaeefb;
??}
??.main-container?{
????flex:?1;
????overflow:?hidden;
??}
}
style>
總結
以上是生活随笔為你收集整理的editor修改样式 vue_手摸手Electron + Vue实战教程(三)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 叶片制成切片的结构示意图_吉林大学《JP
- 下一篇: 80070583类不存在_原创 | 类应