尝试调用API写个vue的查询天气WEB

news/2024/11/20 23:32:19/

写在前面:

心血来潮想用vue写个项目,也方便看看自己最近的代码学习效率和成果 ;

不写不知道,一写还确实踩了不少坑.....

文中需要重要注意的地方都用红色粗体标注了,代码部分的话就用注释就行了。写这个文章,以供以后再遇到相同问题,可以省不少事...也尽可能帮助到和我一样的vue小白们。

-----------------------------------------------2023/4/21----------------------------------------------------

简单写个页面,可以查询各地的天气那种;大概就是让用户输入城市,点击个按钮可以返回值;

先把数值写死,然后整个简单的样式;大概实现这个效果:

<template><input type="text"  /><button>查询</button><h1>您查询的城市是:</h1><table><tr><th>日期</th><th>天气情况</th><th>温度</th></tr></table>
</template>

其实设计H5的总体页面就是这么简单;但是之后就需要优化优化了,

接下来,我们尝试给button添加一个点击事件。

  <button @click="searchEvent">查询</button>

 添加了@click,就肯定需要有触发的事件,

<script>
export default{methods: {searchEvent() {console.log("我被点击了")},},
}
</script>

大概就是这样;其实我做完这一步之后设计了一个优化。因为毕竟是vue,vue的优点是组件代码分离,可以实现多处调用,但是就因为我这个优化...导致我后来频繁bug:不是数据传不到子页面,就是数据实时传值的过程把变量各种修改…

这样,咱先把某个组件拆出来。这里我把<table></table>组件整个搬了出来,并且创建了子组件weather.vue用来存储后期查询到的某城市的天气数据。大概是...这样,

 OK。麻烦的来了(对于萌新来说)。实时监听数据并传值...

vue中怎么get到用户输入的数据呢?我一开始使用的是v-model。对没错,v-model....

我直接监听了用户的实时传值,但事实证明,这东西还真不是自己想用就能用的。

=======================分割线============================

因为这篇文章是在项目敲完之后创作的,所以我这里先说云端数据获取的部分,其实上述说的v-model传值是完全可以使用的,而且能如期获得用户输入的字符;但是却不符合我们目前的项目要求。

我们为button的点击事件绑定触发事件:

searchEvent() {axios.get("http://apis.juhe.cn/simpleWeather/query?city=" +this.city +"&key=594cf24c8a7b4c4d56de72d5296b85df").then(res=>{this.res = res.data.result.future});},

其实不得不承认,代码里的每句话都要了老命。但是单就这么看好像是不是并没什么?

axios.get()方法我就不说了,这里没有涉及到一些加密传值;但是就是vue中的这个

.then(res=>{this.res = res.data.result.future});

这里的this.res是外部的全局变量!res.data.result.future是通过axios.get获取的response,

这个的前提是,外部data里已经创建了一个res的空串:

data() {return {city: "",res:[]};},

好了。重点来了,

我App.vue的父组件中获得了天气的数据,交给了res;(假设我用v-model的方法获取到了用户输入的城市)并交给了city;那我之后,该咋把值交给weather.vue呢?

 Components && Props

大体解释一下这俩,

我在父组件中的export default中定义需要把数据交给谁?对,weather.vue;于是

export default{components: { weather },
}

好了,现在weather.vue可以访问父组件App.vue中所有定义的data{}值了,那之后需要用到哪个值,就在他组件后面是使用就ok了。比如我要用到data{number:1}中的number的值,我就在后面定义

<template><weather :number="number"></weather>
</template>

:number是将number的值传给了子组件,子组件使用{{ number }}调用;

父元素传值,子元素自然要接收,这里就用到了Props

 /* 获取父组件传值 */props:{city:{type:String,},res:{type:Object,}}

这里不做赘述。就是将两个变量重新定义,并声明类型。

可以了,App.vue大概是如此

