Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >onMount被叫了两次

onMount被叫了两次
EN

Stack Overflow用户
提问于 2022-03-31 22:37:22
回答 1查看 1K关注 0票数 1

我有一个布局页面,每个组件都继承它。我的问题是对每个组件调用两次onMount函数。它产生了许多问题,因为我的onMount函数包含对API的调用。这意味着打给Api的电话翻了一番。很长一段时间以来,我都不知道为什么会这样。最近,我注意到布局组件有一个触发转换的包装器。当我移除转换时,onMount被按预期的方式调用了一次。另一方面,我不想失去过渡,因为页面看起来很糟糕。如何解决这个问题?

PageTransitions.svelte:

代码语言:javascript
运行
AI代码解释
复制
<script>
  import { fly } from "svelte/transition";
  export let refresh = "";
</script>

{#key refresh}
  <div in:fly={{ y: -50, duration: 250, delay: 300 }} out:fly={{ y: -50, duration: 250 }} class="flex flex-1">
    <slot>Zawartość</slot>
  </div>
{/key}

layout.svelte:

代码语言:javascript
运行
AI代码解释
复制
<script>
  import { googleMap } from "./../stores.js";
  import { page } from "$app/stores";
  import Footer from "$lib/Footer.svelte";
  import Header from "$lib/Header.svelte";
  import PageTransitions from "$lib/PageTransitions.svelte";
  import Notifications from "svelte-notifications";
  import "../app.css";
  import { GOOGLE_API_KEY } from "$lib/constants.js";
  import { setContext } from "svelte";
  import { writable } from "svelte/store";

  const url = `https://maps.googleapis.com/maps/api/js?key=${GOOGLE_API_KEY}&libraries=places,directions`;

  let isSideMenuOpen = setContext("isSideMenuOpen", writable(false));

  $: loaded = $googleMap.loaded;

  const onLoad = () => {
    $googleMap.loaded = true;
    console.log("Google Maps SDK loaded…", window.google);
  };
</script>

<svelte:head>
  {#if !loaded}
    <script
      src={url}
      type="application/javascript"
      defer
      async
      on:load={onLoad}></script>
  {/if}
</svelte:head>

<Notifications>
  <div
    class="h-screen flex flex-col bg-gray-50 dark:bg-gray-900"
    class:overflow-hidden={isSideMenuOpen}
  >
    <Header />

    <PageTransitions refresh={$page.path}>
      <slot>Strona</slot>
    </PageTransitions>

    <Footer />
  </div>
</Notifications>

modules.svelte (示例组件):

代码语言:javascript
运行
AI代码解释
复制
<script context="module">
  export const ssr = false;
  export const prerender = true;

  export async function load({ session }) {

    if (!session.authenticated) {
      return {
        status: 302,
        redirect: "/auth/login",
      };
    }
    return {
      props: {
        authenticated: session.authenticated,
        token: session.token,
        user: session.user,
      },
    };
  }
</script>

<script>
    import { slide } from 'svelte/transition';
  import GenericTable from "$lib/GenericTable.svelte";
  import { profile, modules } from "../../stores";
  import { getModuleDataURL, getModuleTypeDataURL, get, del } from "$lib/api";
  import GenericRow from "$lib/Rows/ModuleRow.svelte";
  import { onMount } from "svelte";
  import Loader from "$lib/Loader.svelte";
  import { getNotificationsContext } from "svelte-notifications";

  const { addNotification } = getNotificationsContext();

  let loading = false;

  export let authenticated;
  export let token;
  export let user;

  const siteHeader = "Moduły";
  const rootPath = "modules";

  let filters = {
    moduleType: null,
    imei: "",
    serialNumber: "",
    phoneNumber: "",
    isActive: null,
    desc: "",
    id: null,
  };

  const filtersChange = () => {
    let filteredItems = [...$modules.items];

    $modules.filters = false;
    if (
      filters.moduleType ||
      filters.id ||
      filters.desc.length > 2 ||
      filters.isActive !== null ||
      filters.imei.length > 2 ||
      filters.serialNumber.length > 2 ||
      filters.phoneNumber.length > 2
    ) {
      $modules.filters = true;
    }

    if (filters.moduleType) {
      filteredItems = filteredItems.filter(
        (item) => item.moduleType.id === filters.moduleType.value
      );
    }
    if (filters.isActive !== null) {
      filteredItems = filteredItems.filter(
        (item) => item.isActive === filters.isActive
      );
    }
    if (filters.imei.length > 2) {
      filteredItems = filteredItems.filter((item) =>
        item.imei.includes(filters.imei)
      );
    }
    if (filters.serialNumber.length > 2) {
      filteredItems = filteredItems.filter((item) =>
        item.serialNumber.includes(filters.serialNumber)
      );
    }
    if (filters.phoneNumber.length > 2) {
      filteredItems = filteredItems.filter((item) =>
        item.phoneNumber.includes(filters.phoneNumber)
      );
    }
    if (filters.desc.length > 2) {
      filteredItems = filteredItems.filter((item) =>
        item.desc ? item.desc.includes(filters.desc) : false
      );
    }
    if (filters.id === "DESC") {
      filteredItems.sort((a, b) => (a.id > b.id ? 1 : -1));
    } else if (filters.id === "ASC") {
      filteredItems.sort((a, b) => (a.id < b.id ? 1 : -1));
    }
    $modules.filteredModules = filteredItems;
  };

  const urlModuleType = getModuleTypeDataURL();
  const urlModuleData = getModuleDataURL();

  const deleteItem = async (id) => {
    loading = true;
    const url = getModuleDataURL() + "?id=" + id;
    try {
      const result = await del(url, token, false);
      if (result.status) {
        $modules.items = $modules.items.filter((item) => id !== item.id);
        $modules.filteredModules = $modules.filteredModules.filter(
          (item) => id !== item.id
        );
        addNotification({
          text: "Usunięto moduł o id - " + id,
          position: "bottom-right",
          type: "success",
          removeAfter: 4000,
        });
      } else throw result.message;
    } catch (err) {
      console.error(err);
      addNotification({
        text: err,
        position: "bottom-right",
        type: "danger",
        removeAfter: 4000,
      });
    }
    loading = false;
  };

  onMount(async () => {
    loading = true;
    $modules.filters = false;
    $modules.filteredGroups = [];
    try {
      const resultModules = await get(
        urlModuleData + "?$orderby=isActive desc,id",
        token
      );
      if (resultModules.data) $modules.items = resultModules.data.items;

      const resultModuleTypes = await get(urlModuleType, token);
      if (resultModuleTypes.data)
        $modules.moduleTypes = resultModuleTypes.data.items;
    } catch (err) {
      console.error(err);
      addNotification({
        text: "Podczas komunikacji z serwerem wystąpił błąd. Spróbuj raz jeszcze. Jeśli problem się powtórzy, skontaktuj się z administratorem aplikacji.",
        position: "bottom-right",
        type: "danger",
        removeAfter: 4000,
      });
    }
    loading = false;
  });

  let virtualListData = [];
  $: virtualListData = $modules.filters
    ? $modules.filteredModules
    : $modules.items;

  let moduleTypes = [];
  $: moduleTypes = $modules.moduleTypes.map((item) => ({
    value: item.id,
    label: item.type,
  }));

  const widths = ["5%", "15%", "10%", "10%", "15%", "15%", "20%", "10%"];

  let listTableHead = [];
  $: listTableHead = [
    {
      id: 1,
      name: "ID",
      filter: true,
      type: "id",
    },
    {
      id: 2,
      name: "IMEI",
      filter: true,
      label: "imei",
      type: "text",
      placeholder: "Wpisz minimum 3 znaki",
      onInput: filtersChange,
    },
    {
      id: 3,
      name: "Typ modułu",
      filter: true,
      label: "moduleTypes",
      type: "select",
      placeholder: "-",
      items: moduleTypes,
      select: (e) => {
        filters.moduleType = e.detail;
        filtersChange();
      },
      clear: () => {
        filters.moduleType = null;
        filtersChange();
      },
    },
    {
      id: 4,
      name: "Aktywność",
      filter: true,
      label: "isActive",
      type: "select",
      placeholder: "-",
      items: [
        { value: true, label: "Aktywny" },
        { value: false, label: "Nieaktywny" },
      ],
      select: (e) => {
        filters.isActive = e.detail.value;
        filtersChange();
      },
      clear: () => {
        filters.isActive = null;
        filtersChange();
      },
    },
    {
      id: 5,
      name: "Numer telefonu",
      filter: true,
      label: "phoneNumber",
      type: "text",
      placeholder: "Wpisz minimum 3 znaki",
      onInput: filtersChange,
    },
    {
      id: 6,
      name: "Numer seryjny",
      filter: true,
      label: "serialNumber",
      type: "text",
      placeholder: "Wpisz minimum 3 znaki",
      onInput: filtersChange,
    },
    {
      id: 7,
      name: "Opis",
      filter: true,
      label: "desc",
      type: "text",
      placeholder: "Wpisz minimum 3 znaki",
      onInput: filtersChange,
    },
    {
      id: 8,
      name: "Dodaj nowy moduł",
      type: "addNew",
    },
  ];
</script>

<main class="w-full flex flex-1 overflow-y-auto bg-red-100">
  <div class="p-2 overflow-y-auto flex flex-1">
    {#if loading}
      <Loader />
    {/if}
    <div
      transition:slide
      style="display:{loading ? 'none' : 'block'}"
      class="flex flex-col flex-1 items-center justify-center"
    >
      <GenericTable
        {siteHeader}
        {filtersChange}
        {deleteItem}
        {virtualListData}
        {widths}
        {listTableHead}
        {filters}
        {rootPath}
        {GenericRow}
      />
    </div>
  </div>
</main>

我试过的是:

  1. 我试图从PageTransitions组件中删除layout.svelte,它在onMount函数方面有帮助,但是页面看起来很糟糕。
  2. 我尝试将转换分别移动到每个组件,部分工作,但不是所有地方。
  3. 尝试将onMount函数内容移动到Load函数,但我无法编译

这一切为什么要发生?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-02 08:01:01

有一个相关的问题有文档化的这里 (没有解决方案)。

根本原因是时间问题。layout.sveltePageTransitions.svelte中更改<slot/>。这会导致新的插槽/页面加载甚至触发onMount。

新的页面也会在屏幕上显示几毫秒,因为还没有发生转换!

更改插槽后,Svelte将触发一个$page存储更新。在您的代码中,这将导致转换为update ({#key refresh}),从而再次加载<slot/>

如果不修改Svelte本身,就无法更改<slot/> exchange和$page存储集之间的时间安排。

此代码触发转换,并且只导致一个组件挂载。

layout.svelte:

代码语言:javascript
运行
AI代码解释
复制
<script context="module">
    export const load = async ({ url }) => ({ props: { refresh: url } });
</script>
<script>
    import { googleMap } from "./../stores.js";
    import Footer from "$lib/Footer.svelte";
    import Header from "$lib/Header.svelte";
    import PageTransitions from "$lib/PageTransitions.svelte";
    import Notifications from "svelte-notifications";
    import "../app.css";
    import { GOOGLE_API_KEY } from "$lib/constants.js";
    import { setContext } from "svelte";
    import { writable } from "svelte/store";

    export let refresh;
    const url = `https://maps.googleapis.com/maps/api/js?key=${GOOGLE_API_KEY}&libraries=places,directions`;

    let isSideMenuOpen = setContext("isSideMenuOpen", writable(false));

    $: loaded = $googleMap.loaded;

    const onLoad = () => {
      $googleMap.loaded = true;
      console.log("Google Maps SDK loaded…", window.google);
    };
  </script>

  <svelte:head>
    {#if !loaded}
      <script
        src={url}
        type="application/javascript"
        defer
        async
        on:load={onLoad}></script>
    {/if}
  </svelte:head>

  <Notifications>
    <div
      class="h-screen flex flex-col bg-gray-50 dark:bg-gray-900"
      class:overflow-hidden={isSideMenuOpen}
    >
      <Header />

      <PageTransitions {refresh}>
        <slot>Strona</slot>
      </PageTransitions>

      <Footer />
    </div>
  </Notifications>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71702763

复制
相关文章
保护版权,用 Python 为图片添加盲水印
如果你想保护自己的原创图片,那最好的方式就是为图片添加盲水印,盲水印就是图片有水印但人眼看不出来,需要通过程序才能提取水印,相当于隐形“盖章”,可以用在数据泄露溯源、版权保护等场景。今天分享如何用 Python 为图片添加盲水印。
somenzz
2021/10/08
4.3K0
如何在Linux中使用 seq 命令打印具有指定增量或格式的数字序列?
seq 命令是 sequence 的缩写,用于打印数字序列,数字可以是整数或实数(带小数点)。
网络技术联盟站
2022/04/12
1.6K0
如何在Linux中使用 seq 命令打印具有指定增量或格式的数字序列?
Python批量下载无版权图片
生活或者工作中,不管是写文章、公司 UI 交互图还是广告图等等都需要用到图片,图片的优点和重要性自不用说。
数据森麟
2019/09/27
2.4K0
各种途径的图片版权保护措施
  随着互联网应用的发展,图片素材的网络化和数字化成为了一种常态,这种现象也使得相应的版权问题应运而生,网络技术的快速发展对网络图片的版权保护产生了前所未有的影响。版权验证,交易和补救是在线图像版权保护的三个主要方面。
墨者安全科技
2019/08/15
2.5K0
各种途径的图片版权保护措施
用ASP.NET上传图片并生成带版权信息的缩略图
作者:活靶子      出处:AspxBoy.ComC#
Java架构师必看
2021/03/22
1.1K0
Python | 无版权图片素材下载
但在现在版权十分重视的时代,我们使用网络上的素材时,还得小心图片素材是否有版权,一不小心就侵权了。
用户6825444
2019/12/18
4.7K2
Python | 无版权图片素材下载
网络图片版权保护的主要问题
近段时间由人类历史上首张黑洞照片的发布而引发版权争议的话题愈演愈烈。自事情发生以来,关注图片版权的话题也持续升温,引起来各大媒体、群中和相关机构的引论。为了更好的规范图片版权问题,国家版权局也借此契机把图片版权纳入了“剑网2019”专项行动中。随着网络技术的迅猛发展,对图片的版权保护方面也带来了前所未有的冲击和挑战。在图片版权确权、交易这两个方面是图片保护的主要问题所在。
墨者安全科技
2019/07/29
2.3K0
网络图片版权保护的主要问题
那些好用的无版权免费图片网站
平常搜图片一般直接在谷歌搜,可能一不小心就侵权了,这里分享些好用的无版权免费图片网站。
苏生不惑
2020/05/20
10.9K1
JavaScript图片隐写术 – 图片加入看不见的版权文字
隐写术算是一种加密技术,权威的wiki说法是“隐写术是一门关于信息隐藏的技巧与科学,所谓信息隐藏指的是不让除预期的接收者之外的任何人知晓信息的传递事件或者信息的内容。”这看似高大上的定义,并不是近代新诞生的技术,早在13世纪末德国人Trithemius就写出了《隐写术》的著作,学过密码学的同学可能知道。好了,说了这么多,隐写术到底是什么技术,让我们看一个例子。
Javanx
2019/09/05
2.8K0
如何在你的文章中添加隐藏的版权信息
现在有4个中文汉字: 我是青南,首先介绍Python的 ord函数,它可以查询Unicode字符对应的Unicode码
青南
2019/03/18
1.7K0
如何在你的文章中添加隐藏的版权信息
6款无版权可商用的图片网站
今天给大家分享几个无版权可商用的图片网站,无论是网页设计、还是数字营销、商业海报制作等等都可以非常简单方便的查询到自己想要的图片。
网站小运营
2023/04/07
2K0
三个免费的无版权图片站
精挑细选的 https://www.pexels.com/ 海纳百川的https://pixabay.com/ 文艺小清新的 https://stocksnap.io/
zhaoolee
2019/11/21
2K0
三个免费的无版权图片站
【区块链实践】区块链+数字版权:“权利”的游戏
数字版权,一直是区块链落地的“香饽饽”。它有着天然的优势:原生就在线上,不存在线上线下自有闭环。
辉哥
2018/10/11
2.2K0
Python简单实现批量下载无版权图片
有时候我们有一些获取图片素材的需求,比如写博客或者公众号文章时,需要的插图和封面,当然这些图片必须是没有版权的免费图片,比较常用网站有pexels、pixabay等,今天再给大家介绍一个新的网站 :http://alana.io/。
吾非同
2020/10/23
1.8K0
Python简单实现批量下载无版权图片
Unsplash能找到很多免费无版权图片
https://unsplash.com/ 能找到很多免费无版权图片, 我从中下载了几张图, 用Keynote做了几张幻灯片
zhaoolee
2019/11/12
1.3K0
如何在 Eclipse 中更改注释块的 @author 版权信息?
我们在使用 IDE——Ecilpse 进行开发,需要注明版权信息的时候,如果不更改默认设置的话,在注释块 @author 的内容就是电脑系统默认的,例如下图所示。为了开发方便就需要进行修改。
白鹿第一帅
2021/03/02
4.8K0
如何在 Eclipse 中更改注释块的 @author 版权信息?
游戏直播乱象频出,版权保护毋庸置疑!
目前,中国游戏直播业已经告别了这一风口,但它处于蓬勃发展的势头当中,并拥有数量庞大的用户基础。游戏直播行业的兴起,促进了周边行业的融合,多元化了行业的收入渠道,形成了完整的供需产业链。这已成为文化和创造领域经济增长的重要点。
墨者安全科技
2019/09/30
4750
游戏直播乱象频出,版权保护毋庸置疑!
用 PyQt 打造具有专业外观的 GUI
如果您一直在创建表单以执行将数据输入数据库等操作,那么QFormLayout适合您。此类将小部件布置为两列布局。第一列通常显示描述预期输入的标签,第二列通常包含允许用户输入或编辑数据的输入小部件,例如QLineEdit,QComboBox或QSpinBox。
sergiojune
2021/07/19
2.9K0
用 PyQt 打造具有专业外观的 GUI
写一只具有识别能力的图片爬虫
在网上看到python做图像识别的相关文章后,真心感觉python的功能实在太强大,因此将这些文章总结一下,建立一下自己的知识体系。 当然了,图像识别这个话题作为计算机科学的一个分支,不可能就在本文简单几句就说清,所以本文只作基本算法的科普向。如有错误,请多包涵和多多指教。 本文参考文章和图片来源 wbj0110的文章 http://soledede.iteye.com/blog/1940910 赖勇浩的文章 http://blog.csdn.net/gzlaiyonghao/article/detai
机器学习AI算法工程
2018/03/13
2K0
写一只具有识别能力的图片爬虫
Fckeditor中使用图片上传
所需jar包为下图的5个jar包,其中第三个为Fckeditor的核心包,全名应该叫fckeditor-java-core-2.4.jar
Java架构师必看
2021/05/17
1.2K0
Fckeditor中使用图片上传

相似问题

狂热的游戏版权?

10

在付费游戏中使用无版权音乐

20

用棋盘游戏制作移动应用程序。侵犯版权?

30

游戏标题中的版权侵权

30

在电子游戏中使用旧飞机;版权?

20
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档