动态组件与数据穿透_vue3选项api

简介: 动态组件与数据穿透_vue3选项api

动态组件与数据穿透_vue3选项api

动态组件

有的需求会想要在两个组件间来回切换,比如 Tab 界面:

上面的例子是通过 Vue 的 <component> 元素和特殊的 is attribute 实现的:

<!-- currentTab 改变时组件也改变 -->
<component :is="currentTab"></component>

在上面的例子中,被传给 :is 的值可以是以下几种:

  • 被注册的组件名
  • 导入的组件对象

你也可以使用 is attribute 来创建一般的 HTML 元素。

当使用 <component :is="..."> 来在多个组件间作切换时,组件会在被切换掉后卸载。我们可以通过 <KeepAlive>组件强制不活跃的组件仍然保持“存活”的状态。

数据穿透

父组件使用provide,任意层级的子组件使用inject。可以实现数据穿透,从而不需要一级一级的使用prop传参。

如果要实现响应式:

  • 传递的参数为一个对象,利用对象传递为传址的js特性
  • 传递一个计算属性(computed)

父组件

<script>
//....
export default {
  provide() {
    return {
      siteTitle: this.db[0].title,
    };
  },
//....
};
</script>

<!--
......
-->

子组件

<script>
export default {
//....
  inject: ["siteTitle"],
  data() {
    return {
      inputKey: this.siteTitle,
    };
  },
//....
};
</script>

<!--
......
-->

ref

我们可以通过ref来使父组件调用子组件的属性和方法

父组件

<script>
export default {
//......
  methods: {
    callShow() {
      this.$refs.component.show();
    },
  },
//......
};
</script>

<!-- .... -->
<button @click="callShow">App调用子组件的方法</button>
<component :is="curComponent" ref="component" />
<!-- .... -->

子组件

<script>
export default {
//....
  methods: {
    show() {
      alert(`${this.inputValue}组件的show方法`);
    },
  },
//....
};
</script>
<!-- ....  -->

实例演示

文件结构为App.vue根组件,component文件夹里面的子组件,data文件夹里面的db.js

App.vue

<script>
import WeChat from "./components/WeChat.vue";
import Site from "./components/Site.vue";
import db from "./data/db";
export default {
  components: { Site, WeChat },
  provide() {
    return {
      siteTitle: this.db[0].title,
    };
  },
  data() {
    return {
      curComponent: "we-chat",
      db,
      components: [
        { title: "微信管理", name: "we-chat" },
        { title: "站点管理", name: "site" },
      ],
    };
  },
  methods: {
    callShow() {
      this.$refs.component.show();
    },
  },
};
</script>

<template>
  <div class="m-4">
    <button
      v-for="(component, index) of components"
      :key="index"
      @click="curComponent = component.name"
      :class="{ 'bg-green-700 text-white': component.name === curComponent }"
    >
      {{ component.title }}
    </button>
    <button @click="callShow">App调用子组件的方法</button>
    <KeepAlive>
      <component :is="curComponent" ref="component" />
    </KeepAlive>
  </div>
</template>

<style scoped>
button {
  @apply m-4 p-2 border-gray-200 border-2 shadow-md hover:shadow-lg;
}
</style>

Card.vue

<script setup></script>

<template>
  <div>
    <header>
      <slot name="header" />
    </header>
    <main>
      <slot />
    </main>
  </div>
</template>

<style scoped lang="scss">
div {
  @apply border-2 border-slate-200 mt-4 rounded-md;
  header {
    @apply border-b-2 border-slate-200 p-3 bg-slate-200;
  }
  main {
    @apply p-3;
  }
}
</style>

Site.vue

<script>
export default {
  inject: ["siteTitle"],
  data() {
    return {
      inputValue: "www.kk.com",
      inputKey: this.siteTitle,
    };
  },
  methods: {
    show() {
      alert(`Site组件的show方法`);
    },
  },
};
</script>

<template>
  <div class="">
    <card>
      <template #header>站点管理</template>
      <x-input title="站点网址" v-model="inputValue" />
      <x-textarea title="站点说明" v-model="inputKey" />
    </card>
  </div>
</template>

<style scoped></style>

WeChat.vue

<script>
export default {
  data() {
    return {
      inputValue: "wechat",
      inputKey: "abcd",
    };
  },
  methods: {
    show() {
      alert(`${this.inputValue}组件的show方法`);
    },
  },
};
</script>

<template>
  <div class="">
    <card>
      <template #header>微信管理</template>
      <x-input title="微信号" v-model="inputValue" />
      <x-input title="密钥" v-model="inputKey" />
    </card>
  </div>
</template>

<style scoped></style>

XInput.vue

