背景图像不会使用 tailwind 和 nextjs 动态变化

BackgroundImage is not changing dynamically using tailwind & nextjs

简介

我正在使用 nextJS 和 TailwindCSS 创建一个天气应用程序。我几乎已经创建了整个应用程序,但最后却遇到了这个 UI 问题。

我想要什么?

我想根据天气描述动态更改背景图像(例如:晴空、阴霾、雨、雪)。

问题

为此,我编写了一个函数 changeBackground("rain"),但它不起作用。我已经在 tailwind.config.js 文件中定义了所有图像路径。调试后,我发现该函数给出了正确的答案(在控制台中打印出答案)但我的 className="bg-${changeBackground("rain")}" 不工作。下面是这个

的代码

tailwind.config.js

module.exports = {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {
      backgroundImage: {
        'day_sun' : "url('../public/back_big.jpg')",
        'day_rain' : "url('../public/dayrain.jpg')",
        'day_cloud' : "url('../public/daycloud2.jpg')",
        'day_snow' : "url('../public/daysnow.jpg')",
        'night_sun' : "url('../public/nightsunny.jpg')",
        'night_snow' : "url('../public/nightsnow.jpg')",
        'night_thunder' : "url('../public/nightthunder.jpg')",
      }
    },
  },
  plugins: [],
}

index.js

import Head from "next/head";
import { useEffect } from "react";
import Image from "next/image";
import { useState } from "react";
import Today_highlight from "./components/Today_highlight";
import Weather_Today from "./components/Weather_Today";
import Weather_week from "./components/Weather_week";
import searchimageurl from "../public/search.gif";
import Typed from "react-typed";


const Home = () => {
  //console.log("res1 = ", results1);
  //const router = useRouter();
  const [city, setCity] = useState("");
  const [data, setData] = useState({ day: {}, week: {} });

  


  //for the first time
  useEffect(() => {
    (async () => {
      const url = `https://api.openweathermap.org/data/2.5/weather?q=Delhi&appid=${process.env.NEXT_PUBLIC_API_KEY_1}`;
      const res1 = await fetch(url);
      const response1 = await res1.json();
      //console.log("res1 = ",response1);

      //api-2
      const url1 = `https://api.openweathermap.org/data/2.5/forecast/daily?q=Delhi&appid=${process.env.NEXT_PUBLIC_API_KEY_1}`;
      const res2 = await fetch(url1);
      const response2 = await res2.json();
      //console.log("res2 = ",response2);

      setData({ day: response1, week: response2 });
    })();
  }, []);


  const handleChange = (e) => {
    setCity(e.target.value);
    //console.log(city)
  };

  const handleSubmit = async (e) => {
    //console.log("%c ClickSubmit","font-size:12px; color:green; padding:10px;")
    //console.log("city = ", city);
    //router.push(`/?term=${city}`);

    const url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${process.env.NEXT_PUBLIC_API_KEY_1}`;
    const res = await fetch(url);
    const data1 = await res.json();
    //console.log(data1);

    //api-2
    const url1 = `https://api.openweathermap.org/data/2.5/forecast/daily?q=${city}&appid=${process.env.NEXT_PUBLIC_API_KEY_1}`;
    const res1 = await fetch(url1);
    const data2 = await res1.json();
    //console.log(data2);
    setData({ day: data1, week: data2 });
  };

  //console.log(data);
  const weather = data?.day?.weather;
  
  //console.log("we - ",weather[0]?.description)
  //fn to determine the bg
  function changebackground(des) {
    //console.log("des =",des)

    if (des === "sky is clear" || des === "clear sky") return 'day_sun';
    else if (des === "few clouds") return 'day_cloud';
    else if (des === "scattered clouds") return 'day_cloud';
    else if (des === "broken clouds" || des === "overcast clouds")
      return 'day_cloud';
    else if (
      des === "shower rain" ||
      des === "light rain" ||
      des === "drizzle" ||
      des === "moderate rain"
    )
      return 'day_rain';
    else if (
      des === "rain" ||
      des === "very heavy rain" ||
      des === "heavy intensity rain" ||
      des === "extreme rain" ||
      des === "heavy intensity shower rain"
    )
      return 'day_rain';
    else if (
      des === "thunderstorm" ||
      des === "light thunderstorm" ||
      des === "heavy thunderstorm" ||
      des === "ragged thunderstorm" ||
      des === "thunderstorm with rain"
    )
      return 'night_thunder';
    else if (des === "snow" || des === "light snow" || des === "heavy snow")
      return 'day_snow';
    else if (
      des === "light rain and snow" ||
      des === "rain and snow" ||
      des === "light shower snow"
    )
      return 'night_snow';
    else if (
      des === "mist" ||
      des === "fog" ||
      des === "smoke" ||
      des === "haze"
    )
      return 'day_rain';
    else return 'day_sun';
  }

  console.log(changebackground("snow"),"-> picture")

  return (
    <>
      <Head>
        <title>Weather-Lytics</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <div  className={`lg:bg-${changebackground("snow")} bg-no-repeat`} >
        {/* input */}
        <div className="p-3 xl:p-5 flex flex-row justify-center items-center space-x-2 xl:space-x-5 ">
          <div className=" border-2 border-stone-700 rounded-full ">
            <Typed
              strings={[
                "Search for Delhi",
                "Search for Tokyo",
                "Search for California",
                "Search for Ulaanbaatar",
              ]}
              typeSpeed={30}
              backSpeed={50}
              attr="placeholder"
              loop
            >
              <input
                className="w-full rounded-full p-2 xl:p-4 pl-5 xl:pl-10 text-base xl:text-3xl text-blue-800 font-bold active:rounded-full "
                value={city}
                type="text"
                onChange={handleChange}
              />
            </Typed>
          </div>
          <div>
            <button
              className="p-1 m-auto p-auto"
              onClick={() => handleSubmit()}
            >
              <div className="w-14 h-14 xl:w-16 xl:h-16 p-2 rounded-full bg-pink-400 border-2 hover:bg-pink-600 border-white">
                <Image
                  src={searchimageurl}
                  layout="responsive"
                  alt="Search_icon"
                  className=" rounded-full p-3 bg-blue-900 "
                />
              </div>
            </button>
          </div>
        </div>

        <div className="min-h-full  flex flex-col lg:flex-row justify-evenly ">
          <div className="bg-white/50 xl:bg-white/70  w-full h-full lg:w-1/4 lg:h-full xl:m-4 rounded-lg xl:rounded-3xl">
            <Weather_Today results={data.day} />
          </div>
          <div className=" lg:h-full">
            <div className="min-h-full flex flex-col">
              <div className="bg-white/50 xl:bg-white/70 xl:m-4 xl:rounded-3xl">
                <Today_highlight results={data.day} />
              </div>
              <div className="bg-white/50 xl:bg-white/70 xl:m-4 xl:rounded-3xl">
                <Weather_week results1={data.week} />
              </div>
            </div>
          </div>
        </div>
      </div>
    </>
  );
};


