vue二次封装组件

本文介绍了Vue组件化的最佳实践,包括自定义组件设计原则,如API先行、props的语义化和校验。重点讲解了如何封装Editor编辑器组件,利用wangeditor插件,通过npm或CDN引入。详细阐述了组件的初始化、数据回显、内容变更事件监听以及父子组件间的数据传递。在遇到问题时,通过$watch监听props变化以实现内容更新。最后总结了组件化的常见操作,并展示了源代码示例。
摘要由CSDN通过智能技术生成

2、vue 组件化开发

2.7 自定义组件的 总结
  1. 编写组件时,应该 api 先行,先确定组件 该 如何给用户用,再根据 api 编写逻辑
  2. props 的名称 应该具备语义化,类型应该符合规范,并且可以添加自定义校验
  3. 组件上绑定的类似于原生的事件,默认是不会被识别的,需要额外处理
  4. 组件有一些设计需要整体把控,比如 props 与 对应类名的匹配,这是我们故意设计的
2.8 Editor 编辑器组件开发

通常,我们封装组件,不会自己从头开始封装, 一般来说都是借鉴别人的 第三方基础插件 进行封装

npm 安装 npm i wangeditor --save

CDN 链接 https://cdn.jsdelivr.net/npm/wangeditor@latest/dist/wangEditor.min.js

Editor官网

2.9 初始化 Editor
<template>
  <div ref="editorRef">editor</div>
</template>

<script>
// 引入第三方的编辑器插件
import E from "wangeditor";
export default {
  props: {},
  data() {
    return {};
  },
  created() {},
  mounted() {
    // 因我们需要 DOM 渲染完成 才能初始化
    // 所以我们 再  mounted 钩子函数里面初始化
    this.initEditor();
  },
  watch: {},
  computed: {},
  methods: {
    initEditor() {
      // 编辑器初始化方法
      const editor = new E(this.$refs.editorRef);
      editor.create();
    },
  },
  components: {},
};
</script>
<style lang="less" scoped>
</style>

2.10 实现数据的回显

app.vue

<template>
  <div>
    <br />
    <!-- 
      1、编辑器组件可以接收我传入的数据,并且可以显示到编辑器内部,实现数据的回显
      2、一旦编辑器中进行内容编辑之后,绑定的 content 属性,也可以得到修改,变成编辑器中最新的值
     -->
    <!-- 
       实现步骤
      1、实现 回显:
        v-model 一旦写到 一个组件身上,默认情况下 相当于
        传入了名为 value 的自定义 属性,以及名为 input 的自定义事件
        v-model 其实是一个语法糖,可以写一次完成两件事情
        
      -->
    <Editor v-model="content" />
  </div>
</template>

<script>
import Editor from "./components/Editor/index";
export default {
  props: {},
  data() {
    return {
      content: "我是编辑器,我出来了",
    };
  },
  components: {
    DButton,
    Editor,
  },
};
</script>
<style lang="less" scoped>
</style>

index.vue

  methods: {
    initEditor() {
      // 编辑器初始化方法
      const editor = new E(this.$refs.editorRef);
      editor.create();
      editor.txt.html(this.value); // 重新设置编辑器内容
    },
  },
2.11 实现 编辑器内容更改,传出到 content

