0
点赞
收藏
分享

微信扫一扫

一个例子手把手教你入门Vue2

爱情锦囊 2022-03-22 阅读 49

文章目录


效果展示:

  • 由于用户名是<h2/>标签,所以会比较大,撑大了父元素让整个布局显得有点乱
  • 不过写完才发现,就懒得优化了
    请添加图片描述

一、创建并配置好vue脚手架

1,创建Vue脚手架,选择Vue2的默认版本
在这里插入图片描述
2,vscode打开我们创建的脚手架
准备工作:

  • 删除components文件夹中的文件
  • 删除App.vue中的内容并且重新配置模板
  • 关闭eslint语法检查(不关闭会报错)
  • vue.config.js文件中新增配置项lintOnSave:false
    在这里插入图片描述

二、创建组件并完成静态页面

组件结构很简单,Header组件用来搜索,Main组件用来展示
在这里插入图片描述
接着开始写静态页面
Header组件

<template lang="">
  <div>
    <div class="search">
      <input type="text">
      <button>点我搜索</button>
    </div>
  </div>
</template>
<script>
  export default {

  }
</script>
<style scoped>
  .search{
    display: flex;
    justify-content: center;
  }
</style>

Main组件

<template lang="">
  <div>
    <div class="show_container">
        <div class="card">
          <a href="">
            <img src="../assets/download.jpg" alt="">
          </a>
          <h2>UserName</h2>
        </div>
    </div>
  </div>
</template>
<script>
export default {
  
}
</script>
<style scoped>
  .show_container{
    margin-top: 50px;
    width: 90vw;
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
  }
  img{
    width: 100px;
    height: 100px;
    object-fit: cover;
  }
  h2{
    text-align: center;
  }
</style>

App组件

  • 引入、注册并使用Header和Main两个组件
<template lang="">
  <div class="main_container">
    <Header></Header>
    <Main></Main>
  </div>
</template>
<script>
  import Header from './components/Header.vue'
  import Main from './components/Main.vue'
  export default {
    components: {
      Header,
      Main
    }
  }
</script>
<style scoped>
  .main_container {
    display: flex;
    flex-direction: column;
    align-items: center;
  }
  * {
    margin: 0;
    padding: 0;
  }
</style>
  • 输入yarn serve执行项目
    静态页面效果如下
    在这里插入图片描述

三、使用axios发送ajax请求

首先要弄懂啥是静态页面,啥是动态页面,千万别以为页面上有个动图就是动态页面了;通俗点来讲,静态页面没有交互效果,上面的都是死数据;而动态页面用户可以很好的进行交互,可以根据自己的想法得到想要的数据。

先别急着来请求数据,我们向github请求数据总得带关键词吧,而关键词也就是我们Header组件中用户输入的内容,那么开干吧!

  • 首先给<input/>输入框进行双向数据绑定:v-model=‘keyWord’
  • 接着给<input/>绑定回车事件,给button绑定点击事件,并指向同一函数searchUsers
    以下为Header组件
<template lang="">
  <div>
    <div class="search">
      <input type="text" v-model="keyWord" @keyup.enter="searchUsers">
      <button @click="searchUsers">点我搜索</button>
    </div>
  </div>
</template>
<script>
  export default {
    data() {
      return {
        keyWord: ''
      }
    },
    methods: {
      searchUsers() {
        
      }
    },
  }
</script>
<style scoped>
  .search {
    display: flex;
    justify-content: center;
  }
</style>
  • 接下来就是要根据获取到的keyWord发送ajax请求了,那么在哪个组件中发呢?必然是Main组件,因为请求回来的数据将在Main组件中渲染。
  • 这时候我们将要想办法将Header中的数据keyWord传给其兄弟组件Main。有N中办法,我选择的是全局事件总线(我会单独写一篇关于它的)
  1. 首先在main.js中定义全局事件总线
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
  beforeCreate(){
    //将vm挂载在到Vue的显式原型上
    Vue.prototype.$bus = this
  }
}).$mount('#app')

  1. 在Main组件中自定义事件并指定回调
mounted() {
    //定义事件,指定回调函数searchAjax
    this.$bus.$on('key',this.searchAjax)
  },
methods:{
	//q是Header组件传过来的keyWord
  searchAjax(q){

  }
}
  1. 在Header组件中触发自定义事件并传送自己的参数
methods: {
  searchUsers() {
    //将数据传给Main组件
    this.$bus.$emit('key',this.keyWord)
  }
},
  • 这时候在Main组件中已经可以拿到Header组件中的keyWord了

开始玩axios,我们的api是https://api.github.com/search/users(querry参数)

  1. 安装axios;命令:yarn add axios -S
  2. 在Main组件中引入axios;命令:import axios from 'axios'
  3. 根据拿到的keyWord作为querry参数发送请求
