笔记
模拟掉线,让chrome浏览器断网。设置如下:

重要文件源码
components\Search.vue
<template>
    <!-- 头部搜索 -->
    <section class="jumbotron">
        <h3 class="jumbotron-heading">Search Github Users</h3>
        <div>
            <!-- 获取用户输入 -->
            <input type="text" placeholder="enter the name you search" v-model="keyWord"/> 
            <button @click="searchUsers">Search</button>
        </div>
    </section>
</template>
<script>
    //引入
    import axios from 'axios'
    export default {
        name:'SearchVue',
        data(){
            return {
                keyWord:''
            }
        },
        methods: {
            searchUsers(){
                //100
                //请求前更新List的数据
                //this.$bus.$emit('updateListData', false,true,'',[])
                //语义化:
                this.$bus.$emit('updateListData', {isFirst:false, isLoading:true, errMsg:'', users:[]})
                //注意: 为了让 ${this.keyWord} 起作用, 必须使用反引号 `,不能使用 单引号。
                //      反引号 `(模板字符串):支持通过 ${变量}插入动态值
                //      模板字符串。如果想把 this.keyWord 像模板一样解析,需要包裹 $(this.keyWord)
                //      地址里面带?参数,表示get请求的query参数。
                //      虽然该接口是免费的,但是不要请求太频繁,否则可能被认为你正在攻击github服务器而被屏蔽。
                let strUrl = `https://api.github.com/search/users?q=${this.keyWord}`
                console.log(strUrl)
                axios.get(strUrl).then( //两个回调:成功+失败
                    response => {
                        console.log('请求成功了', response.data.items)
                        //099
                        //this.$bus.$emit('getUsers', response.data.items)
                        //100
                        //this.$bus.$emit('updateListData', false,false, '', response.data.items)
                        //语义化:
                        //请求成功后,更新List的数据
                        this.$bus.$emit('updateListData', {isFirst:false, isLoading:false, errMsg:'', users:response.data.items})
                    },
                    error => {
                        console.log('请求失败了', error.message)
                        //请求失败后,更新List的数据
                        this.$bus.$emit('updateListData', {isFirst:false, isLoading:false, errMsg:error.message, users:[]})
                    }
                )
            }
        },
    }
</script>
<style>
</style>components\List.vue
<template>
    <!-- list区 -->
    <div class="row">
        <!-- 同一个网站上不允许有相同用户名 -->
        <div v-show="info.users.length" class="card" v-for="user in info.users" :key="user.login">
            <!-- 属性值 动态绑定 :属性名 -->
            <a :href="user.html_url" target="_blank">
            <img :src="user.avatar_url" style='width: 100px'/>
            </a>
            <!-- 标签体 插值语法-->
            <p class="card-text">{{user.login}}</p>
        </div>
        <!-- 展示欢迎词 -->
        <h1 v-show="info.isFirst">欢迎使用</h1>
        <!-- 展示加载中 -->
        <h1 v-show="info.isLoading">加载中 ...</h1>
        <!-- 展示错误信息 -->
        <h1 v-show="info.errMsg">{{ info.errMsg }}</h1>
    </div>  
</template>
<script>
    export default {
        name:'ListVue',
        //099
        data(){
            return{
                /*
                //100
                isFirst:true,
                isLoading:false,
                errMsg:'',
                //本例用户数据来源: 
                //  github.com 提供的免费get请求接口 https://api.github.com/search/users?q=xxx
                users:[] //值为数组
                */
               //再进行一次包装:
               info:{
                    isFirst:true,
                    isLoading:false,
                    errMsg:'',
                    users:[] //值为数组
               }
            }
        },
        mounted(){
            //099
            //第1步:全局事件总线绑定
            //this.$bus.$on('getUsers',(isFirst, isLoading, errMsg, users)=>{
            //this.$bus.$on('updateListData',(isFirst, isLoading, errMsg, users)=>{
            //尽可能参数要语义化,方便阅读: 调整为一个参数,别整一堆参数
            this.$bus.$on('updateListData',(dataObj)=>{
                console.log('我是List组件,收到数据:', dataObj.users)
                console.log(dataObj)
                /*this.users = users
                //100
                this.isFirst = isFirst
                this.isLoading = isLoading
                this.errMsg = errMsg
                */
                //为了书写方便,在上面 data 中对上面4个变量进行了再次包装为了 info
                //this.info = dataObj
                //为了解决传递过来的 dataObj 元素比 info 少了的情况,不破坏原来 info结构的情况,可以使用下面的方法:
                this.info = {...this.info, ...dataObj}  
                //意思:通过字面量的形式去合并对象。
                //     即:将 this.info的所有属性放在这,随后再把dataObj的所有也放在这,两者重名的属性以后面的为主,后面没说的原来是什么还是什么。 与顺序无关。
                console.log(this)
            })
        },
    }
</script>
<style scoped>
    .album {
        min-height: 50rem; /* Can be removed; just added for demo purposes */
        padding-top: 3rem;
        padding-bottom: 3rem;
        background-color: #f7f7f7;
    }
    .card {
        float: left;
        width: 33.333%;
        padding: .75rem;
        margin-bottom: 2rem;
        border: 1px solid #efefef;
        text-align: center;
    }
    .card > img {
        margin-bottom: .75rem;
        border-radius: 100px;
    }
    .card-text {
        font-size: 85%;
    }
</style>
                    