113.【Vue-细刷-04】(五)

简介: 113.【Vue-细刷-04】

(二十七)、Vue中的ajax

1.Vue项目中常用的2个ajax库

(1).vue-resource
  • vue插件,非官方库,vue1.x使用广泛、现在已经弃用。
(2).axios
  • 通用的ajax请求库,官方推荐,vue2.x使用广泛。

2.解决开发环境Ajax跨域问题

  • 使用代理服务器

3.Github搜索案列_axios_全局总线

(1).静态资源

App.vue

<template>
  <div>
    <div class="container">
    <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>
    <div class="row">
      <div class="card">
        <a href="https://github.com/reactjs" target="_blank">
          <img src="https://avatars.githubusercontent.com/u/6412038?v=3" style='width: 100px'/>
        </a>
        <p class="card-text">reactjs</p>
      </div>
      <div class="card">
        <a href="https://github.com/reactjs" target="_blank">
          <img src="https://avatars.githubusercontent.com/u/6412038?v=3" style='width: 100px'/>
        </a>
        <p class="card-text">reactjs</p>
      </div>
      <div class="card">
        <a href="https://github.com/reactjs" target="_blank">
          <img src="https://avatars.githubusercontent.com/u/6412038?v=3" style='width: 100px'/>
        </a>
        <p class="card-text">reactjs</p>
      </div>
      <div class="card">
        <a href="https://github.com/reactjs" target="_blank">
          <img src="https://avatars.githubusercontent.com/u/6412038?v=3" style='width: 100px'/>
        </a>
        <p class="card-text">reactjs</p>
      </div>
      <div class="card">
        <a href="https://github.com/reactjs" target="_blank">
          <img src="https://avatars.githubusercontent.com/u/6412038?v=3" style='width: 100px'/>
        </a>
        <p class="card-text">reactjs</p>
      </div>
    </div>
  </div>
  </div>
</template>
<script>
export default {
  name:'App'
}
</script>
<style>
.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;
  /* 这个意思是每个div的行距是2分米 */
  margin-bottom: 2rem;
  border: 1px solid #efefef;
  text-align: center;
}
.card > img {
  margin-bottom: .75rem;
  border-radius: 100px;
}
.card-text {
  font-size: 85%;
}
</style>

bootstrap.css

太多了这里不展示
• 1

public: 就是我们引入第三方库的位置 比如:"layui.js,bootstrap.js"

<%= BASE_URL %>  相当于帮助我们找到了pubilic/
• 1

(2).静态资源设置成组件

App.vue

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

Searcher.vue

<template>
  <div>
    <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>
  </div>
</template>
<script>
export default {
    name:'Searcher'
}
</script>
<style>
</style>

List.vue

<template>
  <div>
        <div class="row">
      <div class="card">
        <a href="https://github.com/reactjs" target="_blank">
          <img src="https://avatars.githubusercontent.com/u/6412038?v=3" style='width: 100px'/>
        </a>
        <p class="card-text">reactjs</p>
      </div>
      <div class="card">
        <a href="https://github.com/reactjs" target="_blank">
          <img src="https://avatars.githubusercontent.com/u/6412038?v=3" style='width: 100px'/>
        </a>
        <p class="card-text">reactjs</p>
      </div>
      <div class="card">
        <a href="https://github.com/reactjs" target="_blank">
          <img src="https://avatars.githubusercontent.com/u/6412038?v=3" style='width: 100px'/>
        </a>
        <p class="card-text">reactjs</p>
      </div>
      <div class="card">
        <a href="https://github.com/reactjs" target="_blank">
          <img src="https://avatars.githubusercontent.com/u/6412038?v=3" style='width: 100px'/>
        </a>
        <p class="card-text">reactjs</p>
      </div>
      <div class="card">
        <a href="https://github.com/reactjs" target="_blank">
          <img src="https://avatars.githubusercontent.com/u/6412038?v=3" style='width: 100px'/>
        </a>
        <p class="card-text">reactjs</p>
      </div>
    </div>
  </div>
</template>
<script scoped>
export default {
    name:'List'
}
</script>
<style>
.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;
  /* 这个意思是每个div的行距是2分米 */
  margin-bottom: 2rem;
  border: 1px solid #efefef;
  text-align: center;
}
.card > img {
  margin-bottom: .75rem;
  /* 控制图片的范围 */
  border-radius: 100px;
}
.card-text {
  font-size: 95%;
}
</style>

