vue组件封装之computed妙用

1,310 阅读1分钟

前言

在工作中,我们会经常封装一些业务组件,然后封装业务组件的时候会使用到双向绑定功能简化操作,而这篇文章正是使用computed实现双向绑定功能。

前置技能

vue2/vue3 computed vue双向绑定 element-ui

在此主要讲的是computedvue双向绑定

如果你还不理解什么是vue双向绑定,建议先看vue官方文档《组件基础 在组件上使用 v-model》《自定义事件 — sync修饰符》,在此不多赘述。

场景

以封装一个弹窗组件为例,由于使用了ui框架,所以实际上是3方组件通信:外部组件、业务组件、ui组件通信,在此使用computed让3方都能够双向绑定起来

init

环境:vue2 element-ui

<template>
  <el-dialog :visible.sync="visible" class="demo-dialog" title="弹窗名称"> 
    do somthing
  </el-dialog>
</template>

<script>
export default {
  name: 'DemoDialog',
  data() {
    return {
      // 控制弹窗的显隐
      visible: false,
    };
  },
};
</script>

<style lang="scss"></style>

很简单,一个弹窗组件就做好了,接下来我们要让它能通过外部变量控制开启和关闭弹窗组件

通过props传入的属性控制弹窗的显隐

<template>
  <el-dialog :visible.sync="visible" class="demo-dialog" title="弹窗名称"> do something </el-dialog>
</template>

<script>
export default {
  name: 'DemoDialog',
  props: {
    // 通过外部传入的属性控制弹窗的显隐
    show: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      // 控制弹窗的显隐
      visible: false,
    };
  },
  watch: {
    // 监听show的变化,如果有变动则设置visible
    show: {
      handler(n) {
        this.visible = n;
      },
      // 立即响应,有可能组件刚渲染就show就已经设置过了
      immediate: true,
    },
    visible(n) {
      // 如果visible变动(el-dialog双向绑定值修改)并且和show不一样时,通过双向绑定改变show的值
      if (n !== this.show) this.$emit('update:show', n);
    },
  },
};
</script>

<style lang="scss"></style>

在此新增了props show,以及watch监听show变化时同步设置visible、监听visible变化时通知外部

使用弹窗组件

<template>
  <div class="use-dialog">
    <!--  使用弹窗组件  -->
    <DemoDialog :show.sync="show" />
    <button @click="show=true">点击打开弹窗</button>
  </div>
</template>

<script>
import DemoDialog from './DemoDialog';
export default {
  name: 'UseDialog',
  components: {
    DemoDialog,
  },
  data() {
    return {
      // 控制弹窗组件显隐
      show: false,
    };
  },
};
</script>

<style lang="scss"></style>

发现了吗,如果不使用computed而用watch实现双向绑定的话,需要监听showvisible,过于繁琐,接下来使用computed简化这一步。

使用computed优化

<template>
  <el-dialog :visible.sync="visible" class="demo-dialog" title="弹窗名称"> do something </el-dialog>
</template>

<script>
export default {
  name: 'DemoDialog',
  props: {
    // 通过外部传入的属性控制弹窗的显隐
    show: {
      type: Boolean,
      default: false,
    },
  },
  computed: {
    visible: {
      // 直接返回show
      get() {
        return this.show;
      },
      // 接收el-dialog双向绑定的显隐,当el-dialog设置visible值时双向绑定改变show的值
      set(value) {
        this.$emit('update:show', value);
      },
    },
  },
};
</script>

<style lang="scss"></style>

首先data中的visible改为了computed属性,并且set get都要使用(computed普遍用法是不设set只用get),然后get直接返回showsetemit事件、通过双向绑定语法糖改变show的值。

vue3版

<template>
  <el-dialog v-model="visible" class="demo-dialog" title="弹窗名称"> do something </el-dialog>
</template>
<script lang="ts" setup>
import { defineEmits, computed } from 'vue';

const props = defineProps({
  show: {
    type: Boolean,
    default: true,
  },
});

const emits = defineEmits(['update:show']);

const visible = computed({
  get: () => props.show,
  set: (value: boolean) => emits('update:show', value),
});
</script>

最后

其实不仅仅是封装弹窗组件时可以使用该方法,任何需要组件内外皆可操控某个值的场景都可以使用该方法,能使我们代码更加优雅,也更好理解。