likes
comments
collection
share

豆包Marscode体验官:搭建自己的实时天气网站,以后出门再也不会忘带伞!

作者站长头像
站长
· 阅读数 31

前言

简单介绍 豆包Marscode

豆包Marscode其实主要分为两个东西,一个是编程助手,另一个是集成了多种开发环境的IDE。

编程助手

就是一个可以在vscode或其他IDE上使用的轻量级插件,安装既可用,十分方便。

豆包Marscode体验官:搭建自己的实时天气网站,以后出门再也不会忘带伞! 不仅仅是简单的回答问题,还能解释、注释代码和生成单测!

豆包Marscode体验官:搭建自己的实时天气网站,以后出门再也不会忘带伞!

在线IDE

豆包Marscode体验官:搭建自己的实时天气网站,以后出门再也不会忘带伞! 豆包MarsCode IDE 是一个在线编译器,内部集成了各种环境,可以直接生成模板,这就意味着只要有网络,不管是什么设备都能coding,十分的便捷!

环境创建与配置

因为我们要开发的是一个VUE项目,所以直接用豆包MarsCode IDE 创建一个VUE项目

豆包Marscode体验官:搭建自己的实时天气网站,以后出门再也不会忘带伞!

进入生成的项目模板后,在命令行输入 npm create vue@latest 开始初始化项目

豆包Marscode体验官:搭建自己的实时天气网站,以后出门再也不会忘带伞!

再安装依赖 npm i

项目初始化后把豆包模板自带的文件删了

豆包Marscode体验官:搭建自己的实时天气网站,以后出门再也不会忘带伞!

配置 main.js


// 引入

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'



const app = createApp(App)

app.use(router)


app.mount('#app')

然后再去配置路由 index.js

import { createRouter, createWebHistory } from 'vue-router'


const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path:'/',
      component: () => import('@/views/index.vue')
    }
  ]
})

export default router

然后在vies目录下创建一个index.vue这将会是这个小demo的主要视图

点击右侧即可唤起豆包MarsCode编程助手

豆包Marscode体验官:搭建自己的实时天气网站,以后出门再也不会忘带伞! 模板什么的直接用编程助手生成即可😎

再在命令行输入npm run dev ,如过在右侧出现了 Webview 显示无误,则说明环境配置好了。

豆包Marscode体验官:搭建自己的实时天气网站,以后出门再也不会忘带伞!

然后再将原来的所有css样式消除, 在assets文件夹下新建一个reset.css文件,并粘贴这段,这样原本的一些样式就被消除了。

/* http://meyerweb.com/eric/tools/css/reset/ 
   v2.0 | 20110126
   License: none (public domain)
*/

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 100%;
	font: inherit;
	vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
	display: block;
}
body {
	line-height: 1;
}
ol, ul {
	list-style: none;
}
blockquote, q {
	quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
	content: '';
	content: none;
}
table {
	border-collapse: collapse;
	border-spacing: 0;
}

紧接着,项目正式开始了。

项目搭建

首先分析一下,我们要搭建的是一个实时天气的网站,不仅仅是要用文本数据去展示天气数据,还要用一些图像例如折线图去展示一下气温变化,这个项目中我们使用的是Apache ECharts,更深入的使用可以参考快速上手 - 使用手册 - Apache ECharts。而且我们需要的数据得通过调用一些平台接口去获取,这里我们以高德平台为例,介于该平台的api文档写得简洁。如果想要深入学习可以参考 概述-Web服务 API | 高德地图API (amap.com)

安装Echarts

首先通过 npm 安装Echarts:

npm install echarts

index.vue 中引入

import * as echarts from 'echarts';

引入高德API

首先得去官网获取API的KEY安全密钥创建应用和 Key-Web服务 API | 高德地图API (amap.com),可以查看详细教程。

然后在 index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vite App</title>
    <script type="text/javascript">
      window._AMapSecurityConfig = {
        securityJsCode: "      ",
      };
    </script>
    <script
      type="text/javascript"
      src="https://webapi.amap.com/maps?v=2.0&key=      "
    ></script>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>

把自己申请的API的keysecurityJsCode 填进去

安装Vant

首先,通过npm安装Vant:

npm install vant
npm install @vant/area-data

引入和使用Vant组件