(3).github搜索案列_发送请求

下载axios的插件。在控制台我们添加 axios

npm add axios

接口地址: https://api.github.com/search/users?q=xxx

注册全局事件总线

import  Vue  from 'vue'  // 引入阉割版本的vue
import  App  from './App.vue' // 引入App.vue组件
Vue.config.productionTip = false;
new Vue({
    // 1.安装全局事件总线
    beforeCreate(){
        Vue.prototype.$bus=this;
    },
    render:h=>h(App)
}).$mount('#app');

App.vue

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

List.vue

1.接受兄弟List传递过来的数据
    methods: {
      accept_message(x){
        console.log('搜索的信息->>>>',x)
      }
    },
    mounted() {
      this.$bus.$on('list_A',this.accept_message)
    },
<template>
  <div>
        <div class="row">
      <div class="card">
        <a href="https://github.com/reactjs" target="_blank">
          <img src="https://avatars.githubusercontent.com/u/6412038?v=3" style='width: 100px'/>
        </a>
        <p class="card-text">reactjs</p>
      </div>
      <div class="card">
        <a href="https://github.com/reactjs" target="_blank">
          <img src="https://avatars.githubusercontent.com/u/6412038?v=3" style='width: 100px'/>
        </a>
        <p class="card-text">reactjs</p>
      </div>
      <div class="card">
        <a href="https://github.com/reactjs" target="_blank">
          <img src="https://avatars.githubusercontent.com/u/6412038?v=3" style='width: 100px'/>
        </a>
        <p class="card-text">reactjs</p>
      </div>
      <div class="card">
        <a href="https://github.com/reactjs" target="_blank">
          <img src="https://avatars.githubusercontent.com/u/6412038?v=3" style='width: 100px'/>
        </a>
        <p class="card-text">reactjs</p>
      </div>
      <div class="card">
        <a href="https://github.com/reactjs" target="_blank">
          <img src="https://avatars.githubusercontent.com/u/6412038?v=3" style='width: 100px'/>
        </a>
        <p class="card-text">reactjs</p>
      </div>
    </div>
  </div>
</template>
<script scoped>
export default {
    name:'List',
    data() {
      return {
        lists:[],
      }
    },
    methods: {
      accept_message(x){
        // this.lists=x;
        console.log('搜索的信息->>>>',x)
      }
    },
    mounted() {
      this.$bus.$on('list_A',this.accept_message)
    },
}
</script>
<style>
.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;
  /* 这个意思是每个div的行距是2分米 */
  margin-bottom: 2rem;
  border: 1px solid #efefef;
  text-align: center;
}
.card > img {
  margin-bottom: .75rem;
  /* 控制图片的范围 */
  border-radius: 100px;
}
.card-text {
  font-size: 95%;
}
</style>

Searcher.vue

在搜索的组件中: 我们需要在方法上添加 async 标注着这个方法是异步方法。然后通过axios.get进行获取某一个接口,
第一个参数是异步请求的网址,第二个是请求网址的参数。response.data是获取回调的信息。然后需要向兄弟组件中传递我们回调成功的数据。
methods: {
      async Searcher(){
        // TODO:  拼接参数: 左边的是网址右边是拼接参数。 里面的对象名一定要是params。
        // ! https://api.github.com/search/users?q=xxx
        try {
          const response= await axios.get('https://api.github.com/search/users',{params:{q:this.key_words}})
          const {items}=response.data;  // 假如信息调用成功我们就回显
          console.log(items)  // 展示我们查询到的信息
          this.$bus.$emit('list_A',items)
        } catch (error) {
          console.log('信息调用失败了!!')
        }
      }
    },
<template>
  <div>
    <section class="jumbotron">
      <h3 class="jumbotron-heading">Search Github Users</h3>
      <div>
        <input type="text" placeholder="enter the name you search" v-model="key_words"/>&nbsp;
        <button @click="Searcher">Search</button>
      </div>
    </section>
  </div>