export default Home;

请帮我做一下???

TailwindCSS 不允许您动态生成 classes。因此,当您使用以下内容生成 class…

`lg:bg-${changebackground("snow")}`

…TailwindCSS 不会将其作为有效的 TailwindCSS class 选择,因此不会产生必要的 CSS.

相反,您必须在源代码中包含 class 的全名。我建议使用一个对象来快速获得正确的 class:

const backgroundClasses = {
  day_snow: 'lg:bg-day_snow',
  day_sun: 'lg:bg-day_sun',
  // ...
}

然后使用您的函数从该对象中查找正确的 class。

通过这种方式,每个 class 的整个字符串都在您的源代码中,因此 TailwindCSS 将知道生成适用的 CSS.

阅读更多:https://tailwindcss.com/docs/content-configuration#class-detection-in-depth

TailwindCss 不允许动态构造 class 名称。 而是使用

 if (des === "sky is clear" || des === "clear sky") return 'bg-day_sun';
    else if (des === "few clouds") return 'bg-day_cloud';
    else if (des === "scattered clouds") return 'bg-day_cloud';
    else if (des === "broken clouds" || des === "overcast clouds")
      return 'bg-day_cloud';
    else if (
      des === "shower rain" ||
      des === "light rain" ||
      des === "drizzle" ||
      des === "moderate rain"
    )
      return 'bg-day_rain';
    else if (
      des === "rain" ||
      des === "very heavy rain" ||
      des === "heavy intensity rain" ||
      des === "extreme rain" ||
      des === "heavy intensity shower rain"
    )
      return 'bg-day_rain';
    else if (
      des === "thunderstorm" ||
      des === "light thunderstorm" ||
      des === "heavy thunderstorm" ||
      des === "ragged thunderstorm" ||
      des === "thunderstorm with rain"
    )
      return 'night_thunder';
    else if (des === "snow" || des === "light snow" || des === "heavy snow")
      return 'bg-day_snow';
    else if (
      des === "light rain and snow" ||
      des === "rain and snow" ||
      des === "light shower snow"
    )
      return 'bg-night_snow';
    else if (
      des === "mist" ||
      des === "fog" ||
      des === "smoke" ||
      des === "haze"
    )
      return 'bg-day_rain';
    else return 'day_sun';
  }

并在您的 CSR 中使用

<div  className={`lg:${changebackground("snow")} bg-no-repeat`} >