在项目的入口文件 src/main.js 中引入Vant组件和样式:

main.js


// 引入

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import '@/assets/reset.css'

import { Button } from 'vant';
import 'vant/lib/index.css';  // 通用的样式

import { Area,ActionSheet  } from 'vant';



const app = createApp(App)

app.use(router)
app.use(Area);
app.use(ActionSheet);

app.mount('#app')

在这里,van-action-sheet 组件用于显示一个底部弹出的选择框,van-area 组件用于选择城市。

基础模板

首先,我们来看 index.vue 中的HTML模板部分。这部分主要定义了页面的布局和展示结构。

<template>
    <div class="container">
        <div class="nav">
            <div class="time">{{ now }}</div>
            <div class="city" @click="state.show = true">切换城市</div>
        </div>
        <div class="city-info">
            <p class="city">{{ state.city }}</p>
            <p class="weather">{{ state.today.weather }}</p>
            <h2 class="temp">
                <em>{{ state.today.temperature }}</em>℃
            </h2>
            <div class="detail">
                <span>风力: {{ state.today.windPower }}级</span> |
                <span>风向: {{ state.today.windDirection }}风</span> |
                <span>空气湿度: {{ state.today.humidity }}%</span>
            </div>
        </div>
        <div class="future" v-if="state.future.length">
            <div class="group">
                明天:
                <span class="tm">白天:{{ state.future[1].dayTemp }}℃ {{ state.future[1].dayWeather }}
                    {{ state.future[1].dayWindDir }}风 {{ state.future[1].dayWindPower }}级</span>
                <span class="tm">夜间:{{ state.future[1].nightTemp }}℃ {{ state.future[1].nightWeather }}
                    {{ state.future[1].nightWindDir }}风 {{ state.future[1].nightWindPower }}级</span>
            </div>
            <div class="group">
                后天:
                <span class="tm">白天:{{ state.future[2].dayTemp }}℃ {{ state.future[2].dayWeather }}
                    {{ state.future[2].dayWindDir }}风 {{ state.future[2].dayWindPower }}级</span>
                <span class="tm">夜间:{{ state.future[2].nightTemp }}℃ {{ state.future[2].nightWeather }}
                    {{ state.future[2].nightWindDir }}风 {{ state.future[2].nightWindPower }}级</span>
            </div>
            <div class="echarts-wrap" ref="echartsWrap"></div>
        </div>
        <van-action-sheet v-model:show="state.show">
            <div class="content">
                <van-area title="地区" :area-list="areaList" :columns-num="2" @confirm="selectCity"
                    @cancel="state.show = false" />
            </div>
        </van-action-sheet>
    </div>
</template>

首先我们的布局是 上、中、下布局。

最上面是一个导航栏 (nav) :

  • 显示当前时间 ({{ now }})。

  • 提供一个按钮用于切换城市。

中间是城市信息 (city-info) :

  • 显示当前城市名 ({{ state.city }})。

  • 显示当前天气 ({{ state.today.weather }})。

  • 显示当前温度 ({{ state.today.temperature }})。

  • 显示风力、风向和空气湿度等详细信息。

然后是一个未来天气 (future) :

  • 显示未来几天的天气预报。

  • 使用 v-if 指令在 state.future 有数据时显示此部分。

  • 包含未来几天天气的详细信息。

  • 显示一个用于展示折线图的容器 (.echarts-wrap)。

在导航栏上右侧有一个切换城市的按钮,点击会展开选择城市的操作表 (van-action-sheet) 使用 Vant 的 ActionSheet 组件来实现选择城市的功能。 其中 van-area 组件用于选择地区。

js部分

首先是初始化和状态管理
<script setup>
import { onBeforeMount, reactive, ref, nextTick } from 'vue';
import { areaList } from '@vant/area-data';
import * as echarts from 'echarts';

let now = ref('00:00:00')
setInterval(() => {
    now.value = new Date().toLocaleTimeString()
}, 1000);

const state = reactive({
    city: '',
    today: {},
    show: false,
    future: []
})

使用 refsetInterval 每秒更新一次 now 的值,以显示当前时间。

使用 reactive 创建一个 state 对象,包含城市名 (city)、今日天气 (today)、显示切换城市组件的状态 (show) 和未来天气 (future)。