</template>
<script>
// TODO: 引入我们添加得axios
import axios from 'axios'
export default {
    name:'Searcher',
    data() {
      return {
        key_words:''
      }
    },
    methods: {
      async Searcher(){
        // TODO:  拼接参数: 左边的是网址右边是拼接参数。 里面的对象名一定要是params。
        // ! https://api.github.com/search/users?q=xxx
        try {
          const response= await axios.get('https://api.github.com/search/users',{params:{q:this.key_words}})
          const {items}=response.data;  // 假如信息调用成功我们就回显
          console.log(items)  // 展示我们查询到的信息
          this.$bus.$emit('list_A',items)
        } catch (error) {
          console.log('信息调用失败了!!')
        }
      }
    },
}
</script>
<style>
</style>

(4).github搜索案列完成

这里我们新增了是否是第一次访问、是否正在加载中、和加载后数据的处理

App.vue

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

Searcher.vue

这里的参数我们传递的是: 对象。对象里面的对象名要和接受这个数据组件里面的data对象名要一致。
分别触发三次: 分别是-> 请求之前、请求成功之后、请求失败之后
    methods: {
      async Searcher(){
        // 请求之前通知List更新它的data
        this.$bus.$emit('list_A',{isFirst:false,isLoading:true})
        // TODO:  拼接参数: 左边的是网址右边是拼接参数。 里面的对象名一定要是params。
        // ! https://api.github.com/search/users?q=xxx
        try {
          const response= await axios.get('https://api.github.com/search/users',{params:{q:this.key_words}})
          const {items}=response.data;  // 假如信息调用成功我们就回显
          console.log(items)  // 展示我们查询到的信息
          // 请求成功之后,通知List组件更新它的data
          this.$bus.$emit('list_A',{isLoading:false,lists:items})
        } catch (error) {
          // 请求失败周会
          this.$bus.$emit('list_A',{isLoading:false,lists:[],errMsg:error.message})
          console.log('信息调用失败了!!')
        }
      }
    },
<template>
  <div>
    <section class="jumbotron">
      <h3 class="jumbotron-heading">Search Github Users</h3>
      <div>
        <input type="text" placeholder="enter the name you search" v-model="key_words"/>&nbsp;
        <button @click="Searcher">Search</button>
      </div>
    </section>
  </div>
</template>
<script>
// TODO: 引入我们添加得axios
import axios from 'axios'
export default {
    name:'Searcher',
    data() {
      return {
        key_words:''
      }
    },
    methods: {
      async Searcher(){
        // 请求之前通知list_A更新它的data
        this.$bus.$emit('list_A',{isFirst:false,isLoading:true})
        // TODO:  拼接参数: 左边的是网址右边是拼接参数。 里面的对象名一定要是params。
        // ! https://api.github.com/search/users?q=xxx
        try {
          const response= await axios.get('https://api.github.com/search/users',{params:{q:this.key_words}})
          const {items}=response.data;  // 假如信息调用成功我们就回显
          console.log(items)  // 展示我们查询到的信息
          // 请求成功之后,通知List组件更新它的data
          this.$bus.$emit('list_A',{isLoading:false,lists:items})
        } catch (error) {
          // 请求失败周会
          this.$bus.$emit('list_A',{isLoading:false,lists:[],errMsg:error.message})
          console.log('信息调用失败了!!')
        }
      }
    },
}
</script>
<style>
</style>

Lists.vue

接受数据的时候: 
1. {...this.listInfo,...x} 就是把第一个的key-value替换成第二个key-value。只替换不一样的。
2. 三个点对象 代表展开成key-value形式。
3. {...对象名,属性名:值}  就是将第一个对象的属性名替换成右边的假如不同的情况下。
methods: {
      // 我们接受的是一个对象 
      accept_message(x){
        console.log('搜索的信息->>>>',x);
        this.listInfo={...this.listInfo,...x} // 假如左边的key-value与右边的key-value不一样,就替换成右边的
      }
    },
    mounted() {
      this.$bus.$on('list_A',this.accept_message)
    },
}
<template>
  <div>
      <div class="row">
        <h2 v-show="listInfo.isFirst">第一次请求</h2>
        <h2 v-show="listInfo.isLoading">正在加载....</h2>
      <div class="card" v-for="list_obj in listInfo.lists" :key="list_obj.id">
        <a :href="list_obj.html_url" target="_blank">
          <img :src="list_obj.avatar_url" style='width: 100px'/>
        </a>
        <p class="card-text">{{list_obj.login}}</p>
      </div>
    </div>
  </div>
