vue2.0 插槽不是响应性的

news2024/11/23 13:04:43

请注意插槽不是响应性的。如果你需要一个组件可以在被传入的数据发生变化时重渲染,我们建议改变策略,依赖诸如 propsdata 等响应性实例选项。-- vm.$slots

问题描述

项目中自定了组件 widget,作为容器,其中 header 部分做了预置插槽 slot,用于信息的展示;在实际使用过程中,header 内容需要根据不同条件展示不同信息。至此,问题出现了~~~

期望效果,右侧 title 根据 ajax 返回结果,展示其中一种
在这里插入图片描述
实际效果,ajax 正常返回,但没有渲染成功
在这里插入图片描述
widget 代码

<template>
	<div	class="widget-container">
    <header v-if="titleSlots.length">
      <div v-for="(item, index) in titleSlots" :key="index">
        <slot :name="item"></slot>
      </div>
    </header>
    <main v-if="$slots.default">
      <slot></slot>
    </main>
    <footer v-if="$slots.footer">
      <slot name="footer"></slot>
    </footer>
  </div>
</template>
<script>
const TITLE_SLOTS_TYPES = ['title-left', 'title-center', 'title-right'] // title-slots类型
export default {
  name: 'widget',
	computed: {
    titleSlots () {
      return TITLE_SLOTS_TYPES.filter(name => this.$slots[name])
    }
  }
}
</script>

① slots 是动态渲染的;② titleSlots 值是由 vm.$slots 计算(computed)而来。

业务中使用代码

<template>
	<widget>
    <template slot="title-left">
      <span>任务名称:{{taskName}}</span>
		</template>
		<template slot="title-right">
    	<el-button v-if="condition1">开始报送</el-button>
			<el-button v-else-if="condition2">重新报送</el-button>
			<el-button v-else-if="condition3">报送中</el-button>
		</template>
  </widget>
</template>

condition 条件是通过异步 ajax 请求返回,初始状态slot为空;② 请求成功后,其中某一条件生效,但不展示!

问题拆解

将上述示例进行简化,以便剖解问题。

Test.vue

<template>
  <div>
  	<slot name="content" v-if="isShow"></slot>
  </div>
</template>
<script>
export default {
  name: 'test',
  computed: {
    isShow () {
      return !!this.$slots.content
    }
  },
  created () {
    console.log(this.$slots.content)
  }
}
</script>

App.vue

<template>
 <test ref="test">
   <template slot="content">
     <p v-if="count === 1">1</p>
     <p v-else-if="count === 2">2</p>
     <p v-else-if="count >= 3">3</p>
  	</template>
  </test>
	<button @click="getTestSlots">获取test组件slots</button>
</template>
<script>
import Test from './components/Test.vue'
export default {
  name: 'App',
  components: { Test },
  data () {
    return {
      count: 0
    }
  },
  methods: {
    getTestSlots () {
      console.log(this.$refs['test'].$slots)
    }
  },
  created () {
    // 模拟 ajax
    setTimeout(() => {
      this.count = 3
    }, 3000)
  }
}
</script>

【问题1】slot 内容为空,组件内部 vm.$slots 无法获取相应内容

如示例,在初始状态,任何一个 condition 都不成立,此时组件内部 vm.$slots 是获取不到相应 slot 的。

console.log(this.$refs['test'].$slots)  // getTestSlots App.vue 

结果:{}

console.log(this.$slots.content)	// created Test.vue

结果:undefined

【问题2】$slots 不具备响应性

如示例, 等待 3000 ms,此时 count 值变成了3,但 test 组件依然未渲染
在这里插入图片描述

console.log(this.$refs['test'].$slots)  // getTestSlots App.vue 

结果:{content: [VNode]}

isShow(Computed)未生效,但 vm. s l o t s 中是有值的,应征了官方 a p i 中提到的:“ ‘ v m . slots 中是有值的,应征了官方 api 中提到的:“`vm. slots中是有值的,应征了官方api中提到的:“‘vm.slots`不具备响应性!!”

问题解决

问题的核心:组件内依赖 $slots 来判断是否渲染相应的 slot 内容;而业务端调用时,初始时不存在,数据变化时,$slots 不具备响应性(computed也就不会生效),从而相应的 slot 也就无法显示。

【方案1】规避默认不存在 slot 的情况

初始时,让相应 slot 具备内容,组件中也就无需依赖 computed 。

App.vue

<test ref="test">
  <template slot="content">
		<div>
      <p v-if="count === 1">1</p>
      <p v-else-if="count === 2">2</p>
      <p v-else-if="count >= 3">3</p>
    </div>
  </template>