然后则是获取当前城市并获取天气信息
AMap.plugin('AMap.CitySearch', function () {
    var citySearch = new AMap.CitySearch()
    citySearch.getLocalCity(function (status, result) {
        if (status === 'complete' && result.info === 'OK') {
            state.city = result.city
            getWeather(result.city)
        }
    })
})

这里我们使用了 AMap.CitySearch 获取当前城市。 在回调函数中,将获取到的城市名赋值给 state.city,并调用 getWeather 函数获取该城市的天气信息。

获取天气信息
const getWeather = (city) => {
    AMap.plugin("AMap.Weather", function () {
        var weather = new AMap.Weather();
        weather.getLive(city, function (err, data) {
            state.today = data
        });
        weather.getForecast(city, function (err, data) {
            state.future = data.forecasts;
            nextTick(() => {
                initEcharts(data.forecasts.map(item => item.dayTemp));
            });
        });
    });
}

实时天气信息: 使用 AMap.Weather 插件的 getLive 方法获取实时天气信息,并将数据赋值给 state.today

天气预报:使用 AMap.Weather 插件的 getForecast 方法获取未来几天的天气预报,并将数据赋值给 state.future

值得注意的是使用 nextTick 确保DOM更新完成后再初始化Echarts图表,保证内部的逻辑会在页面渲染完毕后执行。

接着去是去实现切换城市功能
const selectCity = ({ selectedOptions }) => {
    state.city = selectedOptions[1].text;
    getWeather(selectedOptions[1].text);
    state.show = false;
}

当用户在 van-area 组件中选择城市时,将选中的城市赋值给 state.city。 调用 getWeather 函数获取新城市的天气信息。 将 state.show 设置为 false,关闭 ActionSheet

最后则是去完善折线图
const echartsWrap = ref(null);

const initEcharts = (arr) => {
    let chart = echarts.init(echartsWrap.value);
    chart.setOption({
        title: {
            text: '未来几天气温变化'
        },
        tooltip: {},
        xAxis: {
            type: 'category',
            data: ['今天', '明天', '后天', '大后天']
        },
        yAxis: {},
        series: [
            {
                name: '温度',
                type: 'line',
                data: arr
            }
        ]
    });
}

Echarts选项详解

  • title: 设置图表的标题。
  • tooltip: 配置提示框。
  • xAxis: 配置X轴,type: 'category' 表示类别轴。
  • yAxis: 配置Y轴。
  • series: 设置数据系列,type: 'line' 表示折线图,data 是数据数组。

我们通过 获取 echartsWrap DOM 元素,并初始化Echarts实例。 设置图表选项,包括标题、提示框、X轴、Y轴和数据系列。 注意 arr 参数传递的是未来几天的温度数据。

以下是 index.vue的详细代码

<template>
    <div class="container">
        <div class="nav">
            <div class="time">{{ now }}</div>
            <div class="city" @click="state.show = true">切换城市</div>
        </div>
        <div class="city-info">
            <p class="city">{{ state.city }}</p>
            <p class="weather">{{ state.today.weather }}</p>
            <h2 class="temp">
                <em>{{ state.today.temperature }}</em>℃
            </h2>
            <div class="detail">
                <span>风力: {{ state.today.windPower }}级</span> |
                <span>风向: {{ state.today.windDirection }}风</span> |
                <span>空气湿度: {{ state.today.humidity }}%</span>
            </div>
        </div>
        <div class="future" v-if="state.future.length">
            <div class="group">
                明天:
                <span class="tm">白天:{{ state.future[1].dayTemp }}℃ {{ state.future[1].dayWeather }}
                    {{ state.future[1].dayWindDir }}风 {{ state.future[1].dayWindPower }}级</span>
                <span class="tm">夜间:{{ state.future[1].nightTemp }}℃ {{ state.future[1].nightWeather }}
                    {{ state.future[1].nightWindDir }}风 {{ state.future[1].nightWindPower }}级</span>
            </div>
            <div class="group">
                后天:
                <span class="tm">白天:{{ state.future[2].dayTemp }}℃ {{ state.future[2].dayWeather }}
                    {{ state.future[2].dayWindDir }}风 {{ state.future[2].dayWindPower }}级</span>
                <span class="tm">夜间:{{ state.future[2].nightTemp }}℃ {{ state.future[2].nightWeather }}
                    {{ state.future[2].nightWindDir }}风 {{ state.future[2].nightWindPower }}级</span>
            </div>

            <div class="echarts-wrap" ref="echartsWrap"></div>
        </div>



        <van-action-sheet v-model:show="state.show">
            <div class="content">
                <van-area title="地区" :area-list="areaList" :columns-num="2" @confirm="selectCity"
                    @cancel="state.show = false" />
            </div>
        </van-action-sheet>
    </div>
