vue3x——provide与inject、Composition API、Fragment、Teleport、Suspense

Vue3x

5.provide与inject

作用:实现祖孙组件间通信

套路:父组件有一个provide选项来提供数据,子组件有一个inject选项来开始使用这些数据

具体写法:

1.父组件中:引用provide

<template>
  <div class="app">
    <p>我是App组件————祖组件</p>
    <p>数据:name:{{ name }}——————age:{{ age }}</p>
    <Child />
  </div>
</template>

<script>
import Child from "./components/Child.vue";
import { reactive, toRefs, provide } from "vue";
export default {
  name: "App",
  components: {
    Child,
  },
  setup() {
    let obj = reactive({
      name: "张三",
      age: 20,
    });
    // 给自己的后代组件传递数据
    provide("obj", obj);
    return {
      // obj,
      ...toRefs(obj),
    };
  },
};
</script>

<style>
.app {
  padding: 10px;
  border-radius: 5px;
  background-color: orange;
}
</style>

2.子组件:中间的组件

<template>
  <div class="child">
    <p>我是child组件————子组件</p>
    <Son />
  </div>
</template>

<script>
// 在这个组件也可以用inject接收父组件的数据,但是这是父子组件之间的传值,一般不用这个
import Son from "./Son.vue";
export default {
  name: "child",
  components: {
    Son,
  },
};
</script>

<style>
.child {
  padding: 10px;
  border-radius: 5px;
  background-color: pink;
}
</style>

3.孙组件:

<template>
  <div class="son">
    <p>我是Son组件————孙组件</p>
  </div>
</template>

<script>
import { inject } from "vue";
export default {
  name: "Son",
  setup() {
    //   这个obj也是响应式的数据
    const obj = inject("obj");
    return {
      obj,
    };
  },
};
</script>

<style>
.son {
  padding: 10px;
  border-radius: 5px;
  background-color: skyblue;
}
</style>
6.响应式数据的判断

1.isRef:检查一个值是否为一个ref对象(RefImpl)

2.isReactive:检查一个对象是否是由reactive创建爱你的响应式代理

3.isReadonly:检查一个对象是否是由readonly创建的只读代理

4.isProxy:检查一个对象是否由reactive或者readonly方法创建的代理

<template>
  <div class="app">
    <p>obj:{{ name }}——————{{ age }}</p>
    <p>p:{{ p }}</p>
  </div>
</template>

<script>
import {
  reactive,
  toRefs,
  ref,
  readonly,
  isProxy,
  isReactive,
  isRef,
  isReadonly,
} from "vue";
export default {
  name: "App",
  components: {},
  setup() {
    let obj = reactive({
      name: "张三",
      age: 20,
    });
    let num = ref(0);
    let p = readonly(obj);
    // 判断
    console.log(isProxy(p)); //true
    console.log(isProxy(obj)); //true
    console.log(isReactive(p)); //true
    console.log(isReactive(obj)); //true
    console.log(isRef(num)); //true
    console.log(isReadonly(p)); //true
    console.log(isReadonly(obj)); //false

    return {
      // obj,
      ...toRefs(obj),
      num,
      p,
    };
  },
};
</script>

<style>
.app {
  padding: 10px;
  border-radius: 5px;
  background-color: orange;
}
</style>

Composition API的优势

1.Options API存在的问题

​ 使用传统Options API(vue2.0)中,新增或者修改一个需求,就需要分别在data、methods、computed里修改

2.Composition API的优势

​ 可以更加优雅的组织代码、函数,让相关功能的代码更加有序的组织在一起(要结合hooks)

新的组件

1.Fragment

​ 在Vue2中:组件必须有一个根标签

​ 在Vue3中:组件可以没有根标签,内部会将多个标签包含在一个Fragment虚拟元素中

​ 好处:减少标签层级,减少内存占比

2.Teleport

​ Teleport是一种能够将我们的组件html结构移动到指定位置的技术

<template>
  <div>
    <button @click="isShow = !isShow">显示弹窗</button>
    <!-- to:将teleport标签内的内容放到指定地方,可以写当前页面内的标签,也可以写与容器(App)平级的容器 -->
    <teleport to="body">
      <!-- <teleport to="#box"> -->
      <!-- 遮罩层 -->
      <div v-if="isShow" class="mask">
        <div class="dialog">
          <p>干饭了</p>
          <p>下班啦</p>
          <p>睡觉了</p>
          <button @click="isShow = false">关闭弹窗</button>
        </div>
      </div>
    </teleport>
  </div>
</template>

<script>
import { ref } from "vue";
export default {
  name: "Dialog",
  setup() {
    let isShow = ref(false);
    return {
      isShow,
    };
  },
};
</script>

<style>
.mask {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.3);
}
.dialog {
  /* 居中显示 */
  position: absolute;
  left: 50%;
  top: 50%;
  /* 参考自身 */
  transform: translate(-50%, -50%);
  width: 300px;
  height: 300px;
  border-radius: 10px;
  color: #fff;
  text-align: center;
  font-weight: bold;
  background-color: palevioletred;
}
</style>
3.Suspense

等待异步组件时渲染一些额外内容,让应用有更好的用户体验

使用步骤:

​ 异步引入组件:

import { defineAsyncComponent } from "vue";
const Child = defineAsyncComponent(() => import("./components/Child.vue"));

​ 使用Suspense包裹组件,并配置好default与fallback

<Suspense>
      <!-- 正常情况下默认显示的是这个,default是固定的,不可改 -->
      <template v-slot:default>
        <Child />
      </template>
      <!-- 网速太慢了,Child组件还未渲染出来时显示这里面的内容,fallback是内定的,不可改 -->
      <template v-slot:fallback>
        <p>加载中,请稍后</p>
      </template>
    </Suspense>

你可能感兴趣的:(javascript,Vue,es6,vue.js,javascript,组件化,vue3)