Vue gitHub案例(Day38)

105 阅读1分钟

gitHub案例

静态组件

包括搜素组件和列表组件

App组件

<template>
    <div class="container">
        <Search/>
        <List/>
    </div>
</template><script>
import Search from '@/components/Search.vue'
import List from "@/components/List.vue";
​
export default {
    name: 'App',
    components: {
        Search,
        List
    }
}
</script>

Search组件

<script>
import {defineComponent} from 'vue'export default defineComponent({
    name: "Search"
})
</script><template>
    <section class="jumbotron">
        <h3 class="jumbotron-heading">Search GitHub Users</h3>
        <div>
            <input type="text" placeholder="enter the name you search"/>
            &nbsp;
            <button>Search</button>
        </div>
    </section>
</template>

List组件

<script>
import {defineComponent} from 'vue'export default defineComponent({
    name: "List"
})
</script><template>
    <div class="row">
        <div class="card">
            <a href="https://github.com/xxxxx" target="_blank">
                <img src="https://v2.cn.vuejs.org/images/logo.svg" style="width: 100px">
            </a>
            <p class="card-text">xxxxx</p>
        </div>
​
        <div class="card">
            <a href="https://github.com/xxxxx" target="_blank">
                <img src="https://v2.cn.vuejs.org/images/logo.svg" style="width: 100px">
            </a>
            <p class="card-text">xxxxx</p>
        </div>
​
        <div class="card">
            <a href="https://github.com/xxxxx" target="_blank">
                <img src="https://v2.cn.vuejs.org/images/logo.svg" style="width: 100px">
            </a>
            <p class="card-text">xxxxx</p>
        </div>
​
        <div class="card">
            <a href="https://github.com/xxxxx" target="_blank">
                <img src="https://v2.cn.vuejs.org/images/logo.svg" style="width: 100px">
            </a>
            <p class="card-text">xxxxx</p>
        </div>
​
        <div class="card">
            <a href="https://github.com/xxxxx" target="_blank">
                <img src="https://v2.cn.vuejs.org/images/logo.svg" style="width: 100px">
            </a>
            <p class="card-text">xxxxx</p>
        </div>
    </div></template><style scoped>
.album {
    min-height: 50rem;
    padding-top: 3rem;
    padding-bottom: 3rem;
    background-color: #f7f7f7;
}
​
.card {
    float: left;
    width: 33.333%;
    padding: .75rem;
    border: 1px solid #efefef;
    text-align: center;
}
​
.card > img {
    margin-bottom: .75rem;
    border-radius: 100px;
}
​
.card-text {
    font-size: 85%;
}
​
</style>

列表展示

  1. 双向绑定搜索框内的值
  2. 点击按钮获取搜索列表
  3. 使用全局事件总线实现兄弟组件间传值
  4. 将列表渲染至页面

main.js文件

import Vue from 'vue'
import App from './App.vue'Vue.config.productionTip = falsenew Vue({
    render: h => h(App),
    beforeCreate() {
        Vue.prototype.$bus=this
    }
}).$mount('#app')
​

Search组件

<script>
import {defineComponent} from 'vue'
import axios from "axios";
​
export default defineComponent({
    name: "Search",
    data() {
        return {
            keyWord: ''
        }
    },
    methods: {
        searchUsers() {
            axios.get(`https://api.github.com/search/users?q=${this.keyWord}`).then(
                response => {
                    // console.log('请求成功',response.data.items)
                    this.$bus.$emit('userList', response.data.items)
                },
                error => {
                    console.log('请求失败', error.message)
                }
            )
        }
    }
})
</script><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"/>
            &nbsp;
            <button @click="searchUsers">Search</button>
        </div>
    </section>
</template>

List组件

<script>
import {defineComponent} from 'vue'export default defineComponent({
    name: "List",
    data() {
        return {
            users: []
        }
    },
    mounted() {
        this.$bus.$on('userList', (users) => {
            console.log('list组件收到数据', users)
            this.users = users
        })
    }
})
</script><template>
    <div class="row">
        <div class="card" v-for="user in users" :key="user.id">
            <a :href="user.html_url" target="_blank">
                <img :src="user.avatar_url" style="width: 100px">
            </a>
            <p class="card-text">{{ user.login }}</p>
        </div>
    </div></template>

功能完善

List组件

    data() {
        return {
            info: {
                isFirst: true,
                isLoading: false,
                errMsg: '',
                users: [],
            }
        }
    },

初始欢迎页面

        <!--展示欢迎词-->
        <h1 v-show="info.isFirst">欢迎使用</h1>

搜索加载页面

        <!--展示加载中-->
        <h1 v-show="info.isLoading">加载中···</h1>

请求成功展示页面

        <!--展示用户列表-->
        <div class="card" v-show="info.users.length" v-for="user in info.users" :key="user.id">
            <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.errMsg">请求出错了,{{ info.errMsg }}</h1>

功能逻辑

List组件

    mounted() {
        this.$bus.$on('userList', (dataObj) => {
            this.info = {...this.info, ...dataObj}
        })
    }

Search组件

    methods: {
        searchUsers() {
            //  请求前更新list数据
            this.$bus.$emit('userList', {isFirdt: false, isLoading: true, errMsg: '', users: []})
            axios.get(`https://api.github.com/search/users?q=${this.keyWord}`).then(
                response => {
                    //  请求成功后更新list数据
                    this.$bus.$emit('userList', {isLoading: false, errMsg: '', users: response.data.items})
                },
                error => {
                    //  请求失败后更新list数据
                    this.$bus.$emit('userList', {isLoading: false, errMsg: error.message, users: []})
                }
            )
        }
    }