</template>

<script setup>
import { onBeforeMount, onMounted, reactive, ref, nextTick } from 'vue';
import { areaList } from '@vant/area-data';
import * as echarts from 'echarts';



let now = ref('00:00:00')
setInterval(() => {
    now.value = new Date().toLocaleTimeString()
}, 1000);

const state = reactive({
    city: '',
    today: {},
    show: false,
    future: []
})

AMap.plugin('AMap.CitySearch', function () {
    var citySearch = new AMap.CitySearch()
    citySearch.getLocalCity(function (status, result) {
        if (status === 'complete' && result.info === 'OK') {
            // 查询成功,result即为当前所在城市信息
            // console.log(result);
            state.city = result.city
            getWeather(result.city)
        }
    })
})


const getWeather = (city) => {
    //加载天气查询插件
    AMap.plugin("AMap.Weather", function () {
        //创建天气查询实例
        var weather = new AMap.Weather();
        //执行实时天气信息查询
        weather.getLive(city, function (err, data) {
            // console.log(err, data);
            state.today = data
        });
        weather.getForecast(city, function (err, data) {
            console.log(err, data);
            state.future = data.forecasts
            nextTick(() => {  //保证内部的逻辑会在页面渲染完毕后执行
                initEcharts(data.forecasts.map(item => item.dayTemp))
            })

        });
    });
}

const selectCity = ({ selectedOptions }) => {
    console.log(selectedOptions[1].text)
    state.city = selectedOptions[1].text
    getWeather(selectedOptions[1].text)
    state.show = false
}

const echartsWrap = ref(null)
const initEcharts = (arr) => {
    let abc = echarts.init(echartsWrap.value)
    abc.setOption({
        title: {
            text: ''
        },
        tooltip: {},

        xAxis: {
            type: 'category',
            data: ['今天', '明天', '后天', '大后天']
        },
        yAxis: {},
        series: [
            {
                name: '温度',
                type: 'line',
                data: arr
            }
        ]
    })
}


//   onMounted(() => {
//     initEcharts();
//   })

onBeforeMount(() => {
    console.log('挂载前');
})




</script>

<style lang="css" scoped>
.container {
    min-height: 100vh;
    background: #000;
    opacity: 0.7;
    color: #fff;
}

.nav {
    display: flex;
    justify-content: space-between;
    padding: 20px;
}

.city-info {
    text-align: center;
}

p {
    margin-top: 10px;
}

.temp {
    font-size: 26px;
    margin: 10px 0;
}

.temp em {
    font-size: 34px;
}

.future {
    margin-top: 30px;
    padding: 0 10px;
}

.group {
    height: 44px;
    line-height: 44px;
    background-color: rgba(255, 255, 255, 0.3);
    font-size: 13px;
    padding: 0 10px;
    margin-bottom: 10px;
    border-radius: 5px;
}

.echarts-wrap {
    width: 100%;
    height: 50vh;
}
</style>

这便是成果!

豆包Marscode体验官:搭建自己的实时天气网站,以后出门再也不会忘带伞!

总结

通过豆包Marscode IDE 和 豆包Marscode 编程助手,我们完成了一个可以实时查看天气的小项目。通过完成这个项目,我发现了一些关于豆包的小缺陷。在IDE中创建的VUE模板默认为TS的,这对于不熟悉TS的创建环境会有点麻烦,而且在AI编程助手中,会出现联系不了上下文的问题,而且每天代码补全是有限定额度的。但是作为刚一款发布的豆包Marscode 产品,还是有很大的潜力的,其IDE 提供了方便的编程环境,编程助手也比较可靠。愿我们以后能使用上更好用国产的AI!

转载自:https://juejin.cn/post/7395862170562150450
评论
请登录