686 vue3 Composition API:setup的this、参数、返回值,reactive ,ref,readonly,toRefs,toRef,shallowRef

Options API的弊端


大组件的逻辑分散


认识Composition API


setup函数的参数


setup函数的返回值


setup不可以使用this



App.vue

<template>
  <div>
    <home message="hahahaha" id="aaa" class="bbbb"></home>
  </div>
</template>

<script>
  import Home from "./Home.vue";

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

<style scoped></style>

02_setup的参数.vue

<template>
  <div>
    <h3>Home Page</h3>
    <h3>{{ message }}</h3>

    <h2>{{ title }}</h2>
    <h2>当前计数: {{ counter }}</h2>
    <button @click="increment">+1</button>
  </div>
</template>

<script>
  export default {
    props: {
      message: {
        type: String,
        required: true,
      },
    },
    data() {
      return {
        counter: 100,
      };
    },
    /**
     * 参数一: props, 父组件传递过来属性
     */
    // setup函数有哪些参数?
    // setup函数有什么样的返回值
    // setup(props, context) {
    setup(props, { attrs, slots, emit }) {
      console.log(props.message);
      console.log(attrs.id, attrs.class);
      console.log(slots);
      console.log(emit);

      return {
        title: "Hello Home",
        counter: 100,
      };
    },
    methods: {
      btnClick() {
        this.$emit("");
      },
    },
  };
</script>

<style scoped></style>

03_setup的返回值.vue

<template>
  <div>
    Home Page
    <h2>{{ message }}</h2>

    <h2>{{ title }}</h2>
    <h2>当前计数: {{ counter }}</h2>
    <button @click="increment">+1</button>
  </div>
</template>

<script>
  export default {
    props: {
      message: {
        type: String,
        required: true,
      },
    },
    setup() {
      let counter = 100;

      // 局部函数
      const increment = () => {
        counter++;
        console.log(counter);
      };

      return {
        title: "Hello Home",
        counter,
        increment,
      };
    },
  };
</script>

<style scoped></style>

Reactive API


04_reactiveAPI使用.vue

<template>
  <div>
    Home Page
    <h2>{{ message }}</h2>
    <h2>当前计数: {{ state.counter }}</h2>
    <button @click="increment">+1</button>
  </div>
</template>

<script>
  import { reactive } from "vue";

  export default {
    props: {
      message: {
        type: String,
        required: true,
      },
    },
    setup() {
      const state = reactive({
        counter: 100,
      });

      // 局部函数
      const increment = () => {
        state.counter++;
        console.log(state.counter);
      };

      return {
        state,
        increment,
      };
    },
  };
</script>

<style scoped></style>

Ref API


Ref自动解包


05_refAPI使用.vue

<template>
  <div>
    Home Page
    <h2>{{ message }}</h2>
    <!-- 当我们在template模板中使用ref对象, 它会自动进行解包 -->
    <h2>当前计数: {{ counter }}</h2>
    <button @click="increment">+1</button>

    <show-message :message="counter"></show-message>
  </div>
</template>

<script>
  import { ref } from "vue";

  export default {
    props: {
      message: {
        type: String,
        required: true,
      },
    },
    setup() {
      // counter编程一个ref的可响应式的引用
      // counter = 100;
      let counter = ref(100);

      // 局部函数
      const increment = () => {
        counter.value++;
        console.log(counter.value);
      };

      return {
        counter,
        increment,
      };
    },
  };
</script>

<style scoped></style>

06_ref的浅层解包.vue

<template>
  <div>
    Home Page
    <h2>{{ message }}</h2>
    <!-- 当我们在template模板中使用ref对象, 它会自动进行解包 -->
    <h2>当前计数: {{ counter }}</h2>
    <!-- ref的解包只能是一个浅层解包(info是一个普通的JavaScript对象) -->
    <h2>当前计数: {{ info.counter.value }}</h2>
    <!-- 当如果最外层包裹的是一个reactive可响应式对象, 那么内容的ref可以解包 -->
    <h2>当前计数: {{ reactiveInfo.counter }}</h2>
    <button @click="increment">+1</button>
  </div>
</template>

<script>
  import { ref, reactive } from "vue";

  export default {
    props: {
      message: {
        type: String,
        required: true,
      },
    },
    setup() {
      let counter = ref(100);

      const info = {
        counter,
      };

      const reactiveInfo = reactive({
        counter,
      });

      // 局部函数
      const increment = () => {
        counter.value++;
        console.log(counter.value);
      };

      return {
        counter,
        info,
        reactiveInfo,
        increment,
      };
    },
  };
</script>

<style scoped></style>

认识readonly


readonly的使用


readonly.vue

<template>
  <div>
    <!-- 下面3行, 加的 -->
    <div>{{ info1.name }}</div>
    <div>{{ info2.name }}</div>
    <div>{{ info3 }}</div>
    <button @click="updateState">修改状态</button>
  </div>
</template>

<script>
  import { reactive, ref, readonly } from "vue";

  export default {
    setup() {
      // 1.普通对象
      const info1 = { name: "why" };
      const readonlyInfo1 = readonly(info1);

      // 2.响应式的对象reactive
      const info2 = reactive({
        name: "why",
      });
      const readonlyInfo2 = readonly(info2);

      // 3.响应式的对象ref
      const info3 = ref("why");
      const readonlyInfo3 = readonly(info3);

      const updateState = () => {
        // 【不允许这样修改】
        // readonlyInfo3.value = "hahaha"
        info3.value = "hahaha";
      };

      return {
        // 下面3行, 加的
        info1,
        info2,
        info3,
        updateState,
      };
    },
  };
</script>

<style scoped></style>

Reactive判断的API


Reactive判断的API.vue

<template>
  <div></div>
</template>

<script>
  import {
    reactive,
    readonly,
    isProxy,
    isReadonly,
    isReactive,
  } from "vue";

  export default {
    setup() {
      const obj = { name: "杰", age: 18, friends: { name: "哈哈", age: 66 } };
      const info1 = reactive(obj);
      const info2 = readonly(obj);
      console.log(isProxy(info1), isProxy(info2)); // true true
      console.log(isReadonly(info1), isReadonly(info2)); // false true
      console.log(isReactive(info1), isReactive(info2)); // true false
    },
  };
</script>

<style scoped></style>

toRefs


toRef


01_toRefs和toRef的使用.vue

<template>
  <div>
    <h2>{{ name }}-{{ age }}</h2>
    <button @click="changeAge">修改age</button>
  </div>
</template>

<script>
  import { reactive, toRefs, toRef } from "vue";

  export default {
    setup() {
      const info = reactive({ name: "why", age: 18 });
      // 1.toRefs:将reactive对象中的所有属性都转成ref,建立链接【传入reactive对象】
      // let { name, age } = toRefs(info);

      // 2.toRef: 对其中一个属性进行转换ref, 建立链接
      let { name } = info;
      let age = toRef(info, "age"); // toRef返回一个ref值,不能解构age

      const changeAge = () => {
        age.value++;
      };

      return {
        name,
        age,
        changeAge,
      };
    },
  };
</script>

<style scoped></style>

ref其他的API


02_refAPI的补充.vue

<template>
  <div>
    <h2>{{ info }}</h2>
    <button @click="changeInfo">修改Info</button>
  </div>
</template>

<script>
  import { ref, shallowRef, triggerRef } from "vue";

  export default {
    setup() {
      const res = ref({ name: "杰11", age: 18 });
      console.log(res.value.name); // 杰11
      console.log(unref(res).name); // 杰11

      // 这种是深层的响应式 【深层:对象里的属性也是响应式的,浅层:对象里的属性不是响应式的,需要triggerRef触发才能能变成响应式。】
      // const info = ref({name: "why"})
      const info = shallowRef({ name: "why" });

      const changeInfo = () => {
        // 【注意,是info.value.name,不是info.name.value】
        info.value.name = "james";
        // 【副作用:比如页面响应式更新数据。】
        triggerRef(info);
      };

      return {
        info,
        changeInfo,
      };
    },
  };
</script>

<style scoped></style>

customRef【了解】


posted on 2021-06-18 22:21  冲啊!  阅读(285)  评论(0编辑  收藏  举报

导航