</test>

增加一层元素<div>,确保在自定义组件初始化过程中,即可获取 $slots

【方案2】规避到 “vm.$slots不具备响应性 “

改变策略,依赖 props 等响应性实例

App.vue

<test ref="test" :isShow="count > 0">
...
</test>

Test.vue

props: ['isShow']

【其他】相同父元素的子元素渲染错误

不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。

<p v-if="count === 1" key="1">1</p>
<p v-else-if="count === 2" key="2">2</p>
<p v-else-if="count >= 3" key="3">3</p>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/158369.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SCI投稿:MDPI旗下期刊Mathematics投稿经历

最近写了篇论文&#xff0c;由于国内期刊现状&#xff08;懂的都懂&#xff09;&#xff0c;打算投国外的期刊&#xff0c;看来看去选择投MDPI旗下的Mathematics。手稿经过一轮大修之后顺利收到了Accepted&#xff0c;过程还是比较顺利的&#xff0c;记录一下投稿过程。 论文撰…

Matlab实现的FEMIC的说明书

FEMIC程序是用来反演小回路频域电磁感应数据的。要启动代码,在Matlab命令窗口中输入start,然后点击“Enter”或“返回”按钮。然后会出现FEMIC的主界面,见图1。 它由几个输入区域组成,这几个区分别实现了:加载数据,反演过程控制和最终显示。 图1 主界面 下面对这些输入…

[oeasy]python0045_四种进制_binary_octal_decimal_hexadecimal

四种进制 回忆上次内容 上次研究了 通过 八进制数值 转义 \ooo把(ooo)8进制对应的ascii字符输出 转义序列 \n、\t 是 转义序列\xhh 也是 转义序列\ooo 还是 转义序列 现在 总共有 几种进制 了呢&#xff1f;&#x1f914; 先数一下 树 数树 树 就是这么多棵树 用八进制的…

Redis持久化Redis主从

Redis持久化 RDB持久化 RDB: Redis数据备份文件。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后&#xff0c;从磁盘读取快照文件&#xff0c;恢复数据。 主要流程 bgsave开始时会fork主进程得到子进程&#xff0c;子进程共享主进程的内存数据。完成f…

误删的文件不在回收站如何找回?分享一些恢复数据的教程

电脑清理的文件数据&#xff0c;一般都会经过回收站。如果想要恢复回来&#xff0c;可以直接打开电脑的回收站来寻找。可凡事都有万一&#xff0c;我们删除的文件不在回收站里面。这是什么原因&#xff1f;误删的文件不在回收站如何找回&#xff1f;今天就来分享如何恢复不在回…

git快速学习笔记

1.目标 了解Git基本概念能够概述git工作流程能够使用Git常用命令熟悉Git代码托管服务能够使用idea操作git 2.概述 2.1开发中的实际场景 场景一&#xff1a;备份 小明负责的模块就要完成了&#xff0c;就在即将Release之前的一瞬间&#xff0c;电脑突然蓝屏&#xff0c;硬盘光…

C语言进阶(6)——结构体

文章目录1.结构体的基础知识2.结构体的声明3.特殊的声明4.结构体的自引用6. 结构体的内存对齐7.修改默认对齐数8.结构体传参位段1、位段定义2. 位段的内存分配3.位段的跨平台问题4.位段的运用场景1.结构体的基础知识 结构是一些值的集合&#xff0c;这些值称为成员变量。结构的…

51单片机——LED基础

从小就对电器元件比较感兴趣吧&#xff0c;经常拿坏的电器里面的芯片拆下来玩&#xff0c;甚至那些没坏的电器&#xff0c;比如我家的电视&#xff0c;也会希望它能坏掉&#xff0c;我好去看看里面是什么样子的&#xff0c;为什么能播放节目……&#xff0c;所以我第一眼看到51…

阿里云-解决EDAS创建应用文件过大无法上传部署问题

文章目录1、背景2、问题具体描述3、解决方案3.1、 2种方案3.2 、OSS 简介3.3、 OSS 功能特性4、 OSS 实操4.1、 上传程序文件4.2、 创建应用1、背景 在一次使用阿里云-EDAS发布应用服务过程中出现EDAS 上传应用包过大无法上传现象。 2、问题具体描述 最近在使用阿里云-EDAS发…

1.1.2续 特殊二极管部分选型