<script setup>
import weather from "./components/weather.vue";
import axios from "axios";</script><script>
export default {components: { weather },data() {return {city: "",res:[]};},methods: {searchEvent() {axios.get("http://apis.juhe.cn/simpleWeather/query?city=" +this.city +"&key=594cf24c8a7b4c4d56de72d5296b85df").then(res=>{this.res = res.data.result.future});},},
};
</script><template><!-- v-model 实现用户和页面的数据交互,实现把用户输入的数据和vue值更新 --><!-- v-bind 实现数值在父组件和子组件的交互,或者相同页面不同组件中的交互 --><input type="text" v-model="city" /><button @click="searchEvent">查询</button><!-- weather绑定 :city,向子组件传city的值 并且子组件中用props{city}获取传值--><weather :city="city" :res="res"></weather>
</template>

子组件weather.vue:

<template><h1>您查询的城市是:{{ city }}</h1><table class="gridtable" ><tr><th>日期</th><th>天气情况</th><th>温度</th></tr><tr><td>{{res[0].date}}</td><td>{{res[0].weather}}</td><td>{{res[0].temperature}}</td></tr><tr><td>{{res[1].date}}</td><td>{{res[1].weather}}</td><td>{{res[1].temperature}}</td></tr></table>
</template><script>
export default{/* 获取父组件传值 */props:{city:{type:String,},res:{type:Object,}}
}</script>

这里我省略了一些表格的样式。看一下最终的效果

是不是感觉项目做到这已经完成了?

nonono....

你看到的他执行效果是这样的,但实际上,他是这样的.........

实例视频

怎么解决这个问题?那就涉及到v-model这个命令了。v-bind和v-model虽然可以绑定数据,但是一旦绑定,就是响应式数据。用户输一个字,那边就显示一个字。所以就是不管用户点不点查询,另一头都会把用户输入的一个字一个字都展示出来。于是....v-model绑定数据传值,按理来说型不太通。

那该怎么办?

还有一个方法——{{ ref }}

这是一个很神奇的包。大致是这么用的

<template><!-- v-model 实现用户和页面的数据交互,实现把用户输入的数据和vue值更新 --><!-- v-bind 实现数值在父组件和子组件的交互,或者相同页面不同组件中的交互 --><input type="text" ref="searchCity" /><button @click="searchEvent">查询</button><!-- weather绑定 :city,向子组件传city的值 并且子组件中用props{city}获取传值--><weather :city="city" :res="res"></weather>
</template>

看出哪里变化了没?

输入框<input />的绑定由v-model变成了ref="searchCity" 

<script>
export default {methods: {searchEvent() {const theCity = this.$refs.searchCity.value;axios.get("http://apis.juhe.cn/simpleWeather/query?city=" +theCity +"&key=594cf24c8a7b4c4d56de72d5296b85df").then(res=>{this.res = res.data.result.future,this.city = theCity});},},
};
</script>

而在JavaScript标签下,我们定义了一个变量theCity,用来存储用户点击按钮之后,input框中的value值。this.$refs.searchCity即是我们所定位的那个输入框;之后,我们把theCity的值再传给全局变量city,搞定!经过测试,用户输入完城市后,点击查询,之后数据变化。

==============  =====  又一个优化  = ====  ==========================

经过测试可以发现,我们每一次调用天气的API接口,每次的get请求都会返回5个数组。那与其使用{{ res[0].data }}的方式获取数值,为什么不能通过遍历,来将所get到的数组依次展示出来呢?

答案肯定是ok的,v-for 就可以很轻松的解决这个问题;

<template><h1>您查询的城市是:{{ city }}</h1><table class="gridtable" v-if="city"><tr v-if="city"><th>日期</th><th>天气情况</th><th>温度</th></tr><tr v-for="items in res"><td>{{ items.date }}</td><td>{{ items.weather }}</td><td>{{ items.temperature }}</td></tr></table>
</template>

==============  =====  一个问题和一个建议  = ====  ==========================

ERROR :Acess to XMLHttpRequest at 'http://apis.juhe.cn/simpleWeather/query?city=%E4%B8%B4%E6%B2%82&key=594cf24c8a7b4c4d56de72d5296b85df' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

 这个问题大致是因为你localhost的地址和你发起get的地址有冲突。目前的解决方式是下载Chorme里的一个模块并开启它

 之后报错就解决了。

