npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@panhezeng/el-tinymce

v2.2.16

Published

A Vue Element UI Component

Downloads

14

Readme

el-tinymce

示例

点击预览

示例代码目录 /example

说明

基于 tinymce 富文本编辑器和 element-ui 组件库开发,tinymce 使用的是@panhezeng/vue-tinymce 模块,风格模仿微信公众号后台的富文本编辑器,增加了资源侧边栏。

如有定制需要,可以 fork 自行修改,建议阅读 tinymce 和 element-ui 等相关文档

首先请按 element-ui 官方文档安装 element-ui,确保能正常使用 element-ui

index.vue

<script>
export default {
  // 侧边栏属性通过$attrs传入,side 是否显示侧边栏,image,audio,video是否显示对应项目 i18n 国际化
  props: {
    // 父组件通过:content.sync同步富文本编辑器内容
    content: {
      type: String,
      required: true,
    },
    // 触发content同步更新的tinymce Editor Events,其他https://www.tiny.cloud/docs/advanced/events/
    updateEvent: {
      type: String,
      default: "beforeaddundo undo redo keyup",
    },
    // tinymce依赖文件的cdn url
    url: {
      type: String,
      default: "https://cdn.jsdelivr.net/npm/tinymce@%5E5.10.3",
    },
    // tinymce的init方法的config参数,本组件有默认设置,比如不要toolbar3,可以使用该组件时写上 :config="{toolbar2:''}"
    config: {
      type: Object,
      default() {
        return {};
      },
    },
    // 编辑器高度
    height: {
      type: Number,
      default: 500,
    },
    // 只读
    readonly: {
      type: Boolean,
      default: false,
    },
    // 上传文件的方法
    upload: {
      required: true,
      type: Function,
    },
  },
};
</script>

Side.vue

<script>
export default {
  props: {
    // 整个侧边栏是否显示
    side: {
      type: Boolean,
      default: true,
    },
    // 侧边栏图片项是否显示
    image: {
      type: Boolean,
      default: true,
    },
    // 侧边栏音频项是否显示
    audio: {
      type: Boolean,
      default: true,
    },
    // 侧边栏视频项是否显示
    video: {
      type: Boolean,
      default: true,
    },
    // tinymce实例
    editor: {
      type: null,
      required: true,
    },
    // 侧边栏所有文本
    i18n: {
      type: Object,
      default() {
        return {
          resource: "资源",
          btn: {
            reset: "重置",
            submit: "提交",
          },
          width: "宽",
          height: "高",
          align: {
            title: "排版方式",
            default: "默认",
            top: "文字上对齐",
            middle: "文字中对齐",
            bottom: "文字下对齐",
            left: "文字环绕在右侧",
            right: "文字环绕在左侧",
          },
        };
      },
    },
    // 侧边栏列表,dialog是该侧边按钮的弹出框数据
    list: {
      type: Array,
      default() {
        return [
          {
            type: "image",
            title: "图片",
            dialog: {
              activeName: "image0",
              tabs: [
                {
                  title: "本地图片",
                  desc: "支持png、jpg、gif、svg、webp,大小不能超过10M",
                  uploadProps: {
                    accept: "image/*",
                    size: 10240,
                    placeholder: "图片链接地址",
                  },
                  formName: "image0",
                  formData: {
                    content: "",
                    width: "",
                    height: "",
                    align: "",
                    alignStyle: "",
                  },
                  formRules: {
                    content: [
                      {
                        required: true,
                        message: "请上传图片",
                        trigger: "blur",
                      },
                    ],
                  },
                },
                {
                  title: "外链图片",
                  desc: "支持png、jpg、gif、svg、webp",
                  formName: "image1",
                  formData: {
                    content: "",
                    width: "",
                    height: "",
                    align: "",
                    alignStyle: "",
                  },
                  formRules: {
                    content: [
                      {
                        required: true,
                        message: "请输入有效图片链接",
                        trigger: "blur",
                        pattern: /\.(png|jpe?g|gif|svg|webp)$/,
                      },
                    ],
                  },
                },
              ],
              template(data) {
                return `<p class="el-tinymce-resource el-tinymce-image"><img src="${data.content}" width="${data.width}" height="${data.height}" style="${data.alignStyle}"></p>`;
              },
            },
          },
          {
            type: "audio",
            title: "音频",
            dialog: {
              activeName: "audio0",
              tabs: [
                {
                  title: "本地音频",
                  desc: "支持mp3、ogg、wav、flac、aac,大小不能超过100M",
                  uploadProps: {
                    accept: ".mp3,.ogg,.wav,.flac,.aac",
                    size: 102400,
                    placeholder: "音频链接地址",
                  },
                  formName: "audio0",
                  formData: {
                    content: "",
                    align: "",
                    alignStyle: "",
                  },
                  formRules: {
                    content: [
                      {
                        required: true,
                        message: "请上传音频",
                        trigger: "blur",
                      },
                    ],
                  },
                },
                {
                  title: "外链音频",
                  desc: "支持mp3、ogg、wav、flac、aac",
                  formName: "audio1",
                  formData: {
                    content: "",
                    align: "",
                    alignStyle: "",
                  },
                  formRules: {
                    content: [
                      {
                        required: true,
                        message: "请输入有效音频链接",
                        trigger: "blur",
                        pattern: /\.(mp3|ogg|wav|flac|aac)$/,
                      },
                    ],
                  },
                },
              ],
              template(data) {
                return `<p class="el-tinymce-resource el-tinymce-audio"><audio src="${data.content}" controls style="${data.alignStyle}"></audio></p>`;
              },
            },
          },
          {
            type: "video",
            title: "视频",
            dialog: {
              activeName: "video0",
              poster: {
                desc: "支持png、jpg、gif、svg、webp,大小不能超过10M",
                uploadProps: {
                  accept: "image/*",
                  size: 10240,
                  placeholder: "视频封面图片链接地址",
                },
              },
              tabs: [
                {
                  title: "本地视频",
                  desc: "支持mp4、webm,大小不能超过1G",
                  uploadProps: {
                    accept: ".mp4,.webm",
                    size: 1048576,
                    placeholder: "视频链接地址",
                  },
                  formName: "video0",
                  formData: {
                    content: "",
                    width: "",
                    height: "",
                    poster: "",
                    align: "",
                    alignStyle: "",
                  },
                  formRules: {
                    content: [
                      {
                        required: true,
                        message: "请上传视频",
                        trigger: "blur",
                      },
                    ],
                  },
                },
                {
                  title: "外链视频",
                  desc: "支持mp4、webm链接和第三方网站分享视频iframe代码",
                  formName: "video1",
                  formData: {
                    content: "",
                    width: "",
                    height: "",
                    poster: "",
                    align: "",
                    alignStyle: "",
                  },
                  formRules: {
                    content: [
                      {
                        required: true,
                        message: "请输入有效视频链接或代码",
                        trigger: "blur",
                        pattern: /\.(mp4|webm)|<\/iframe>$/,
                      },
                    ],
                  },
                },
              ],
              template(data) {
                if (/\.(mp4|webm)$/.test(data.content)) {
                  data.content = `<video controls src="${data.content}" poster="${data.poster}" width="${data.width}" height="${data.height}" style="${data.alignStyle}"></video>`;
                }
                return `<p class="el-tinymce-resource el-tinymce-video">${data.content}</p>`;
              },
            },
          },
        ];
      },
    },
    // 上传文件的方法
    upload: {
      required: true,
      type: Function,
    },
  },
};
</script>

用法

如果不希望每次使用组件时都显式传入 upload prop,则可以在全局注册组件前,通过 Vue.use 方式安装组件,给 use 传第二个参数,或者直接赋值 window.ElSingleUploadOptions,数据结构要求{upload:foo}。upload 是上传接口方法,这样后面多处使用该组件实例时就不需要显式传入 upload prop 了。 还有一种方法,就是再包一层,在包裹 js 里,直接修改此组件的 props,其他地方使用修改后的组件

internal vue element-ui 方式

npm i vue element-ui tinymce @panhezeng/el-tinymce -S

异步

<script>
function upload(option) {}
const ElTinymce = () => {
  return import("../../dist/el-tinymce.min").then((res) => {
    Object.assign(res.props.upload, {
      required: false,
      default: upload,
    });
    return Promise.resolve(res);
  });
};

export default {
  components: { ElTinymce },
};
</script>

同步

export default components
<script>
import ElTinymce from "@panhezeng/el-tinymce";

export default {
  components: { ElTinymce },
};
</script>
Vue.use
<script>
import Vue from "vue";
import ElTinymce from "@panhezeng/el-tinymce";

Vue.use(ElTinymce);
</script>

external vue element-ui 方式

<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/element-ui@~2/lib/theme-chalk/index.css"
/>
<script src="https://cdn.jsdelivr.net/combine/npm/vue@~2/dist/vue.min.js,npm/element-ui@~2/lib/index.js"></script>

npm i tinymce @panhezeng/el-tinymce -S

// auto install
import "@panhezeng/el-tinymce";

or

<!--auto install-->
<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/element-ui@~2/lib/theme-chalk/index.css"
/>
<script src="https://cdn.jsdelivr.net/combine/npm/vue@~2/dist/vue.min.js,npm/element-ui@~2/lib/index.js,npm/tinymce@%5E5.10.3/tinymce.min.js,npm/@panhezeng/el-tinymce@latest/dist/el-tinymce.min.js"></script>

编译

# install dependencies
npm install

# 运行插件使用示例
npm run dev:example

# 编译插件
npm run build

# 发版
npm publish --access public --registry https://registry.npmjs.org/

# 发版patch
npm version patch && npm publish --access public --registry https://registry.npmjs.org/