目录 1.稳压管 2.发光二极管 4.光电二极管 5.整流二极管 1.稳压管 利用二极管的反向击穿特性制成的&#xff0c;在电路中其两端的电压保持基本不变&#xff0c;起到稳定电压的作用 Vz 稳定电压&#xff1a;反向击穿后稳定工作的电压 Iz 稳定电流&#xff1a;工作电压等于…

Java异常情况了解

作者&#xff1a;爱塔居的博客_CSDN博客-JavaSE,数据结构领域博主 专栏&#xff1a;JavaSE 作者介绍&#xff1a;大三学生&#xff0c;希望一起进步~ 文章目录 目录 文章目录 一、异常结构体系 二、异常分类 三、异常处理 3.1异常抛出 3.2 异常捕获 四.【面试题】 五、题目练习…

大数据必学Java基础(一百一十九):Maven仓库与JDK的配置

文章目录 Maven仓库与JDK的配置 一、Maven仓库 二、JDK的配置 Maven仓库与JDK的配置 一、Maven仓库 Maven仓库是基于简单文件系统存储的,集中化管理Java API资源(构件)的一个服务。 仓库中的任何一个构件都有其唯一的坐标,根据这个坐标可以定义其在仓库中的唯一存储路…

Linux:gcc工具

文章目录一.程序的翻译二.gcc工具的使用2.1gcc 文件名(直接编译)2.2gcc -o 自定义 原文件(自定义生成可执行程序名称)2.3./可执行文件2.4gcc -E(程序运行到预处理后结束)2.5gcc -S(程序运行到编译之后结束)2.6gcc -i(程序运行到汇编之后结束)2.7小结三.链接的过程3.1ldd命令3.2…

2023年最新谷歌Google帐号Gmail邮箱账号怎么注册成功的方法与教程?

因为工作、游戏或其他需求&#xff0c;有时需要使用谷歌Google帐号或Gmail邮箱账号。首先明确&#xff1a;谷歌google帐号不一定是Gmail邮箱帐号&#xff0c;但是Gmail邮箱账号一定是谷歌帐号。所以&#xff0c;大家注册Google谷歌帐号时默认为谷歌Gmail邮箱帐号就可以满足谷歌…

Linux基础命令,常用操作

Linux基础命令Linux的目录结构ls命令(list)隐藏文件、文件夹pwd命令(print work directory)cd命令(change directory)HOME目录相对路径、绝对路径特殊路径符mkdir命令(make directory)touch命令(touch)cat命令more命令cp命令mv命令rm命令(remove)which命令find命令grep命令wc命…

私有云建设,ALLINONE还是分层自主建设优化?

新钛云服已累计为您分享720篇技术干货私有云建设有两种思路&#xff0c;一种是使用整合解决方案&#xff0c;即ALLINONE的思路。一种是将私有云分层每层自主建设&#xff0c;使用不同的产品和解决方案分层优化组合使用。两种思路各有优缺点&#xff0c;适合不同的场景。一、ALL…

Mybatis-plus(上)

1.什么是mybatis-plus升级版的mybatis&#xff0c;目的是让mybatis更易于使用&#xff0c; 用官方的话说“为简化而生”官网&#xff1a;https://baomidou.com/初体验按照官网中的快速开始即可1.准备数据库脚本数据库 Schema 脚本如下&#xff1a; DROP TABLE IF EXISTS user; …

javaWeb RequestResponse

Request Request 继承体系 Tomcat解析请求数据&#xff0c;封装为request对象&#xff0c;并且创建request对象传递到service方法中 。Java提供了接口&#xff0c;tomcat的RequestFacade提供了实现。 Request 获取请求数据 请求数据分为3部分&#xff1a; 请求行&#xff…

一台手机即可完成 3D 建模,功能有多强大? #Luma AI

AIGC 的出现拓展了内容生产的诸多可能&#xff0c;借助 AI 技术来进行 3D 建模&#xff0c;可以节省不少的时间&#xff0c;市面上也出现了许多功能强大的 3D 建模工具。1 月 9 日&#xff0c;AppStore 上架了一款名为“Luma AI”的软件&#xff0c;能够将现实中的 2D 照片快速…

通过Terraform创建GCP Pubsub

1 简介 Terraform是管理许多平台的基础设施的工具&#xff0c;如AWS、GCP和Azure。这篇文章将讲解如何通过Terraform来管理GCP Pub/Sub。 创建GCP项目请参考&#xff1a;初始化一个GCP项目并用gcloud访问操作 2 Terraform创建Pub/Sub 2.1 下载Terraform插件 我们需要安装G…