<script>
export default {
  props: ["title", "modelValue"],
  // emits: ["update:modelValue"],
  data() {
    return {
      content: this.modelValue,
    };
  },
  watch: {
    content(v) {
      this.$emit("update:modelValue", v);
    },
  },
};
</script>

<template>
  <div class="">
    <label>
      <div>{{ title }}</div>
      <input type="text" v-model="content" />
    </label>
  </div>
</template>

<style scoped lang="scss">
label {
  @apply flex mt-2;
  div {
    @apply mr-4 text-gray-500 w-20;
  }
  input {
    @apply border-2 rounded-md pl-1 pr-1;
  }
}
</style>

XTextarea.vue

<script>
export default {
  props: ["title", "modelValue"],
  data() {
    return {
      key: this.modelValue,
    };
  },
  watch: {
    key(v) {
      this.$emit("update:modelValue", v);
    },
  },
};
</script>

<template>
  <label>
    <div>{{ title }}</div>
    <textarea cols="30" rows="5" v-model="key"></textarea>
  </label>
</template>

<style scoped lang="scss">
label {
  @apply flex mt-2;
  div {
    @apply mr-4 text-gray-500 w-20;
  }
  textarea {
    @apply border-2 rounded-md pl-1 pr-1;
  }
}
</style>

db.js

export default [
  { id: 1, title: 'vue3', preview: '/images/vue.jpg', price: 129 },
  { id: 2, title: 'typescript', preview: '/images/ts.jpg', price: 79 },
  { id: 1, title: 'javascript', preview: '/images/js.png', price: 88 },
]
相关文章
|
1月前
|
API
阿里云微服务引擎及 API 网关 2024 年 2 月产品动态
阿里云微服务引擎及 API 网关 2024 年 2 月产品动态
|
1月前
|
数据采集 JSON Java
揭秘阿里巴巴:如何通过API实时捕获中国市场商品数据
阿里巴巴提供了丰富的API接口,使得第三方开发者可以实时捕获中国市场商品数据。以下是一些关键步骤和要点,帮助你揭秘如何通过阿里巴巴的API实现这一目标:
|
1月前
|
JavaScript API
vue 3.0 所采用的 Composition Api 和 vue 2.0 使用的 Option Api 区别
vue 3.0 所采用的 Composition Api 和 vue 2.0 使用的 Option Api 区别
29 0
|
1月前
|
JSON Java API
教你如何使用API接口获取数据
随着互联网技术的发展和应用的普及,越来越多的系统和应用提供API接口供其他系统和应用进行数据交互。通过API接口,我们可以获取到各种各样的数据,例如天气预报、股票行情、新闻摘要等等。本文将介绍如何使用API接口获取数据,并附有示例代码。
|
2天前
|
API
阿里云微服务引擎及 API 网关 2024 年 3 月产品动态
阿里云微服务引擎及 API 网关 2024 年 3 月产品动态。
|
7天前
|
JavaScript 前端开发 API
Vue3 组合式 API
Vue3 组合式 API
|
25天前
|
供应链 搜索推荐 BI
深入了解淘宝原数据:获取API接口及其使用场景
在当今数字化的时代,对于电商行业来说,数据具有极大的价值。淘宝作为中国最大的综合电商平台,拥有庞大的商品信息和用户数据。对于开发者和企业来说,淘宝原数据的获取和分析是实现个性化服务和精准营销的基础。本文将介绍如何通过API接口获取淘宝原数据,以及数据的使用场景。
|
1月前
|
运维 Cloud Native 应用服务中间件
阿里云微服务引擎 MSE 及 API 网关 2024 年 02 月产品动态
阿里云微服务引擎 MSE 面向业界主流开源微服务项目, 提供注册配置中心和分布式协调(原生支持 Nacos/ZooKeeper/Eureka )、云原生网关(原生支持Higress/Nginx/Envoy,遵循Ingress标准)、微服务治理(原生支持 Spring Cloud/Dubbo/Sentinel,遵循 OpenSergo 服务治理规范)能力。API 网关 (API Gateway),提供 APl 托管服务,覆盖设计、开发、测试、发布、售卖、运维监测、安全管控、下线等 API 生命周期阶段。帮助您快速构建以 API 为核心的系统架构.满足新技术引入、系统集成、业务中台等诸多场景需要。
|
1月前
|
数据采集 API 开发者
调用API接口获取小红书笔记详情数据(小红书怎么推广)
小红书平台对于其API的使用有严格的规定和限制,并且并非所有的功能和数据都通过公开API提供。关于获取小红书笔记详情的API,以下是一些建议和指导:
|
1月前
|
存储 分布式计算 API
adb spark的lakehouse api访问内表数据,还支持算子下推吗
【2月更文挑战第21天】adb spark的lakehouse api访问内表数据,还支持算子下推吗
107 2

热门文章

最新文章