91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

vue中wangEditor5編輯器如何使用

發布時間:2023-03-30 17:51:10 來源:億速云 閱讀:202 作者:iii 欄目:開發技術

這篇文章主要介紹了vue中wangEditor5編輯器如何使用的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇vue中wangEditor5編輯器如何使用文章都會有所收獲,下面我們一起來看看吧。

    一、wangEditor5是什么

    wangEditor是一款富文本編譯器插件,其他的我就不再過多贅述,因為官網上有一大截對于這個編譯器的介紹,但我摸索使用的這兩天里給我的最直觀的感受就是,它是由中國開發者開發,所有的文檔都是中文的,這一點上對我這個菜雞來說非常友好,不用再去逐字逐句翻譯,然后去讀那些蹩腳的機翻中文。而且功能很豐富,能夠滿足很多需求,wangEditor5提供很多版本的代碼,vue2,vue3,react都支持。

    二、wangEditor5基本使用

    (一)、安裝

    yarn add @wangeditor/editor-for-vue
    # 或者 npm install @wangeditor/editor-for-vue --save

    (二)、編譯器引入

    import { Editor, Toolbar } from '@wangeditor/editor-for-vue';

    Editor:引入@wangEditor編譯器 

    Toolbar:引入菜單欄

    (三)、css及變量引入

    <style src="@wangeditor/editor/dist/css/style.css" >
     
    </style>

    這里需要注意,引入的樣式寫在帶有scoped標簽的style內無效。只能引入在全局樣式里,但可能會造成樣式覆蓋,一般會有個清除樣式的文件,會把里面的樣式覆蓋掉。

    三、wangEditor5工具欄配置

    工具欄配置有很多選項,這里以官方為主,我只做一些常用的配置介紹。

    (一)、editor.getAllMenuKeys() 

    查詢編輯器注冊的所有菜單 key (可能有的不在工具欄上)這里注意要在

        onCreated(editor) {
                this.editor = Object.seal(editor) 
            },

    這個函數中去調用 (這個函數是基本配置之一),不然好像調不出來,當然也有可能是博主太菜。

    (二)、toolbarConfig中的excludeKeys

    toolbarConfig: {
            excludeKeys:["uploadVideo","fullScreen","emotion","insertTable"]
           },

    這個是菜單欄配置的一種:排除某項配置 ,這里填寫的key值就是用上面那個方法,查出來的key值。

    四、wangEditor5上傳圖片

    首先在data中return以下信息。

    editorConfig: { 
            placeholder: '請輸入內容...' ,
            MENU_CONF: {
    					uploadImage: {
    						customUpload: this.uploadImg,
    					},
    				}
          },

    然后書寫this.uploadImg函數。

     uploadImg(file, insertFn){
          let imgData = new FormData();
    			imgData.append('file', file);
          axios({
            url: this.uploadConfig.api,
            method: 'post',
            data: imgData,
          }).then((response) => {
           insertFn(response.data.FileURL);
          });
        },

    注意,這里因為返回的數據結構與@wangeditor要求的不一致,因此要使用 insertFn 函數 去包裹返回的url地址。

    五、wangEditor5的一些問題收集及解決

    (一)、引入@wangEditor 編譯報錯 " Module parse failed: Unexpected token (12828:18)You may need an appropriate loader to handle this file type."

    vue中wangEditor5編輯器如何使用

    解決方法:在 wwebpack.base.conf.js 文件的module>rules>.js 的include下加入

    resolve('node_modules/@wangeditor')

     就可以了。

    vue中wangEditor5編輯器如何使用

    (二)、@wangeditor有序列表無序列表的樣式消失問題。

    大概率是全局樣式清除導致的樣式消失,可以去調試工具里看一看,樣式覆蓋的問題。

    然后在style里deep一下改變樣式就行了。

    .editorStyle{
      /deep/ .w-e-text-container>.w-e-scroll>div ol li{
        list-style: auto ;
      }
      /deep/ .w-e-text-container>.w-e-scroll>div ul li{
        list-style: disc ;
      }
      /deep/ .w-e-text-placeholder{
        top:7px;
      }
      
    }

    六、完整代碼

    <template>
      <div v-loading="Loading" class="app_detail">
        <el-form ref="form" :rules="rules" :model="appDetail" label-width="80px">
          <el-form-item prop="name" label="應用名稱">
            <el-input v-model="appDetail.name" ></el-input>
          </el-form-item>
          <el-form-item label="分類">
            <el-select
              v-model="appDetail.appClassificationID"
              
              placeholder="選擇應用分類"
            >
              <template v-for="item in classes">
                <el-option
                  v-if="item.parentAppClassificationID"
                  :key="item.appClassificationID"
                  :label="item.appClassificationName"
                  :value="item.appClassificationID"
                ></el-option>
              </template>
            </el-select>
            <div class="inputdesc">為了適應前臺展示,應用只能屬于二級分類</div>
          </el-form-item>
          <el-form-item label="所屬組織">
            <el-select
              v-model="appDetail.orgID"
              placeholder="請選擇所屬組織"
              
            >
              <el-option
                v-for="item in myorgs"
                :key="item.orgID"
                :label="item.name"
                :value="item.orgID"
              ></el-option>
            </el-select>
          </el-form-item>
          <el-form-item prop="tags" label="標簽">
            <el-select
              v-model="appDetail.tags"
              multiple
              filterable
              
              placeholder="請輸入或選擇應用標簽"
            >
              <el-option
                v-for="item in existTags"
                :key="item"
                :label="item"
                :value="item"
              ></el-option>
            </el-select>
          </el-form-item>
          <el-row>
            <el-col :span="8" class="appsFrom">
              <el-form-item
                label="應用Logo"
                ref="uploadpic"
                class="el-form-item-cen"
                prop="logo"
              >
                <el-upload
                  class="avatar-uploader"
                  :action="uploadConfig.api"
                  :with-credentials="true"
                  :headers="uploadConfig.headers"
                  :show-file-list="false"
                  :on-success="handleAvatarSuccess"
                  :on-error="handleAvatarError"
                  :before-upload="beforeAvatarUpload"
                >
                  <img v-if="appDetail.logo" :src="appDetail.logo" class="avatar" />
                  <i v-else class="el-icon-plus avatar-uploader-icon"></i>
                  <i
                    v-if="appDetail.logo"
                    class="el-icon-delete"
                    @click.stop="() => handleRemove()"
                  ></i>
                </el-upload>
                <span >
                  建議上傳 100*100 比例的Logo
                </span>
              </el-form-item>
            </el-col>
          </el-row>
          <el-form-item prop="desc" label="應用簡介">
            <el-input
              type="textarea"
              v-model="appDetail.desc"
              :rows="3"
              
            ></el-input>
          </el-form-item>
          <el-form-item prop="introduction" label="應用詳情">
            <div >
            <Toolbar
                
                :editor="editor"
                :defaultConfig="toolbarConfig"
                :mode="mode"
                class="barStyle"
            />
            <Editor
                
                v-model="appDetail.introduction"
                :defaultConfig="editorConfig"
                :mode="mode"
                @onCreated="onCreated"
                class="editorStyle"
            />
        </div>
          </el-form-item>
        </el-form>
        <el-button
          class="save_btn"
          type="primary"
          @click="onSubmit"
          :loading="commitLoading"
          >保存</el-button
        >
      </div>
    </template>
     
    <script>
    import { updateApp } from '@/api/app';
    import { getStoreAvailableTags } from '@/api/appStore';
    import { getToken } from '@/utils/auth';
    import axios from 'axios';
    import { errorHandle } from '../../../../utils/error';
    import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
    import { IToolbarConfig, DomEditor, IEditorConfig } from '@wangeditor/editor'
    export default {
      name: 'BasicInfo',
      components: { Editor, Toolbar },
      props: {
        appDetail: {
          type: Object
        },
        marketID: {
          type: String
        },
        Loading: Boolean
      },
      data() {
        var baseDomain = process.env.BASE_API;
        if (baseDomain == '/') {
          baseDomain = window.location.origin;
        }
        const isChinese = (temp) => {
          return /^[\u4e00-\u9fa5]+$/i.test(temp);
        };
        const tagValidate = (rule, value, callback) => {
          let checked = true;
          value.map((tag) => {
            if (tag.length < 2) {
              callback('每個標簽至少兩個字符');
              checked = false;
              return;
            }
            if (isChinese(tag) && tag.length > 5) {
              callback('中文標簽字數應處于2-5個之間');
              checked = false;
              return;
            }
            if (Number(tag) > 0) {
              callback('標簽不能為純數字組成');
              checked = false;
              return;
            }
          });
          if (checked) {
            callback();
          }
        };
        return {
          editor: null,
          toolbarConfig: {
            excludeKeys:["uploadVideo","fullScreen","emotion","insertTable"]
           },
          editorConfig: { 
            placeholder: '請輸入內容...' ,
            MENU_CONF: {
    					uploadImage: {
    						customUpload: this.uploadImg,
    					},
    				}
          },
          mode: 'default', // or 'simple'
          commitLoading: false,
          classes: [],
          existTags: [],
          appPublishTypes: [
            {
              value: 'public',
              label: '免費公開'
            },
            {
              value: 'integral',
              label: '金額銷售'
            },
            {
              value: 'private',
              label: '私有'
            },
            {
              value: 'show',
              label: '展覽'
            }
          ],
          uploadConfig: {
            api: `${baseDomain}/app-server/uploads/picture`,
            headers: {
              Authorization: getToken()
            },
          },
          editorOption: {},
          rules: {
            name: [
              { required: true, message: '應用名稱不能為空', trigger: 'blur' },
              { min: 2, message: '至少兩個字符', trigger: 'blur' },
              { max: 24, message: '應用名稱建議不超過24個字符', trigger: 'blur' }
            ],
            desc: [
              { required: true, message: '應用簡介不能為空', trigger: 'blur' },
              { min: 10, message: '至少10個字符', trigger: 'blur' },
              { max: 82, message: '描述最多82個字符', trigger: 'blur' }
            ],
            introduction: [
              { max: 10140, message: '描述最多10240個字符', trigger: 'blur' }
            ],
            tags: [{ validator: tagValidate, trigger: 'change' }]
          }
        };
      },
      created() {
        this.fetchStoreAppClassList();
        this.fetchStoreAppTags();
      },
      computed: {
        myorgs() {
          return this.$store.state.user.userOrgs;
        }
      },
      
      methods: {
        uploadImg(file, insertFn){
          let imgData = new FormData();
    			imgData.append('file', file);
          axios({
            url: this.uploadConfig.api,
            method: 'post',
            data: imgData,
          }).then((response) => {
           insertFn(response.data.FileURL);
          });
        },
        onCreated(editor) {
                this.editor = Object.seal(editor) 
            },
        fetchStoreAppTags() {
          getStoreAvailableTags({
            marketID: this.marketID,
            size: -1
          })
            .then((res) => {
              if (res && res.tags) {
                const tags = [];
                res.tags.map((item) => {
                  tags.push(item.name);
                });
                this.existTags = tags;
              }
            })
            .catch((err) => {
              this.Loading = false;
            });
        },
        fetchStoreAppClassList() {
          this.$store
            .dispatch('GetStoreAppClassificationList', {
              marketID: this.marketID,
              disableTree: true
            })
            .then((res) => {
              if (res) {
                this.classes = res;
              }
            })
            .catch(() => {});
        },
        fetchUserOrgs() {
          this.$store
            .dispatch('GetUserOrgList')
            .then((res) => {
              if (res) {
                this.myorgs = res;
              }
            })
            .catch(() => {});
        },
        markdownContentUpdate(md, render) {
          this.appData.introduction_html = render;
        },
        markdownImgAdd(pos, $file) {
          // 第一步.將圖片上傳到服務器.
          var formdata = new FormData();
          formdata.append('file', $file);
          axios({
            url: this.api,
            method: 'post',
            data: formdata,
            headers: this.Token
          }).then((re) => {
            if (re && re.data && re.data.data) {
              this.$refs.md.$img2Url(pos, re.data.data);
            }
          });
        },
        handleAvatarSuccess(res, file) {
          this.appDetail.logo = res.FileURL;
        },
        handleAvatarError(re) {
          if (re.code == 10024) {
            this.$message.warning(
              '上傳圖片類型不支持,請上傳以.png .jpg .jpeg 結尾的圖片'
            );
            return;
          }
          this.$message.warning('上傳失敗!');
        },
        beforeAvatarUpload(file) {
          const isJPG = file.type === 'image/jpeg';
          const isPng = file.type === 'image/png';
          const isLt2M = file.size / 1024 / 1024 < 2;
     
          if (!isJPG && !isPng) {
            this.$message.warning('上傳Logo圖片只能是JPG、PNG格式!');
          }
          if (!isLt2M) {
            this.$message.warning('上傳頭像圖片大小不能超過 2MB!');
          }
          return (isJPG || isPng) && isLt2M;
        },
        handleRemove() {
          this.$confirm('是否刪除logo', '提示', {
            confirmButtonText: '確定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            this.appDetail.logo = '';
          });
        },
        handlePictureCardPreview(file) {
          this.dialogImageUrl = file.url;
          this.dialogVisible = true;
        },
        changeSelectApp_type_id(value) {
          this.appData.app_type_id = value;
          this.$forceUpdate();
        },
        changeSelectPublish_type(value) {
          this.appData.publish_type = value;
          this.$forceUpdate();
        },
        onSubmit() {
          this.$refs.form.validate((valid) => {
            if (valid) {
              this.commitLoading = true;
              this.$confirm('是否提交數據', '提示', {
                confirmButtonText: '確定',
                cancelButtonText: '取消',
                type: 'warning'
              })
                .then(() => {
                  updateApp(this.appDetail)
                    .then((res) => {
                      this.$message.success('應用信息更新成功');
                      this.commitLoading = false;
                    })
                    .catch((err) => {
                      errorHandle(err);
                      this.commitLoading = false;
                    });
                })
                .catch(() => {
                  this.commitLoading = false;
                });
            } else {
              return false;
            }
          });
        }
      }
    };
    </script>
    <style lang="scss" scoped >
    .app_detail {
      position: relative;
      padding-bottom: 20px;
      .save_btn {
        margin-left: 80px;
        
      }
      .el-select {
        width: 100%;
      }
    }
    .editorStyle{
      /deep/ .w-e-text-container>.w-e-scroll>div ol li{
        list-style: auto ;
      }
      /deep/ .w-e-text-container>.w-e-scroll>div ul li{
        list-style: disc ;
      }
      /deep/ .w-e-text-placeholder{
        top:7px;
      }
      
    }
    .barStyle{
      /deep/ .w-e-bar-item{
        padding:2.5px
      }
        /deep/ .w-e-bar-item > button >.title{
        border-left:0 !important;
      }
    }
    </style>
    <style src="@wangeditor/editor/dist/css/style.css" >
    .inputdesc {
      font-size: 12px;
      color: rgba(0, 0, 0, 0.45);
      transition: color 0.3s cubic-bezier(0.215, 0.61, 0.355, 1);
    }
    .app_detail img {
      width: auto;
    }
    .app_detail .ql-formats {
      line-height: 22px;
    }
    </style>

    關于“vue中wangEditor5編輯器如何使用”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“vue中wangEditor5編輯器如何使用”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    vue
    AI

    金湖县| 黔西| 特克斯县| 梓潼县| 和平区| 抚松县| 海门市| 大竹县| 九寨沟县| 蓬安县| 镇康县| 雅江县| 淅川县| 双江| 武城县| 海淀区| 柘荣县| 武功县| 昌图县| 安义县| 广宁县| 万盛区| 昭通市| 井陉县| 保德县| 辛集市| 乌鲁木齐市| 花莲市| 澳门| 商丘市| 安化县| 桐庐县| 博客| 哈巴河县| 陆河县| 凉城县| 久治县| 郴州市| 唐海县| 高邮市| 芦山县|