Vue2.x 实现 github 搜索案例
1、前言
如果你对 vue 的基础知识还很陌生,推荐先去学习一下 vue 基础
本篇文章依旧是使用的 Vue 基础知识,同时新增了 axios 请求数据 的需求,及 兄弟组件间 如何 使用自定义事件 实现组件间通信
- 如果你 刚学完 vue 基础知识,想检查一下自己的学习成果
- 如果你 已学完 vue 基础知识,想快速回顾复习
- 如果你 已精通 vue 基础知识,想做个小案例
- 那不妨 再看完这篇文章,我保证你一定会更有收获的!
2、项目演示(一睹为快)
github 搜索案例
3、涉及知识点
- Vue基础:插值语法,常用指令,列表渲染,生命周期
- Vue进阶:自定义事件(兄弟组件间通信),自定义事件的解绑
- 第三方库:axios(发送 axios 请求,请求数据),vue-lazyload 插件,实现 图片懒加载
备注:
- 任意组件间的通信方式有很多种(全局事件总线,消息订阅预发布…),熟练掌握一种即可
- 本文是 vue 基础的练习项目,不涉及 vue 周边(Vuex,Vue-router)
4、项目详情(附源码及解析)
该项目包含三个 vue 组件
(1)App.vue 父组件:整合子组件
(2)Search.vue 子组件:用户查询,发送请求,获取数据
(3)List.vue 子组件:展示用户图片和信息的列表
备注:
- github 提供的请求 API:https://api.github.com/search/users?q=xxx
- 请求的数据(用到的红框起来了)
App.vue 父组件
<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.vue 子组件
- 终端键入 npm i axios 安装 axios
- 给按钮添加点击事件,axios 请求数据并进行页面的渲染更新
- 兄弟组件间通过自定义事件通信,要引入一个 event.js 文件,暴露一个 vue 实例
<template> <section class="jumbotron"> <h3 class="jumbotron-heading">Search Github Users</h3> <input type="text" placeholder="enter the name you search" v-model="keyWords" /> <button @click="searchUsers">Search</button> </section> </template> <script> import axios from "axios"; import event from '../event' export default { name: "mySearch", data() { return { keyWords: "", // 用户输入的关键字 }; }, methods: { // 查询用户 searchUsers() { // 请求前更新 List 的数据 event.$emit("updateListData", { isFirst: false, // 隐藏欢迎词 isLoading: true, // 展示加载中... errMsg: "", // 错误信息为空 users: [], // 数据置为空 }); axios.get(`https://api.github.com/search/users?q=${this.keyWords}`).then( // 成功的回调,隐藏欢迎和加载中,展示请求出来的数据 (reponse) => { console.log("请求成功了", reponse.data.items); // 请求成功后更新 List 数据 event.$emit("updateListData", { isLoading: false, // 请求成功,隐藏加载中... errMsg: "", users: reponse.data.items, // users 数组存放请求成功的数据 }); }, // 失败的回调,提示错误信息 (error) => { //请求失败后更新List数据 console.log("请求失败了", error.message); event.$emit("updateListData", { isLoading: false, // 请求成功,隐藏加载中... errMsg: error.message, // 请求出错,展示错误信息 users: [], // users 数组置空 }); } ); }, }, }; </script> <style> .jumbotron { margin-top: 20px; } .jumbotron-heading { color: skyblue; } </style>
List.vue 子组件
- 终端键入 npm i vue-lazyload 安装懒加载插件
- 在 main.js 中导入并使用它,并设置懒加载时的图片
- 兄弟组件间通过自定义事件通信,要引入一个 event.js 文件,暴露一个 vue 实例
<template> <div class="row"> <!-- 展示用户列表,没有内容时隐藏它。user.login,是唯一标识 --> <div v-show="info.users.length" class="card" v-for="user in info.users" :key="user.login" > <!-- 动态绑定用户的主页地址和图片地址 --> <a :href="user.html_url" target="_blank"> <!-- v-lazy 实现图片的懒加载 --> <img v-lazy="user.avatar_url" style="width: 100px; height: 100px" /> </a> <!-- 呈现用户名 --> <p class="card-text">{{ user.login }}</p> </div> <!-- 初始页面,展示欢迎词 --> <h2 class="welcome" v-show="info.isFirst">前端杂货铺,欢迎你的使用!</h2> <!-- 点击查询,加载过程中展示加载中 --> <h2 class="loading" v-show="info.isLoading">加载中...</h2> <!-- 请求出错,展示错误信息 --> <h2 class="error" v-show="info.errMsg">{{ info.errMsg }}</h2> </div> </template> <script> import event from "../event"; export default { name: "myList", data() { return { info: { isFirst: true, // 欢迎词 isLoading: false, // 加载中... errMsg: "", // 错误信息 users: [], // 存放用户的数组 }, }; }, // 挂载时绑定自定义事件 mounted() { event.$on("updateListData", (dataObj) => { // 合并这两个对象,并且同 key 值的后面的会覆盖前面的,这样 isFirst 就不用重复写了 this.info = { ...this.info, ...dataObj }; }); }, // 销毁前解绑自定义事件 beforeDestroy() { event.$off("updateListData"); }, }; </script> <style scoped> .welcome { color: orange; } .loading { color: rgb(0, 162, 255); } .error { color: red; } .album { min-height: 50rem; padding-top: 3rem; padding-bottom: 3rem; background-color: #f7f7f7; } .card { float: left; width: 33.333%; padding: 0.75rem; margin-bottom: 2rem; border: 1px solid #efefef; text-align: center; } .card > img { margin-bottom: 0.75rem; border-radius: 100px; } .card-text { font-size: 85%; } </style>
main.js 文件
import Vue from 'vue' import App from './App.vue' import VueLazyload from 'vue-lazyload' // 使用懒加载,并设置加载时的图片 Vue.use(VueLazyload, { loading: require("./assets/loading3.png") }) new Vue({ el:'#app', render: h => h(App), })
event.js 文件
- 暴露一个 vue 实例,供自定义事件进行兄弟组件间的通信
import Vue from 'vue' export default new Vue()
5、写在最后的话
如果你是 看完全篇 阅读到了这里,我相信你一定是有收获的!
那么下面不妨打开自己的电脑,启动自己的编译器,来跟着做 / 自己做一遍吧!