</template>
<script scoped>
export default {
    name:'List',
    data() {
      return {
        listInfo:{
        lists:[],
        // 是否是第一次请求
        isFirst:true,
        // 是否正在加载
        isLoading:false,
        errMsg:''
        }
      }
    },
    methods: {
      // 我们接受的是一个对象 
      accept_message(x){
        console.log('搜索的信息->>>>',x);
        this.listInfo={...this.listInfo,...x} // 假如左边的key-value与右边的key-value不一样,就替换成右边的
      }
    },
    mounted() {
      this.$bus.$on('list_A',this.accept_message)
    },
}
</script>
<style>
.card {
    /* 从哪里开始排序 */
  float: left;
  /* 这个目的是一行放三个 */
  width: 33.333%;
  padding: .75rem;
  /* 这个意思是每个div的行距是2分米 */
  margin-bottom: 2rem;
  /* 边框 */
  border: 1px solid #efefef;
  text-align: center;
}
  /* 图片的大小 */
.card > img {
  margin-bottom: .75rem;
  /* 控制图片的范围 */
  border-radius: 100px;
}
/* 文本大小 */
.card-text {
  font-size: 95%;
}
</style>

4.Github搜索案列_订阅与发布_axios

安装订阅与发布的插件

npm add pubsub-js

引入订阅与发布

// 引入订阅与发布的插件
import PubSub from 'pubsub-js'

App.vue

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

Searcher.vue 发送者

// TODO: 引入我们添加得axios
import axios from 'axios'
// 引入订阅与发布的插件
import PubSub from 'pubsub-js'
发送信息
// this.$bus.$emit('list_A',{isFirst:false,isLoading:true})
PubSub.publish('list_A',{isFirst:false,isLoading:true})
<template>
  <div>
    <section class="jumbotron">
      <h3 class="jumbotron-heading">Search Github Users</h3>
      <div>
        <input type="text" placeholder="enter the name you search" v-model="key_words"/>&nbsp;
        <button @click="Searcher">Search</button>
      </div>
    </section>
  </div>
</template>
<script>
// TODO: 引入我们添加得axios
import axios from 'axios'
// 引入订阅与发布的插件
import PubSub from 'pubsub-js'
export default {
    name:'Searcher',
    data() {
      return {
        key_words:''
      }
    },
    methods: {
      async Searcher(){
        // 请求之前通知List更新它的data
        // this.$bus.$emit('list_A',{isFirst:false,isLoading:true})
        PubSub.publish('list_A',{isFirst:false,isLoading:true})
        // TODO:  拼接参数: 左边的是网址右边是拼接参数。 里面的对象名一定要是params。
        // ! https://api.github.com/search/users?q=xxx
        try {
          const response= await axios.get('https://api.github.com/search/users',{params:{q:this.key_words}})
          const {items}=response.data;  // 假如信息调用成功我们就回显
          console.log(items)  // 展示我们查询到的信息
          // 请求成功之后,通知List组件更新它的data
          // this.$bus.$emit('list_A',{isLoading:false,lists:items})
          PubSub.publish('list_A',{isLoading:false,lists:items})
        } catch (error) {
          // 请求失败周会
          // this.$bus.$emit('list_A',{isLoading:false,lists:[],errMsg:error.message})
          PubSub.publish('list_A',{isLoading:false,lists:[],errMsg:error.message})
          console.log('信息调用失败了!!')
        }
      }
    },
}
</script>
<style>
</style>

List.vue 订阅者

// 引入订阅与发布的插件
import PubSub from 'pubsub-js'
// 订阅
mounted() {
     this.token=PubSub.subscribe('list_A',this.accept_message)
    },
// 取消订阅
    beforeDestroy(){
      PubSub.unsubscribe(this.token);
    }
<template>
  <div>
      <div class="row">
        <h2 v-show="listInfo.isFirst">第一次请求</h2>
        <h2 v-show="listInfo.isLoading">正在加载....</h2>
      <div class="card" v-for="list_obj in listInfo.lists" :key="list_obj.id">
        <a :href="list_obj.html_url" target="_blank">
          <img :src="list_obj.avatar_url" style='width: 100px'/>
        </a>
        <p class="card-text">{{list_obj.login}}</p>
      </div>
    </div>
  </div>
