动态组件与数据穿透_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 },
]
相关文章
|
3月前
|
JSON 安全 API
亚马逊商品列表API秘籍!轻松获取商品列表数据
亚马逊商品列表API(SP-API)提供标准化接口,支持通过关键词、分类、价格等条件搜索商品,获取ASIN、价格、销量等信息。采用OAuth 2.0认证与AWS签名,保障安全。数据以JSON格式传输,便于开发者批量获取与分析。
|
3月前
|
JSON 缓存 算法
如何通过API获取1688商品类目数据:技术实现指南
1688开放平台提供alibaba.category.get接口,支持获取全量商品类目树。RESTful架构,返回JSON数据,含类目ID、名称、层级等信息。需注册账号、创建应用并授权。请求需签名认证,QPS限10次,建议缓存更新周期≥24小时。
400 2
|
3月前
|
JSON 监控 API
小红书笔记评论API:一键获取分层评论与用户互动数据
小红书笔记评论API可获取指定笔记的评论详情,包括内容、点赞数、评论者信息等,支持分页与身份认证,返回JSON格式数据,适用于舆情监控、用户行为分析等场景。
|
4月前
|
供应链 监控 安全
1688商品详情API接口实战指南:合规获取数据,驱动B2B业务增长
1688商品详情API(alibaba.product.get)是合规获取B2B商品数据的核心工具,支持全维度信息调用,助力企业实现智能选品、供应链优化与市场洞察,推动数字化转型。
|
3月前
|
数据采集 JSON API
微店API使用指南:高效获取商品列表数据
本文介绍如何使用Python爬虫调用微店item_search接口,根据关键词搜索商品并获取商品列表数据,涵盖请求方式、JSON数据解析、分页参数设置及筛选排序功能,适用于电商数据分析与竞品研究。
|
3月前
|
JSON API 数据格式
淘宝拍立淘按图搜索API系列,json数据返回
淘宝拍立淘按图搜索API系列通过图像识别技术实现商品搜索功能,调用后返回的JSON数据包含商品标题、图片链接、价格、销量、相似度评分等核心字段,支持分页和详细商品信息展示。以下是该API接口返回的JSON数据示例及详细解析:
|
3月前
|
JSON 算法 API
Python采集淘宝商品评论API接口及JSON数据返回全程指南
Python采集淘宝商品评论API接口及JSON数据返回全程指南
|
3月前
|
自然语言处理 算法 数据可视化
看球总刷比分?好奇数据哪来的?你该认识一下「体育API」了
体育API是赛事数据的“幕后搬运工”,实时同步比分、赛程、球员统计等信息,支撑各类应用提供精准推送、深度分析与互动体验,让观赛更智能高效。
447 150
|
3月前
|
JSON API 数据安全/隐私保护
Python采集淘宝拍立淘按图搜索API接口及JSON数据返回全流程指南
通过以上流程,可实现淘宝拍立淘按图搜索的完整调用链路,并获取结构化的JSON商品数据,支撑电商比价、智能推荐等业务场景。
|
4月前
|
JSON 前端开发 API
如何调用体育数据足篮接口API
本文介绍如何调用体育数据API:首先选择可靠服务商并注册获取密钥,接着阅读文档了解基础URL、端点、参数及请求头,然后使用Python等语言发送请求、解析JSON数据,最后将数据应用于Web、App或分析场景,同时注意密钥安全、速率限制与错误处理。
567 152