20.compositionApi介绍和setup函数的参数和返

2021-08-28  本文已影响0人  静昕妈妈芦培培

Options API的弊端

在Vue2中,我们编写组件的方式是Options API:

但是这种代码有一个很大的弊端:
下面我们来看一个非常大的组件,其中的逻辑功能按照颜色进行了划分:
这就是Composition API想要做的事情,以及可以帮助我们完成的事情。也有人把Vue CompositionAPI简称为VCA。

认识Composition API

那么既然知道Composition API想要帮助我们做什么事情,接下来看一下到底是怎么做呢?

setup其实就是组件的另外一个选项:
接下来我们一起学习这个函数的使用:

setup函数的参数

我们先来研究一个setup函数的参数,它主要有两个参数:

props非常好理解,它其实就是子组件接收的从父组件传递过来的属性,会被放到1props对象中,我们在setup函数中如果需要使用,那么就可以直接通过props参数获取:
另外一个参数是context,我们也称之为是一个SetupContext,它里面包含三个属性:

attrs:为一个对象,存储着所有的从父组件传递过来的非props的attribute;
slots:父组件传递过来的插槽(这个在以渲染函数返回时会有作用,后面会讲到);
emit:当我们组件内部需要发出事件时会用到emit(因为我们不能访问this,所以不可以通过 this.$emit发出事件);

setup函数的返回值

setup既然是一个函数,那么它也可以有返回值,它的返回值用来做什么呢?

甚至是我们可以返回一个执行函数来代替在methods中定义的方法

setup() {
  let counter = 100
  const increment = () => {
    counter++
  }
  const decrement = () => {
    counter--
  }
  return {
    counter,
    increment,
    decrement
  }
}

但是,如果我们将 counter 在 increment 或者 decrement进行操作时,是否可以实现界面的响应式呢?

案例

App.vue
所有在template模板中使用的变量方法(除了props$attrs中的属性),都得在setup函数中返回

<template>
  <div>
    <!--父组件在使用子组件home时,除了给其传了内部接收的props的属性message,title外,还额外传了两个非props属性id, class-->
    <home
      message="hahahh"
      title="标题"
      id="home"
      class="homeClass"
      @change="change"
    />
  </div>
</template>

<script>
import Home from "./Home.vue";
export default {
  name: "App",
  components: {
    Home,
  },
  setup() {
    const change = (value) => {
      console.log("监听到了change事件", value);
    };
    return {
      //所有在template模板中使用的变量或方法(除了props和$attrs中的属性),都得在setup函数中返回
      change,
    };
  },
};
</script>

<style></style>

Home.vue
父组件传递给子组件的非props属性template中使用,这些属性都存储在$attrs对象中,可以通过attrs.属性名获取
父组件传递给子组件的非props属性setup函数中获取,这些属性都存储在setup函数的第二个参数对象contextattrs属性中,可以通过context.attrs.属性名获取

父组件传递给子组件的props属性setup函数中获取,这些属性都存储在setup函数第一个参数对象props中,可以通过props.属性名获取
在setup函数中,子组件向父组件发射事件,可以通过context.emit发射事件

<template>
  <div>
    <h2>{{ title }}</h2>
    <p>{{ message }}</p>
    <!-- 下面展示父组件传递给子组件的非props属性在template中的使用,这些属性都存储在$attrs对象中 -->
    <div>id: {{ $attrs.id }} - class: {{ $attrs.class }}</div>
    <slot></slot>
  </div>
</template>

<script>
export default {
  props: {
    message: {
      type: String,
      required: true,
    },
    title: {
      type: String,
      default: "",
    },
  },
  emits: ["change"],
  setup(props, context) {
    const { attrs, slots, emit } = context;
    //在setup中获取props中属性,通过setup函数的第一个参数获取
    console.log("props", props, props.message, props.title);
    //父组件传递给子组件的非props属性在setup中使用,这些属性都存储在context.attrs对象中
    console.log("attrs", attrs, attrs.id, attrs.class);
    //父组件插入子组件插槽中的内容
    console.log("slots", slots);
    emit("change", "今天天气不错"); //emit用来向父组件发射事件
  },
};
</script>

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

image.png

setup不可以使用this

官方关于this有这样一段描述:

上一篇 下一篇

猜你喜欢

热点阅读