Используйте модуль изображения в slotProps

Мой проект использует интерфейс Tailwind и Material.

Я пытаюсь добавить фоновое изображение в компонент аватара. Я могу сделать это правильно, используя slotProps компонента Avatar, добавив полный URL-адрес фонового изображения в bg-[url("...")], но я не могу использовать этот URL-адрес с модулем изображения, импортированным в React.

Я собрал простой пример на codeandbox.

import droidbug from "./droidbug.png";
import background from "./background.jpg";

export default function App() {
  return (
    <div className = "App">
      <div className = "flex items-center">
        Background: <img src = {background} width = "50px" />
      </div>
      <AvatarGroup>
        <Avatar
          src = {droidbug}
          alt = "droid"
          slotProps = {{
            img: {
              className:
                "bg-[url(https://uploads.codesandbox.io/uploads/user/5933fafc-2c28-466e-be86-43329df70aa1/V8Vl-001_simple_starry_profile_skin_by_volpheus_dg0v53a-fullview.jpg)]",
            },
          }}
        />
        <Avatar
          src = {droidbug}
          alt = "droid"
          slotProps = {{
            img: {
              className: "bg-[url({background})]",
            },
          }}
        />
      </AvatarGroup>
    </div>
  );
}

Первый Avatar правильно отображает фоновое изображение, второй нет, и при проверке он показывает class= bg-[url({background})]", что явно неверно.

Изменение на className: "bg-[url("+{background}+")]", устанавливает значение class = "bg-[url([object Object])]", что ненамного лучше.

🤔 А знаете ли вы, что...
С JavaScript можно создавать расширения для различных платформ, таких как Adobe Acrobat и Microsoft Office.


1
50
2

Ответы:

Решено

Tailwind может распознавать только полные непрерывные имена классов, определенные во время компиляции. Для динамически определяемых ресурсов их следует указывать напрямую с помощью style.

import "./styles.css";
import { Avatar, AvatarGroup } from "@mui/material";

import droidbug from "./droidbug.png";
import background from "./background.jpg";

export default function App() {
  return (
    <div className = "App">
      <div className = "flex items-center">
        Background: <img src = {background} width = "50px" />
      </div>
      <AvatarGroup>
        <Avatar
          src = {droidbug}
          alt = "droid"
          slotProps = {{
            img: {
              className:
                "bg-[url(https://uploads.codesandbox.io/uploads/user/5933fafc-2c28-466e-be86-43329df70aa1/V8Vl-001_simple_starry_profile_skin_by_volpheus_dg0v53a-fullview.jpg)]",
            },
          }}
        />
        <Avatar
          src = {droidbug}
          alt = "droid"
          slotProps = {{
            img: {
              style: {
                background: `url(${background})`,
              },
            },
          }}
        />
      </AvatarGroup>
    </div>
  );
}

Проблема

Вы закодировали строковый литерал "bg-[url({background})]".

"bg-[url("+{background}+")]" также терпит неудачу, потому что он использует конкатенацию строк, которая неявно вызывает метод .toString ссылки на объект, в результате чего получается строковый литерал "bg-[url([object Object])]".

const background = "../path/to/resource.jpg";
console.info("bg-[url(${background})]");    // "bg-[url(${background})]"
console.info("bg-[url("+{background}+")]"); // "bg-[url([object Object])]"

Решение

Вместо этого используйте литерал шаблона , чтобы ввести URL-путь ресурса background.

const background = "../path/to/resource.jpg";
console.info(`bg-[url(${background})]`); // "bg-[url(../path/to/resource.jpg)]"
<Avatar
  src = {droidbug}
  alt = "droid"
  slotProps = {{
    img: {
      className: `bg-[url(${background})]`,
    },
  }}
/>