axios小demo

颜高格
2023-12-01

一、初步

axios.html

    <script src="https://unpkg.com/vue"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
 <div class="container" id="app">
  <h3 class="text-center">Vue新闻</h3>
        <div class="columns medium-3" v-for="result in results">
      <div class="card">
          <div class="card-divider">
              {{ result.title }}
          </div>
         </div>
         <div class="card-section">
             <p>{{ result.abstract }}</p>
         </div>
     </div>
 </div>
 <script src="app.js"></script>

app.js

const vm = new Vue({
 el: '#app',
 data: {
  results: []
 },
 mounted() {
  axios.get("https://api.nytimes.com/svc/topstories/v2/science.json?api-key=jOVhhQ5IFj9gqNq6TabKzud3IewKTFUh")
   .then(response => {
    this.results = response.data.results
   })
 }
});

二、美化界面

使项目更加简洁,可复用。设置一个getPosts作为应用程序的一个方法

app.js

const NYTBaseUrl = "https://api.nytimes.com/svc/topstories/v2/";
const Apikey = "jOVhhQ5IFj9gqNq6TabKzud3IewKTFUh";
function buildUrl(url) {
 return NYTBaseUrl + url + ".json?api-key=" + Apikey;
}
const vm = new Vue({
 el: '#app',
 data: {
  results: []
 },
 mounted() {
  this.getPosts('science');
 },
 methods: {
  getPosts(section) {
   let url = buildUrl(section);
   axios.get(url).then(response => {
    this.results = response.data.results;
   }).catch(error => {
    console.log(error);
   });
  }
 },
 computed: {
  processedPosts() {
   let posts = this.results;
   //添加image_url属性
   posts.map(post => {
    let imgObj = post.multimedia.find(media => media.format === "superJumbo");
    post.image_url = imgObj ? imgObj.url : "http://placehold.it/300x200?text=N/A";
   });
   //将数据分组
   let i, j, chunkedArray = [],
    chunk = 4;
   for (i = 0, j = 0; i < posts.length; i += chunk, j++) {
    chunkedArray[j] = posts.slice(i, i + chunk);
   }
   return chunkedArray;
  }
 }
});

axios.html

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
 <title>最大的新闻app</title>
 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.3.1/css/foundation.min.css">
</head>
<body>
 <script src="https://unpkg.com/vue"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
 <div class="container" id="app">
  <h3 class="text-center">Vue新闻</h3>
        <div class="row" v-for="posts in processedPosts">
      <div class="columns large-3 medium-6" v-for="post in posts">
          <div class="card">
               <div class="card-divider">
                   {{ post.title }}
              </div>
              <a :href="post.url" target="_blank">
                  <img :src="post.image_url">
              </a>
              <div class="card-section">
                  <p>{{ post.abstract }}</p>
              </div>
          </div>
      </div>
  </div>
 </div>
 <script src="app.js"></script>
</body>
</html>

通过引入计算属性对API获得的原始结果进行一些修改,从而对视图的外观进行一些更改

三、组件化 + 可选阅读

  • app.js
const NYTBaseUrl = "https://api.nytimes.com/svc/topstories/v2/";
const Apikey = "jOVhhQ5IFj9gqNq6TabKzud3IewKTFUh";
const SECTIONS = "home,arts,automobiles,books,business,fashion,food,health,insider,magazine,movies,national,nyregion,obituaries,opinion,politics,realestate,science,sports,sundayreview,technology,theater,tmagazine,travel,upshot,world";
function buildUrl(url) {
 return NYTBaseUrl + url + ".json?api-key=" + Apikey;
}
Vue.component('new-list', {
 props: ['results'],
 template: `<section>
   <div class="row" v-for="posts in processedPosts">
      <div class="columns large-3 medium-6" v-for="post in posts">
          <div class="card">
               <div class="card-divider">
                   {{ post.title }}
              </div>
              <a :href="post.url" target="_blank">
                  <img :src="post.image_url">
              </a>
              <div class="card-section">
                  <p>{{ post.abstract }}</p>
              </div>
          </div>
      </div>
  </div>
 </section>
 `,
 computed: {
  processedPosts() {
   let posts = this.results;
   //添加image_url属性
   posts.map(post => {
    let imgObj = post.multimedia.find(media => media.format === "superJumbo");
    post.image_url = imgObj ? imgObj.url : "http://placehold.it/300x200?text=N/A";
   });
   //将数据分组
   let i, j, chunkedArray = [],
    chunk = 4;
   for (i = 0, j = 0; i < posts.length; i += chunk, j++) {
    chunkedArray[j] = posts.slice(i, i + chunk);
   }
   return chunkedArray;
  }
 }
});
const vm = new Vue({
 el: '#app',
 data: {
  results: [],
  loading: true,
  sections: SECTIONS.split(','), //create an array of the sections
  section: 'home', //set default section
  title: ''
 },
 mounted() {
  this.getPosts('home');
 },
 methods: {
  getPosts(section) {
   let url = buildUrl(section);
   axios.get(url).then(response => {
    this.loading = false;
    this.results = response.data.results;
    let title = this.section !== 'home' ? "Top stories in '" + this.section + "' Today" : "Top stories today";
    this.title = title + "(" + response.data.num_results + ")";
   }).catch(error => {
    console.log(error);
   });
  }
 }
});
  • app.html
<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
 <title>最大的新闻app</title>
 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.3.1/css/foundation.min.css">
 <link rel="stylesheet" href="app.css">
</head>
<body>
 <script src="https://unpkg.com/vue"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
 <div class="container" id="app">
  <h3 class="text-center">Vue新闻</h3>
        <section class="callout secondary">
   <h5 class="text-center">分类</h5>
   <form>
    <div class="row">
     <div class="large-6 columns">
      <select v-model="section">
       <option v-for="section in sections" :value="section">{{section}}</option>
      </select>
     </div>
     <div class="large-6 columns">
      <a @click="getPosts(section)" class="button expanded">我要看新闻</a>
     </div>
    </div>
   </form>
        </section>
        <h5 v-if="!loading" class="text-center uppercase">{{title}}</h5> 
        <div v-if="loading" class="loader">
   <img src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/0.16.1/images/loader-large.gif" alt="loader">
  </div>
        <new-list v-if="!loading" :results = "results"></new-list>
 </div>
 <script src="app.js"></script>
</body>
</html>
  • app.css
.container {
 padding: 20px 0
}
.column:last-child:not(:first-child),
.columns:last-child:not(:first-child) {
 float: left;
}
.main_heading {
 margin: 10px 0 30px;
}
.callout {
 margin-bottom: 40px;
}
select {
 text-transform: capitalize;
}
.loader {
 text-align: center;
 padding: 40px;
}
.uppercase {
 text-transform: uppercase;
}

1.HTTP状态码

  • 403(Forbidden):服务器已经理解请求,但是拒绝执行它。
  • 401(unauthorized)未经许可的。当前请求需要用户验证

2.报错

  1. Failed to load resource: the server responded with a status of 403 (Forbidden)
  • 解决办法:这里反反复复出现好几次,但是如果一开始通过api-key可以访问了,改装以后出现403,基本是参数url的问题。
  1. 值得注意的是 api_key需要翻墙 https://developer.nytimes.com/signup 申请api-key

参考:https://segmentfault.com/a/1190000009192118

 类似资料: