天气网站JS代码逻辑分离咨询:如何划分代码至对应文件?
代码分离方案:按职责拆分模块
核心思路是单一职责原则,每个文件只负责一类功能,避免逻辑混杂。以下是具体拆分方式:
1. 数据模型:weather.model.js
专门定义天气数据的结构,封装数据属性,让数据操作更规范。
export default class Weather { constructor(name, temp, feels, humidity, wind) { this.name = name; this.temp = temp; this.feels = feels; this.humidity = humidity; this.wind = wind; } }
2. API服务:weather.service.js
专注处理和天气API的交互逻辑,和UI、数据模型解耦,方便后续修改API地址、密钥或请求方式。
import Weather from './weather.model.js'; export const getWeather = async (city) => { const apiKey = "000"; const url = `000`; // 替换为你的实际API地址 const response = await fetch(`${url}`); const data = await response.json(); console.log(data); return new Weather(data.name, data.main.temp, data.main.feels_like, data.main.humidity, data.wind.speed); };
3. UI渲染:weather.ui.js
负责所有DOM相关操作,包括创建搜索栏、渲染天气卡片,和数据请求逻辑分离,方便后续修改页面结构。
import createHTMLElement from "./element-helper.js"; import { getWeather } from './weather.service.js'; export const displayCard = async () => { const search = createHTMLElement("div", "search"); const searchBar = createHTMLElement("input", "search-bar"); searchBar.type = "text"; searchBar.placeholder = "Sök på ort..."; const searchButton = createHTMLElement("button"); const searchIcon = createHTMLElement("svg"); searchIcon.innerHTML = ` <svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" height="1.5rem" width="1.5rem" xmlns="http://www.w3.org/2000/svg"><path d="M19.023,16.977c-0.513-0.488-1.004-0.997-1.367-1.384c-0.372-0.378-0.596-0.653-0.596-0.653l-2.8-1.337 C15.34,12.37,16,10.763,16,9c0-3.859-3.14-7-7-7S2,5.141,2,9s3.14,7,7,7c1.763,0,3.37-0.66,4.603-1.739l1.337,2.8 c0,0,0.275,0.224,0.653,0.596c0.387,0.363,0.896,0.854,1.384,1.367c0.494,0.506,0.988,1.012,1.358,1.392 c0.362,0.388,0.604,0.646,0.604,0.646l2.121-2.121c0,0-0.258-0.242-0.646-0.604C20.035,17.965,19.529,17.471,19.023,16.977z M9,14 c-2.757,0-5-2.243-5-5s2.243-5,5-5s5,2.243,5,5S11.757,14,9,14z"></path></svg> `; searchButton.appendChild(searchIcon); search.appendChild(searchBar); search.appendChild(searchButton); document.querySelector("#card").appendChild(search); const weatherKeyword = await getWeather("stockholm"); displayWeatherOverview(weatherKeyword); }; export const displayWeatherOverview = (weather) => { const overview = createHTMLElement("div", "weather loading"); const overviewContainer = createHTMLElement("div", "overview"); const day = createHTMLElement("h2", "day", "Idag"); const city = createHTMLElement("h2", "city", weather.name); const temp = createHTMLElement("h2", "temp", `${weather.temp}°C`); const humidity = createHTMLElement("h2", "humidity", `Luftfuktighet: ${weather.humidity}%`); const wind = createHTMLElement("h2", "wind", `Vindhastighet: ${weather.wind} m/s`); overviewContainer.appendChild(day); overviewContainer.appendChild(city); overviewContainer.appendChild(temp); overviewContainer.appendChild(humidity); overviewContainer.appendChild(wind); overview.appendChild(overviewContainer); document.querySelector("#card").appendChild(overview); };
4. 入口文件:app.js
作为应用的启动点,只负责导入必要模块并初始化,逻辑极简。
import { displayCard } from './weather.ui.js'; displayCard();
拆分后的优势
- 维护成本降低:修改API密钥只动
weather.service.js,调整页面布局只改weather.ui.js - 复用性提升:Weather类和getWeather方法可以被其他组件直接调用
- 测试更简单:每个模块可单独测试,比如API请求测试无需依赖DOM
内容的提问来源于stack exchange,提问作者Computervlog
相关产品推荐
相关产品推荐