就是子传父
2、编辑器一旦编辑内容就把 绑定的 content 属性修掉
1)如何 知道 内容已经编辑了,三方插件提供了方法
2)如果拿到最新的编辑内容然后传出来 交给 content (子传父) $emit(“input”,传递的参数)

  methods: {
    initEditor() {
      // 编辑器初始化方法
      const editor = new E(this.$refs.editorRef);
      // 配置 onchange 回调函数
      editor.config.onchange = (newHtml) => {
        // newHtml 就是编辑器 拿到的,最新的内容
        this.$emit("input", newHtml);
        console.log("change 之后最新的 html", newHtml);
      };
      // 配置触发 onchange 的时间频率,默认为 200ms
      editor.config.onchangeTimeout = 500; // 修改为 500ms
      editor.create();
      editor.txt.html(this.value); // 重新设置编辑器内容
    },
2.11 解决bug,首次数据回显是可以的,第二次不行

如果我们 content 修改了, 会传递到自定义组件,只是自定义组件没有调用相应的方法,进行重新赋值

实现思路,就是每一次 content 发生变化, props中都能 拿到最新的值
我们可以 监控以下, props 中的 value 一旦 value 发生变化,就重新执行一下设置编辑器内容的方法

用 watch 也可以

  methods: {
    initEditor() {
      // 编辑器初始化方法
      const editor = new E(this.$refs.editorRef);
      // 配置 onchange 回调函数
      editor.config.onchange = (newHtml) => {
        // newHtml 就是编辑器 拿到的,最新的内容
        this.$emit("input", newHtml);
        console.log("change 之后最新的 html", newHtml);
      };
      // 配置触发 onchange 的时间频率,默认为 200ms
      editor.config.onchangeTimeout = 500; // 修改为 500ms
      editor.create();
      editor.txt.html(this.value); // 重新设置编辑器内容

      // 当 content 发生变化,  props 其实 已经拿到了,最新的值,但是 视图中, 并没有发生变化
      // 我们可以 监控一下, props 中的 value 一旦 value 发生变化,就重新执行一下设置编辑器内容的方法
      // 用 内置 的 watch 的 optionsAPI
      // $watch 方法 和 watch 配置项 内部实现的 核心原理是一致的,但是 $watch 更加灵活,它并不是组件进行初始化就立刻坚挺的,而是 再某个时刻 你想要监听 的时候,才进行的监听
      this.$watch("value", (newVal, oldVal) => {
        editor.txt.html(this.value); // 重新设置编辑器内容
      });
    },
  },
2.12 总结
  1. 在实际开发中,可能会根据业务借助 三方成熟的插件 修改成我们自己的 vue组件
  2. 在自己的组件 中 把三方组件的功能按照 api 实现出来,然后 暴露一些 api 供用户使用
  3. 组件身上添加 v-model ,一般用于 组件内部 有可能输入的控件,比如 input textarea 内容编辑,目的是为了实现双向绑定,
    • 一旦组件身上写了 v-model 之后,相当于 1. 名称为 value 的自定义属性的绑定 2. 名称为input 的自定义事件
    • ===> <Editor :value="" @input="">
    • 父子传参中 通过定义 props:{value} 来接收传下来的数据
    • 用过 触发 $emit(‘input’) 实现将子组件的数据添加到父组件中
    • 特别注意。v-model 语法糖下,我们并不需要 在父组件定义一个方法来修改 父组件给子组件传递 value 的值,vue系统自己知道要修改谁

源代码

app.vue

<template>
  <div>
   
    <br />
    <!-- 
      1、编辑器组件可以接收我传入的数据,并且可以显示到编辑器内部,实现数据的回显
      2、一旦编辑器中进行内容编辑之后,绑定的 content 属性,也可以得到修改,变成编辑器中最新的值
     -->
    <!-- 
       实现步骤
      1、实现 回显:
        v-model 一旦写到 一个组件身上,默认情况下 相当于
        传入了名为 value 的自定义 属性,以及名为 input 的自定义事件
        v-model 其实是一个语法糖,可以写一次完成两件事情
      2、编辑器一旦编辑内容就把 绑定的 content 属性修掉
        1)如何 知道 内容已经编辑了,三方插件提供了方法
        2)如果拿到最新的编辑内容然后传出来 交给 content (子传父) $emit("input",传递的参数)
      -->
    <Editor v-model="content" />
  </div>
</template>

<script>
import DButton from "./components/Button/index.vue";
import Editor from "./components/Editor/index";
export default {
  props: {},
  data() {
    return {
      content: "我是编辑器,我出来了",
    };
  },
  created() {},
  mounted() {},
  watch: {},
  computed: {},
  methods: {
    handle(e) {
      console.log("点击了", e);
    },
  },
  components: {
    DButton,
    Editor,
  },
};
</script>
<style lang="less" scoped>
</style>

二次封装的组件源代码

<template>
  <div ref="editorRef">editor</div>
</template>

<script>
// 引入第三方的编辑器插件
import E from "wangeditor";
export default {
  props: {
    value: {
      type: String,
    },
  },
  data() {
    return {};
  },
  created() {},
  mounted() {
    // 因我们需要 DOM 渲染完成 才能初始化
    // 所以我们 再  mounted 钩子函数里面初始化
    this.initEditor();
  },
  watch: {},
  computed: {},
  methods: {
    initEditor() {
      // 编辑器初始化方法
      const editor = new E(this.$refs.editorRef);
      // 配置 onchange 回调函数
      editor.config.onchange = (newHtml) => {
        // newHtml 就是编辑器 拿到的,最新的内容
        this.$emit("input", newHtml);
        console.log("change 之后最新的 html", newHtml);
      };
      // 配置触发 onchange 的时间频率,默认为 200ms
      editor.config.onchangeTimeout = 500; // 修改为 500ms
      editor.create();
      editor.txt.html(this.value); // 重新设置编辑器内容

      // 当 content 发生变化,  props 其实 已经拿到了,最新的值,但是 视图中, 并没有发生变化
      // 我们可以 监控一下, props 中的 value 一旦 value 发生变化,就重新执行一下设置编辑器内容的方法
      // 用 内置 的 watch 的 optionsAPI
      // $watch 方法 和 watch 配置项 内部实现的 核心原理是一致的,但是 $watch 更加灵活,它并不是组件进行初始化就立刻坚挺的,而是 再某个时刻 你想要监听 的时候,才进行的监听
      this.$watch("value", (newVal, oldVal) => {
        editor.txt.html(this.value); // 重新设置编辑器内容
      });
    },
  },
  components: {},
};
</script>
<style lang="less" scoped>
</style>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值