在Vue.js中使用Axios取得資料

Sean Yeh
Web Design Zone
Published in
12 min readMar 14, 2022

--

Banff National Park, Canada, photo by Sean Yeh

Vue如果需要取用網站外其他的資料,需要借助於第三方的資源。Axios是其中的一種。

什麼是Axios

依照Axios官方網站的說明,它一個以Promise為基礎(promise-based)的 HTTP 請求工具,可以被應用在瀏覽器與Node.js環境中。在伺服器端可以使用Node.js http模組,而在使用者用戶端則使用XMLHttpRequests。

並且具備下面幾項特性:

  • 1、從瀏覽器發送XMLHttpRequests
  • 2、從node.js發送http請求
  • 3、支援Promise API
  • 4、攔截請求與回應
  • 5、轉換請求與回應的數據
  • 6、並能夠取消請求
  • 7、自動轉換Json格式
  • 8、保護安全預防客戶端受XSRF攻擊

Axios使用場景

簡單的來說,透過HTTP由瀏覽器發送請求或者透過Node.js發送請求時,都可以用Axios來處理。Axios不只是為了Vue.js而開發的套件,其他例如React、Node等,甚至於直接使用JavaScript開發的專案,都可以使用Axios。由於Vue、React等框架的出現,部分網站開始採用前後端分離的架構,使得透過Axios來發送與請求資料的情況也跟著變多。

Axios的安裝

在使用Axios之前需要先進行安裝。安裝的方式很多,除了最簡單的透過CDN安裝之外,還可以透過npm、yam或者是bower來安裝。下面是透過npm安裝的方式:

$ npm install axios

下面是透過CDN直接安裝:

<script src="<https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js>"></script>

跟其他的套件一樣,安裝完畢之後還需要在目前的專案中匯入Axios套件。匯入套件的語法如下:

import axios from 'axios';

當上面的安裝與匯入步驟完成之後,就可以開始使用Axios套件。

Axios基本用法

基本上,Axios可以透過GET與POST兩種方式存取資料。

透過GET取得資料

可以透過get的方式獲取資料。使用get的語法如下:

變數 = axios.get('資料來源網址url')

透過這個語法,get可以從資料來源的網址取得資料,並且返回一個物件。

透過POST傳送資料

傳送資料的方式為post。官網上面示範了最簡單的方式:

axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'}
)

這部分不在本篇文章的範圍,留待後文討論。

與Vue.js結合 — 以Vue 3.x為例

如果要將Axios使用在Vue.js框架中,要如何使用?下面將以Vue 3.x中使用Axios為例說明。

資料來源

為舉例之便,我們將資料放在專案的public資料夾中,在public資料夾裡面建立一個data.json檔案。data.json的內容為一連串的文字列表。下圖為本次實驗使用的data.json檔案之內容。

由於data.json為靜態檔案,且與本專案同處於一台機器上,我們除了透過http://localhost:3000/data.json 的方式來取得檔案外,也可以使用 /data.json 直接取得資料。在這裡我們透過變數url來指定這個資料來源位置,可以用下面方式表示:

//資料來源網址url
const url = '/data.json'

或者是用下面方式表示:

//資料來源網址url
const url = 'http://localhost:3000/data.json'

Vue.js設定

Vue的部分,在這裡使用Vue Composition API的方式來建構。因此,在setup 函式裡面放入axios.get()來獲取資料。

//資料來源網址url
const url = '/data.json'

const App = {
setup() {
axios.get(url)
.then((res)=>{
console.log(res.data)
})
return {};
},
};
Vue.createApp(App).mount("#app");

如果透過Vue Cli安裝Vue3.x的話,可以在App.vue裡面的<script>部分加上下面的程式碼:

import axios from 'axios';const url = '/data.json';export default {
setup() {
axios.get(url).then((res)=>{
console.log(res.data)
})
},
}

執行程式碼的結果會顯示在console裡面,res.data會將data.json裡面的資料全部取出來。

axios取資料的時間點

上面的程式碼還有優化的空間。由於上面的程式碼在網頁DOM元素都還沒有渲染完成之前,就先取出資料。比較好的方式是等到網頁DOM元素都已經在本地端電腦上渲染完成後,再進行下載的程序。

因此,我們可以利用Vue生命週期的onMounted hook,讓取得資料的程序在Vue掛載完成之後才開始進行。我們可以將程式碼改寫成下面:

const { onMounted } = Vue;
//資料來源網址url
const url = '/data.json'
const App = {
setup() {
onMounted(() => {
axios.get(url)
.then((res) => {
console.log(res.data);
});
});
return {};
},
};
Vue.createApp(App).mount("#app");

透過Vue Cli安裝Vue3.x的話,在App.vue裡面的<script>部分的程式碼如下:

import{onMounted} from 'vue';
import axios from 'axios';
const url = '/data.json';export default {
setup() {
onMounted(() => {
axios.get(url)
.then((res)=>{
console.log(res.data)
})
});

return {};
},
}

請注意,在Vue Composition API裡面,需要用到什麼就要匯入什麼。換句話說,我們在這裡需要先匯入onMounted hook,才可以使用。

執行程式碼的結果一樣會顯示在console裡面,res.data會將data.json裡面的資料全部取出來。

顯示在頁面上

到目前為止,在console裡面已經可以看到我們取得的資料了。接下來,就是把這些資料顯示在HTML的頁面上。需要經過下面幾個步驟:

#data變數

首先,要建立一個變數,並在變數裡面放置可以從axios取得的資料。我們就將變數命名為 data 吧。

const data = reactive({
newsdata:'',
})

#reactive匯入

由於需要用到reactive。依照前面提到的,在Vue Composition API裡面,需要用到什麼就要匯入什麼,我們要再匯入reactive(如下:)。

import{reactive, onMounted} from 'vue';

#將axios取得的資料放入data變數

接下來,要把axios取得的資料放入data變數中。我們可以使用下面的方式:

data.newsdata = res.data

#將data變數的內容return

setup函式的最後,要把需要用到的變數內容return出來。如此才可以顯示在頁面上。

setup() {
...略...
return {data};
}

#HTML頁面渲染出data變數的內容

最後,要把return出來的data變數呈現在HTML的頁面上。我們可以先簡單的使用下面方式將資料顯示出來。

<p>{{data.newsdata}}</p>

結果在頁面上會呈現下面的樣子:

可以看見,雖然很醜,但不可否認的是axios取得的data.json內的資料,都已經呈現在頁面上了。到目前為止,我們修改的程式碼如下(以Vue Cli為例):

<template>    <div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<router-view /> <p>{{data.newsdata}}</p></template><script>import{reactive, onMounted} from 'vue';
import axios from 'axios';
const url = '/data.json';export default {
setup() {
const data = reactive({
newsdata:'',
})
onMounted(() => {
axios.get(url)
.then((res)=>{
console.log(res.data)
data.newsdata = res.data
})
});
return {data};
},
}
</script>

優化

如果你跟我ㄧ樣覺得上面的畫面實在是無法給別人看的話,可以對它進行優化。最簡單的優化方式就是加上Bootsrtap的CSS框架。我們可以使用框架中的card元件來重構上面的HTML畫面。(使用Bootstrap前,需要在index.html 裡面載入Bootstrap的CDN)

<template><div id="nav" class="container">    <router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<!-- <router-view /> --><div class="container">
<h1>{{ data.newsdata.title }}</h1>
<div class="row">
<div class="col-3"
v-for="(item, i) in data.newsdata.datas"
:key="item.title"

>
<div class="card mb-3">
<div class="card-body">
<h5 class="card-title" style="height:100px">{{ item.title }}</h5>
<p class="card-text">
{{ item.source }}<br />
{{ item.date }}
</p>
</div>
</div>
</div>
</div>
</div>
</template>

# 改了什麼?

上面的程式碼是App.vue,我們針對這個檔案進行了修改。除了應Bootstrap框架的需要修改HTML的標籤外,我們來看看關於Vue的部分,修改了哪些地方。

#h1標題

在h1的地方顯示標題,標題的內容為JSON檔案裡面的 “title”: “新聞資料”。我們透過下面方式把它取出來。

<h1>{{ data.newsdata.title }}</h1>

#v-for迴圈顯示卡片

下面的粗體字可以看到,透過v-for的方式將資料逐一的顯示出來。

值得注意的是v-for要顯示的資料整體,不是使用data.newsdata而是data.newsdata.datas。因為在data.json檔裡面,所有的新聞資料都放在datas裡面。

data.json
<div class="col-3"
v-for="(item, i) in data.newsdata.datas"
:key="item.title"

>

#卡片內容

datas裡面的資料有title、source與date。我們分別在card-title與card-text標籤裡面,將這三項資料取出來。

<h5 class="card-title" style="height:100px">{{ item.title }}</h5>
<p class="card-text">
{{ item.source }}<br />
{{ item.date }}
</p>

對了,最後我們將 <router-view />隱藏起來。如此就看不到Vue 的Logo了。

完成修改後,執行的結果如下。是不是比較好看一點:

結語

以上僅介紹Axios最基礎的部分。透過GET取得json資料。實際上,Axios還可以透過POST將資料傳送出去。藉由GET與POST的來回傳遞,就可以改變網站的內容。日後再針對Axios的其他部分進行說明。

--

--

Sean Yeh
Web Design Zone

# Taipei, Internet Digital Advertising,透過寫作讓我們回想過去、理解現在並思考未來。並樂於分享,這才是最大贏家。