searchAjax(q){
  axios({
    url:'https://api.github.com/search/users',
    method:'get',
    params:{
      // q:q可简写为下
      q
    }
  }).then(response => {
    console.log(response);
  }).catch(error => {
    console.log(error.message);
  })
}
  • 测试并观察返回的数据结构:随便输入关键词回车,观察控制台中返回的数据结构,发现data下的items数组是我们所需要的
    在这里插入图片描述
  1. 我们先准备一个容器数组users用来存放筛选后的items数组
data() {
  return {
    users:[]
  }
},
  1. 接着用map()方法加工items数组并将加工结果传给users
.then(response => {
 this.users = response.data.items.map(item => ({
   id: item.id,
   userName: item.login,
   avatar: item.avatar_url,
   page: item.html_url,
 }))
})
  1. 最后一步,渲染数据,在Main组件中
<template lang="">
  <div>
    <div class="show_container">
      <div class="card" v-for="(user, index) in users" :key="user.id">
        <a :href="user.page">
          <img :src="user.avatar" alt="">
        </a>
        <h2>{{user.userName}}</h2>
      </div>
    </div>
  </div>
</template>

完成!你学废了吗?
请添加图片描述

效果如下
请添加图片描述
你以为这就完了吗?NONONO,优化在后面。。。
请添加图片描述


四、优化实现人性化效果

1、优化一:首先用户这个东西是很可怕的哇,要考虑用户什么也不输入就回车的情况

优化后的Header组件如下

<template lang="">
  <div>
    <div class="search">
      <input type="text" v-model="keyWord" @keyup.enter="searchUsers">
      <button @click="searchUsers">点我搜索</button>
    </div>
  </div>
</template>
<script>
  export default {
    data() {
      return {
        keyWord: ''
      }
    },
    methods: {
      searchUsers() {
      	//在这儿判断以下用户是否啥也没输就开始搜索了
        if (this.keyWord.trim()) {
          //将数据传给Main组件
          this.$bus.$emit('key', this.keyWord)
        }else{
        //如果啥也没输弹出警告
          alert('别给老子输空串儿!')
        }
      }
    },

  }
</script>
<style scoped>
  .search {
    display: flex;
    justify-content: center;
  }
</style>

优化后效果如下
请添加图片描述

2、优化二:在Main组件中,当没有数据的时候页面一片空白,非常的不美观;

  • 当开始搜索时,数据返回有一段时间,得让用户知道已经开始搜了,只是还没传过来(别骂了,是你网速的问题)
  • 如果搜索失败,给个报错页面,提示下报错信息就完了(甩锅王)
    请添加图片描述

开干!

优化后的Main组件如下

<template lang="">
  <div>
    <div class="show_container">
      <!-- 用条件语句决定显示哪一个标签 -->
      <h2 v-if="isFirst">尊贵的天龙人,请输入用户名查找</h2>
      <h2 v-else-if="isBegin">查找中,别急,快了</h2>
      <div v-else-if="isError">
        <h2>不好意思,出了点问题</h2>
        <h2>{{error}}</h2>
      </div>
      <div v-else class="card" v-for="(user, index) in users" :key="user.id">
        <a :href="user.page">
          <img :src="user.avatar" alt="">
        </a>
        <h2>{{user.userName}}</h2>
      </div>
    </div>
  </div>
</template>
<script>
  import axios from 'axios'
  export default {
    data() {
      return {
        users: [],
        error:'',
        // 三个数据驱动四种状态,分别是一开始,搜索中,出错,正常显示
        isFirst:true,
        isBegin:false,
        isError:false
      }
    },
    mounted() {
      //定义事件,指定回调函数searchAjax
      this.$bus.$on('key', this.searchAjax)
    },
    methods: {
      searchAjax(q) {
        // 开始搜索,将第一次置为false,将开始搜索置为true
        this.isFirst = false
        this.isBegin = true
        axios({
          url: 'https://api.github.com/search/users',
          method: 'get',
          params: {
            // q:q可简写为下
            q
          }
        }).then(response => {
          // 数据回来了,将开始搜索置为false便于下一步显示数据
          this.isBegin = false
          this.users = response.data.items.map(item => ({
            id: item.id,
            userName: item.login,
            avatar: item.avatar_url,
            page: item.html_url,
          }))
        }).catch(error => {
          // 出错,首先将isBegin置为false
          // 然后将isError置为true,显示错误信息
          this.isBegin = false
          this.isError = true
          this.error = error.message
        })
      }
    }
  }
</script>
<style scoped>
  .show_container {
    margin-top: 50px;
    width: 90vw;
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
  }

  img {
    width: 100px;
    height: 100px;
    object-fit: cover;
  }

  h2 {
    text-align: center;
  }
</style>

优化后效果如下

  • 以下是请求成功的情况
    请添加图片描述
  • 以下是请求失败的情况
    请添加图片描述

总结

  • 小孩子才写总结
  • 昨天刚成年
    请添加图片描述
举报

相关推荐

0 条评论