📝 个人简介
⭐ 个人主页:我是段段🙋
🍊 博客领域:编程基础、前端💻
🍅 写作风格:干货!干货!都是干货!
🍑 精选专栏:Vue
🛸 支持段段:点赞👍、收藏⭐、留言💬
在浏览的时候看到两个有意思的小demo,自己动手写了写,具体如下
一、获取笑话
随机获取笑话的接口
- 请求地址:https://autumnfish.cn/api/joke
- 请求方式:get
- 请求参数:无参数
- 相应内容:一条随机笑话
DOM结构比较简单了
<div id="app">
<div class="title font-coloe">{{ title }}</div>
<div class="btn" @click="onGetJokes">获取笑话</div>
<div class="result font-coloe">{{ result }}</div>
</div>
js代码如下
<script>
const { log } = console
let vm = new Vue({
el: '#app',
data: {
title: '嘻哈小笑话',
result: ''
},
methods: {
onGetJoke() {
// 使用Promise将异步操作转化为同步操作
return new Promise((resolve, reject) => {
axios({
methos: 'get',
url: `https://autumnfish.cn/api/joke`
}).then(res => {
resolve(res.data)
}).catch(err => { })
})
},
async onGetJokes() {
this.result = await this.onGetJoke()
}
},
async mounted() {
this.result = await this.onGetJoke()
}
})
</script>
在调用接口的时候使用了Promise
,这样可以将异步操作
转化为同步操作
;因为axios回调函数中的this已经改变,无法访问到data中的数据,如果想要访问data中的数据,可以通过在还没有使用axios时,使用一个变量将this存储起来
实现的效果图如下
完整的代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 注意js文件路径 -->
<script src="../../js/vue.js"></script>
<script src="../../js/axios.js"></script>
<title>小笑话</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
width: 100%;
height: 100vh;
background-color: #D0D0D0;
}
#app {
width: 700px;
height: 500px;
border: 1px solid #D0D0D0;
border-radius: 15px 15px;
box-shadow: 0px 0px 15px pink;
background-color: #FFF;
text-align: center;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.font-coloe {
background: linear-gradient(to right, red, blue);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.title {
width: 600px;
height: 100px;
line-height: 100px;
text-align: center;
font-size: 40px;
font-weight: bold;
letter-spacing: 10px;
font-family: '仿宋';
position: absolute;
top: 10%;
left: 50%;
transform: translate(-50%, -50%);
}
.btn {
margin: 90px 0 40px;
display: inline-block;
width: 100px;
height: 40px;
line-height: 40px;
border-radius: 4px 4px;
cursor: pointer;
background: rgba(78, 110, 242, 1);
color: #FFF;
}
.btn:hover{
background: rgba(78, 110, 242, .8);
}
.result{
cursor: default;
padding: 0 60px;
line-height: 26px;
letter-spacing: 2px;
}
</style>
</head>
<body>
<div id="app">
<div class="title font-coloe">{{ title }}</div>
<div class="btn" @click="onGetJokes">获取笑话</div>
<div class="result font-coloe">{{ result }}</div>
</div>
<script>
const { log } = console
let vm = new Vue({
el: '#app',
data: {
title: '嘻哈小笑话',
result: ''
},
methods: {
onGetJoke() {
return new Promise((resolve, reject) => {
axios({
methos: 'get',
url: `https://autumnfish.cn/api/joke`
}).then(res => {
resolve(res.data)
}).catch(err => { })
})
},
async onGetJokes() {
this.result = await this.onGetJoke()
}
},
async mounted() {
this.result = await this.onGetJoke()
}
})
</script>
</body>
</html>
二、查询天气
获取天气接口
- 请求地址:http://wthrcdn.etouch.cn/weather_mini
- 请求方法:get
- 请求参数:city(需要查询的城市名称)
- 响应内容:天气信息
需求:
1、输入框支持输入城市名称回车查询功能
2、输入框支持输入城市名称搜索查询功能
3、点击热门城市指直接查询功能
4、输入框无内容是默认获取城市数据功能(默认城市以“北京”为例)
5、查询结构无数据时,显示“暂无天气数据”提示信息
DOM相对也是比较简单的
<div id="app">
<div class="title font-coloe">{{ title }}</div>
<div class="wrap">
<div class="search">
<input type="text" v-model="keyword" placeholder="请输入地名进行查找" @keyup.enter="onGetSearch">
<span @click="onGetSelect">查找</span>
</div>
<div class="city">
<span v-for="(item, index) in cityList" :key="index" @click="onGetCity(item)">
{{ item }}
</span>
</div>
<div class="coming">
<div v-if="result.city" class="content">
<div v-for="(item, index) in result.forecast" :key="index" class="content-detail"
:class="{ 'not-line': index == result.forecast.length - 1 }">
<p>{{ item.type }}</p>
<p>{{ item.low + ' ~ ' + item.high }}</p>
<p>{{ item.fengxiang + ' ' + item.fengli.match(reg)[0] }}</p>
<p>{{ item.date }}</p>
</div>
</div>
<div v-else class="not-weather font-coloe">
暂无天气数据
</div>
</div>
<div class="yesterday">
<div class="past-times">
<span>昨日天气:</span>
{{ result.yesterday ? `${result.yesterday.low} ~
${result.yesterday.high},${result.yesterday.type},${result.yesterday.fx}
${result.yesterday.fl.match(reg)[0]}` : '暂无天气数据'}}
</div>
<div class="cozy-tips">
<span class="tips">温馨提示:</span>{{ result.city ? result.ganmao : '暂无天气数据'}}
</div>
<DIV class="now-city">当前城市:{{ city }}</DIV>
</div>
</div>
</div>
js代码结构如下
<s// 页面加载完成获取数据ipt>
const { log } = console
let vm = new Vue({
el: '#app',
data: {
title: '嘻哈查天气',
keyword: '',
reg: /[0-9][\u4e00-\u9fa5]/g, // 正则过滤风力信息
cityList: ['台州', '民权', '无锡', '开封'], // 热门城市
city: '北京', // 默认城市
result: {} // 请求结果
},
methods: {
onGetWeather(city) {
// 使用prmise将异步操作转化为同步操作
return new Promise((resolve, reject) => {
axios({
method: 'get',
url: `http://wthrcdn.etouch.cn/weather_mini?city=${city}`
}).then(res => {
resolve(res.data)
}).catch(err => {})
})
},
// 点击热门城市获取数据
async onGetCity(val) {
this.keyword = this.city = val
let res = await this.onGetWeather(val)
this.onPublic(res)
},
// 点击查找按钮获取数据
async onGetSelect() {
if (this.keyword.length > 0) {
this.city = this.keyword
let res = await this.onGetWeather(this.keyword)
this.onPublic(res)
}
},
// 按回车时获取数据
async onGetSearch() {
if (this.keyword.length > 0) {
this.city = this.keyword
let res = await this.onGetWeather(this.keyword)
this.onPublic(res)
}
},
onPublic(res) {
this.result = res.desc === 'OK' ? res.data : {}
}
},
async mounted() {
// 页面加载完成获取数据
let res = await this.onGetWeather(this.city)
this.onPublic(res)
},
watch: {
// 监听输入框的变化
async keyword(val) {
if (val.length == 0) {
this.city = '北京' // 当输入框为空时,默认城市设置为北京
let res = await this.onGetWeather(this.city)
this.onPublic(res)
}
}
}
})
</script>
实现效果图如下,默认城市
当无城市数据信息时,如下
完整的代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>查看天气</title>
<!-- 注意js文件路径 -->
<script src="../../js/vue.js"></script>
<script src="../../js/axios.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
body {
width: 100%;
height: 100vh;
background-color: #D0D0D0;
}
#app {
cursor: default;
width: 1000px;
height: 600px;
border: 1px solid #D0D0D0;
border-radius: 15px 15px;
box-shadow: 0px 0px 15px pink;
background-color: #FFF;
position: absolute;
top: 45%;
left: 50%;
transform: translate(-50%, -50%);
}
.font-coloe {
background: linear-gradient(to right, red, blue);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.title {
width: 1000px;
height: 100px;
line-height: 100px;
text-align: center;
font-size: 40px;
font-weight: bold;
letter-spacing: 10px;
font-family: '仿宋';
position: absolute;
top: 10%;
left: 50%;
transform: translate(-50%, -50%);
}
.wrap {
width: 1000px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
flex-direction: column;
}
.search {
width: 100%;
height: 85px;
line-height: 130px;
padding: 40px 0 0 8%;
box-sizing: border-box;
}
input[type="text"] {
float: left;
width: 80%;
height: 40px;
font-size: 14px;
padding: 0 10px;
border: 1px solid #C4C7CE;
border-right: none;
border-radius: 8px 0 0 8px;
box-sizing: border-box;
}
input[type="text"]:focus {
outline: none;
border: 1px solid #4E6EF2;
border-right: none;
}
input[type="text"]::placeholder {
color: rgba(0, 0, 0, .3);
}
.search span {
float: left;
height: 40px;
width: 12%;
line-height: 40px;
cursor: pointer;
text-align: center;
letter-spacing: 6px;
background-color: #4E6EF2;
border-radius: 0 8px 8px 0;
border: 1px solid #4E6EF2;
border-left: none;
color: #FFF;
box-sizing: border-box;
}
.city {
width: 100%;
height: 22px;
line-height: 22px;
padding-left: 9%;
cursor: pointer;
box-sizing: border-box;
}
.city span {
margin-right: 8px;
text-decoration: underline;
}
.city span:hover {
color: #4E6EF2;
}
.coming {
width: 100%;
height: 240px;
position: relative;
}
.content {
display: flex;
height: 180px;
padding-top: 30px;
}
.content-detail {
width: 25%;
height: 100%;
text-align: center;
border-right: 1px solid gray;
color: rgba(170, 170, 170, .8);
}
.content-detail p:first-child {
color: rgba(240, 166, 101, .8);
font-size: 30px;
margin-bottom: 22px;
}
.content-detail p:nth-child(2) {
color: rgba(246, 163, 84, .8);
margin-bottom: 22px;
}
.content-detail p:nth-child(3) {
margin-bottom: 22px;
}
.not-line {
border-right: none;
}
.not-weather {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-weight: bold;
font-size: 30px;
letter-spacing: 2px;
}
.yesterday {
width: 100%;
height: 120px;
text-align: center;
font-size: 20px;
}
.cozy-tips {
color: rgba(240, 166, 101, .8);
margin-bottom: 10px;
font-weight: bold;
}
.past-times {
color: rgba(0, 0, 0, .4);
margin: 10px 0;
}
.tips {
color: rgba(0, 0, 0, .7);
}
.now-city {
font-size: 14px;
color: rgba(0, 0, 0, .4);
;
}
</style>
</head>
<body>
<div id="app">
<div class="title font-coloe">{{ title }}</div>
<div class="wrap">
<div class="search">
<input type="text" v-model="keyword" placeholder="请输入地名进行查找" @keyup.enter="onGetSearch">
<span @click="onGetSelect">查找</span>
</div>
<div class="city">
<span v-for="(item, index) in cityList" :key="index" @click="onGetCity(item)">
{{ item }}
</span>
</div>
<div class="coming">
<div v-if="result.city" class="content">
<div v-for="(item, index) in result.forecast" :key="index" class="content-detail"
:class="{ 'not-line': index == result.forecast.length - 1 }">
<p>{{ item.type }}</p>
<p>{{ item.low + ' ~ ' + item.high }}</p>
<p>{{ item.fengxiang + ' ' + item.fengli.match(reg)[0] }}</p>
<p>{{ item.date }}</p>
</div>
</div>
<div v-else class="not-weather font-coloe">
暂无天气数据
</div>
</div>
<div class="yesterday">
<div class="past-times">
<span>昨日天气:</span>
{{ result.yesterday ? `${result.yesterday.low} ~
${result.yesterday.high},${result.yesterday.type},${result.yesterday.fx}
${result.yesterday.fl.match(reg)[0]}` : '暂无天气数据'}}
</div>
<div class="cozy-tips">
<span class="tips">温馨提示:</span>{{ result.city ? result.ganmao : '暂无天气数据'}}
</div>
<DIV class="now-city">当前城市:{{ city }}</DIV>
</div>
</div>
</div>
<script>
const { log } = console
let vm = new Vue({
el: '#app',
data: {
title: '嘻哈查天气',
keyword: '',
reg: /[0-9][\u4e00-\u9fa5]/g,
cityList: ['台州', '民权', '无锡', '开封'],
city: '北京',
result: {}
},
methods: {
onGetWeather(city) {
// 使用prmise将异步操作转化为同步操作
return new Promise((resolve, reject) => {
axios({
method: 'get',
url: `http://wthrcdn.etouch.cn/weather_mini?city=${city}`
}).then(res => {
resolve(res.data)
}).catch(err => {})
})
},
async onGetCity(val) {
this.keyword = this.city = val
let res = await this.onGetWeather(val)
this.onPublic(res)
},
async onGetSelect() {
if (this.keyword.length > 0) {
this.city = this.keyword
let res = await this.onGetWeather(this.keyword)
this.onPublic(res)
}
},
async onGetSearch() {
if (this.keyword.length > 0) {
this.city = this.keyword
let res = await this.onGetWeather(this.keyword)
this.onPublic(res)
}
},
onPublic(res) {
this.result = res.desc === 'OK' ? res.data : {}
}
},
async mounted() {
let res = await this.onGetWeather(this.city)
this.onPublic(res)
},
watch: {
async keyword(val) {
if (val.length == 0) {
this.city = '北京'
let res = await this.onGetWeather(this.city)
this.onPublic(res)
}
}
}
})
</script>
</body>
</html>
以上就是两个小案例,对axios结合Promise以及Vue进行了简单的应用~~