axios结合Promise及Vue整合小demo

📝 个人简介

⭐ 个人主页:我是段段🙋‍
🍊 博客领域:编程基础、前端💻
🍅 写作风格:干货!干货!都是干货!
🍑 精选专栏: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进行了简单的应用~~

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是段段

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值