</template>
<script scoped>
// 引入订阅与发布的插件
import PubSub from 'pubsub-js'
export default {
    name:'List',
    data() {
      return {
        listInfo:{
        lists:[],
        // 是否是第一次请求
        isFirst:true,
        // 是否正在加载
        isLoading:false,
        errMsg:''
        }
      }
    },
    methods: {
      // 我们接受的是一个对象 
      accept_message(msg,x){  // TODO: 发布与订阅模式中,接收信息会收到两个参数,第一个是msg,第二个才是数据。
        console.log('搜索的信息->>>>',x);
        this.listInfo={...this.listInfo,...x} // 假如左边的key-value与右边的key-value不一样,就替换成右边的
      }
    },
    mounted() {
     this.token=PubSub.subscribe('list_A',this.accept_message)
    },
    beforeDestroy(){
      // 取消订阅
      PubSub.unsubscribe(this.token);
    }
}
</script>
<style>
.card {
    /* 从哪里开始排序 */
  float: left;
  /* 这个目的是一行放三个 */
  width: 33.333%;
  padding: .75rem;
  /* 这个意思是每个div的行距是2分米 */
  margin-bottom: 2rem;
  /* 边框 */
  border: 1px solid #efefef;
  text-align: center;
}
  /* 图片的大小 */
.card > img {
  margin-bottom: .75rem;
  /* 控制图片的范围 */
  border-radius: 100px;
}
/* 文本大小 */
.card-text {
  font-size: 95%;
}
</style>

5.Github搜索案列_vue-resource

它是vue的官方插件…

安装vue-resorce

npm add vue-resource

引用Vue-resorce

因为是VUE的官方库、所以我们需要使用到Vue.use

import Vue from "Vue"
import VueResource from 'vue-resource'
Vue.use(VueResource)

引入Vue插件之后: Vue的原型上会新增一个 $http

main.js

import  Vue  from 'vue'  // 引入阉割版本的vue
import  App  from './App.vue' // 引入App.vue组件
import VueResource from 'vue-resource'
Vue.use(VueResource)
Vue.config.productionTip = false;
new Vue({
    // 1.安装全局事件总线
    beforeCreate(){
        Vue.prototype.$bus=this;
    },
    render:h=>h(App)
}).$mount('#app');

App.vue

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

Searcher.vue

const response= await this.$http.get('https://api.github.com/search/users',{params:{q:this.key_words}})
• 1
<template>
  <div>
    <section class="jumbotron">
      <h3 class="jumbotron-heading">Search Github Users</h3>
      <div>
        <input type="text" placeholder="enter the name you search" v-model="key_words"/>&nbsp;
        <button @click="Searcher">Search</button>
      </div>
    </section>
  </div>
</template>
<script>
// TODO: 引入我们添加得axios
import axios from 'axios'
// 引入订阅与发布的插件
import PubSub from 'pubsub-js'
export default {
    name:'Searcher',
    data() {
      return {
        key_words:''
      }
    },
    methods: {
      async Searcher(){
        // 请求之前通知List更新它的data
        // this.$bus.$emit('list_A',{isFirst:false,isLoading:true})
        PubSub.publish('list_A',{isFirst:false,isLoading:true})
        // TODO:  拼接参数: 左边的是网址右边是拼接参数。 里面的对象名一定要是params。
        // ! https://api.github.com/search/users?q=xxx
        try {
          const response= await this.$http.get('https://api.github.com/search/users',{params:{q:this.key_words}})
          const {items}=response.data;  // 假如信息调用成功我们就回显
          console.log(items)  // 展示我们查询到的信息
          // 请求成功之后,通知List组件更新它的data
          // this.$bus.$emit('list_A',{isLoading:false,lists:items})
          PubSub.publish('list_A',{isLoading:false,lists:items})
        } catch (error) {
          // 请求失败周会
          // this.$bus.$emit('list_A',{isLoading:false,lists:[],errMsg:error.message})
          PubSub.publish('list_A',{isLoading:false,lists:[],errMsg:error.message})
          console.log('信息调用失败了!!')
        }
      }
    },
}
</script>
<style>
</style>

List.vue

<template>
  <div>
      <div class="row">
        <h2 v-show="listInfo.isFirst">第一次请求</h2>
        <h2 v-show="listInfo.isLoading">正在加载....</h2>
      <div class="card" v-for="list_obj in listInfo.lists" :key="list_obj.id">
        <a :href="list_obj.html_url" target="_blank">
          <img :src="list_obj.avatar_url" style='width: 100px'/>
        </a>
        <p class="card-text">{{list_obj.login}}</p>
      </div>
    </div>
  </div>