AD:本项目其实还有很多的优化没有完成。比如input中用户如果输入空值、非法字符,应弹出警告框;(或是当我们res.result获取不到有关数值时,便报错通知用户可能其输入的内容非法)。我们或许也可以使用下拉框,或是横向城市选择器,调用全国城市名称来让用户自行选取。其他的地方,比如多加些功能啊,风向什么的,都是API接口提供的,无非是table中再新加一行或一列而已。项目的主体思想还是弄清vue中常用的v-bind、v-model,甚至是v-for、v-if 。这是vue语法的核心,还需要多加练习。但是为了防止新旧技术更替,企业的新技术未迭代,在弄懂新技术的同时,也不要忘了这些指令,在H5和JavaScript中,是如何实现的。


http://www.ppmy.cn/news/708563.html

相关文章

082-天气预报之城市代码 ID

天气预报之城市代码 ID 调用气象局接口获取天气时需要使用到城市代码ID&#xff0c;城市代码ID 获取方式&#xff1a; 城市代码ID 下面将上述地址下载的文件内容整理后的结果&#xff1a; 由于某些名称可能重复&#xff0c;但他们确实存在于不同的区域下&#xff0c;如&#x…

andorid调用天气预报

andorid调用天气预报 今天闲来想做个android的天气预报&#xff0c;百度之&#xff0c;谷歌的天气预报非常的多&#xff0c;下载demo,发现不能访问&#xff0c;至于 原因&#xff0c;你懂得。期间走了很多弯路&#xff0c;为了节省大家时间&#xff0c;就把遇到的坎一一写上。 …

Python爬虫编程思想(156):使用Scrapy抓取天气预报数据

并不是所有的数据都在网页代码中,对于通过AJAX方式更新数据的Web页面,通常会使用Web API的方式从服务端获取数据,然后通过JavaScript代码将这些数据显示在Web页面的组件中。在这种情况下,无法通过抓取HTML代码的方式获取这些数据,而要通过直接访问这些Web API的方式从服务…

天气通遇见乐视TV,神奇化反在哪里

跟着移动互联网快速发展的脚步&#xff0c;人们越来越习惯于用手机来了解实时更新的天气信息。近日&#xff0c;Analysys易观发布了 《中国天气应用市场季度监测报告2016第3季度》显示&#xff0c;天气通已连续多个季度位居中国天气应用活跃用户覆盖率亚军。 作为最受欢迎的贴心…

tableau商业分析一点通 数据下载_干货分享:谁说设计师不会做数据分析

上上周手术一结束&#xff0c;拖着疲惫的身体回伦敦&#xff0c;开学&#xff0c;搬家&#xff0c;整理学生公寓房间&#xff0c;全部一个人来&#xff0c;半条命基本去了。不过我还是熬过来了。这段时间都没有文章更新。先和大家说声抱歉。从明天起&#xff0c;我就开始恢复更…

驾考一点通维语版_驾考宝典维语版下载

1 社会车辆距离消防栓或者消防队(站)门前30米以内的路段不能停车。查看本题分析 2 点火开关在LOCK位置拔出钥匙转向盘会锁住。查看本题分析 3 打开后雾灯开关&#xff0c;(如图所示)亮起。查看本题分析 4 变更车道时只需开启转向灯&#xff0c;并迅速转向驶入相应的车道&#x…

新浪《天气通HD》 首页的 Demo

今天看到了新浪《天气通HD》 app 感觉还可以&#xff0c;就学习山寨了一下&#xff0c;做了一个demo&#xff0c;这个demo 主要是那个游标指示器有点奇葩&#xff0c;别的地方都很简单。 主要功能看代码吧 源代码下载地址 效果图&#xff1a; 效果图&#xff1a; 效果图&#…

显示农历天气时钟小部件下载_iOS 14 Beta 2更新内容整理:图标调整、增加新的小部件及其他...

苹果在今天凌晨通过开发者通道推出了iOS 14第二个测试版本更新&#xff0c;如果你想从系统更新日志了解到这次的更新内容&#xff0c;大概你只能看到bug修复和性能提升之类的话了&#xff0c;一句在软件产品更新当中非常经典的描述啊。在本次的更新当中&#xff0c;苹果其实对不…