</template>
<script scoped>
// 引入订阅与发布的插件
import PubSub from 'pubsub-js'
export default {
    name:'List',
    data() {
      return {
        listInfo:{
        lists:[],
        // 是否是第一次请求
        isFirst:true,
        // 是否正在加载
        isLoading:false,
        errMsg:''
        }
      }
    },
    methods: {
      // 我们接受的是一个对象 
      accept_message(msg,x){  // TODO: 发布与订阅模式中,接收信息会收到两个参数,第一个是msg,第二个才是数据。
        console.log('搜索的信息->>>>',x);
        this.listInfo={...this.listInfo,...x} // 假如左边的key-value与右边的key-value不一样,就替换成右边的
      }
    },
    mounted() {
     this.token=PubSub.subscribe('list_A',this.accept_message)
    },
    beforeDestroy(){
      // 取消订阅
      PubSub.unsubscribe(this.token);
    }
}
</script>
<style>
.card {
    /* 从哪里开始排序 */
  float: left;
  /* 这个目的是一行放三个 */
  width: 33.333%;
  padding: .75rem;
  /* 这个意思是每个div的行距是2分米 */
  margin-bottom: 2rem;
  /* 边框 */
  border: 1px solid #efefef;
  text-align: center;
}
  /* 图片的大小 */
.card > img {
  margin-bottom: .75rem;
  /* 控制图片的范围 */
  border-radius: 100px;
}
/* 文本大小 */
.card-text {
  font-size: 95%;
}
</style>

相关文章
|
2月前
|
JavaScript
Vue中如何实现兄弟组件之间的通信
在Vue中,兄弟组件可通过父组件中转、事件总线、Vuex/Pinia或provide/inject实现通信。小型项目推荐父组件中转或事件总线,大型项目建议使用Pinia等状态管理工具,确保数据流清晰可控,避免内存泄漏。
228 2
|
11天前
|
缓存 JavaScript
vue中的keep-alive问题(2)
vue中的keep-alive问题(2)
221 137
|
5月前
|
人工智能 JavaScript 算法
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
660 0
|
7月前
|
JavaScript
vue实现任务周期cron表达式选择组件
vue实现任务周期cron表达式选择组件
902 4
|
5月前
|
JavaScript UED
用组件懒加载优化Vue应用性能
用组件懒加载优化Vue应用性能
|
6月前
|
JavaScript 数据可视化 前端开发
基于 Vue 与 D3 的可拖拽拓扑图技术方案及应用案例解析
本文介绍了基于Vue和D3实现可拖拽拓扑图的技术方案与应用实例。通过Vue构建用户界面和交互逻辑,结合D3强大的数据可视化能力,实现了力导向布局、节点拖拽、交互事件等功能。文章详细讲解了数据模型设计、拖拽功能实现、组件封装及高级扩展(如节点类型定制、连接样式优化等),并提供了性能优化方案以应对大数据量场景。最终,展示了基础网络拓扑、实时更新拓扑等应用实例,为开发者提供了一套完整的实现思路和实践经验。
662 77
|
4月前
|
JavaScript 安全
在 Vue 中,如何在回调函数中正确使用 this?
在 Vue 中,如何在回调函数中正确使用 this?
165 0
|
4月前
|
人工智能 JSON JavaScript
VTJ.PRO 首发 MasterGo 设计智能识别引擎,秒级生成 Vue 代码
VTJ.PRO发布「AI MasterGo设计稿识别引擎」,成为全球首个支持解析MasterGo原生JSON文件并自动生成Vue组件的AI工具。通过双引擎架构,实现设计到代码全流程自动化,效率提升300%,助力企业降本增效,引领“设计即生产”新时代。
323 1
|
7月前
|
缓存 JavaScript 前端开发
Vue 基础语法介绍
Vue 基础语法介绍
|
5月前
|
JavaScript 前端开发 开发者
Vue 自定义进度条组件封装及使用方法详解
这是一篇关于自定义进度条组件的使用指南和开发文档。文章详细介绍了如何在Vue项目中引入、注册并使用该组件,包括基础与高级示例。组件支持分段配置(如颜色、文本)、动画效果及超出进度提示等功能。同时提供了完整的代码实现,支持全局注册,并提出了优化建议,如主题支持、响应式设计等,帮助开发者更灵活地集成和定制进度条组件。资源链接已提供,适合前端开发者参考学习。
417 17
下一篇
开通oss服务