下面列出这次用到的openapi,
可以看到他有一个共通的domain https://cloud.culture.tw/frontsite
然後後面分成 trans 跟 opendata,後续又根据功能不同拆成多个类别
节庆相关
https://cloud.culture.tw/frontsite/trans/SearchShowAction.do?method=doFindFestivalTypeJ
主题推荐
https://cloud.culture.tw/frontsite/trans/SearchShowAction.do?method=doFindIssueTypeJ
艺文活动-所有类别
https://cloud.culture.tw/frontsite/trans/SearchShowAction.do?method=doFindTypeJ&category=all
音乐表演资讯
https://cloud.culture.tw/frontsite/trans/SearchShowAction.do?method=doFindTypeJ&category=1
查询单一活动详细资料
https://cloud.culture.tw/frontsite/opendata/activityOpenDataJsonAction.do?method=doFindActivityById&id=5a64e3d8c6355e2a94b8a1cf
经纬度查询附近未过期活动
https://cloud.culture.tw/frontsite/opendata/activityOpenDataJsonAction.do?method=doFindActivitiesNearBy&lat=25.051345&lon=121.549569&range=2
查询单一类别未过期活动资料
https://cloud.culture.tw/frontsite/opendata/activityOpenDataJsonAction.do?method=doFindActivitiesByCategory&category=1
首先在src下建立一个 api资料夹,建立 api.js 档。
import axios from 'axios';
// 建立一个axios实例
const publicService = axios.create({
baseURL: 'https://cloud.culture.tw/frontsite', // url = base url + request url
});
时间有限所以先做节庆活动跟主题推荐这2只api,
会更新主题推荐主页、节庆活动主页、节庆活动详细页面 3个页面!
// 节庆活动 api
// eslint-disable-next-line import/prefer-default-export
export const getFestival = data => publicService.get('/trans/SearchShowAction.do?method=doFindFestivalTypeJ', data);
// 主题推荐 api
export const getTopic = data => publicService.get('/trans/SearchShowAction.do?method=doFindIssueTypeJ', data);
这页比较简单一点,在TopicPage里,我把资料逐笔塞进Topic 子组件,没有做其他操作
所以只要修改TopicPage的资料来源,Topic子组件就会自动吃到新的资料
<script>
import Topic from './Topic';
import { getTopic } from '../api/api'; // 从api.js import 主题推荐的api方法
export default {
name: 'TopicPage',
components: { Topic },
data() {
return {
title: '', // 原本这边都是写死的假资料,直接改成空值即可
note: '',
issue: [],
};
},
methods: {
getTopicData() { // 写一个接资料的方法
getTopic() // 呼叫api方法
.then((res) => {
this.title = res.data.title; // 把api回传的值存到data的参数里
this.note = res.data.note;
this.issue = res.data.issue;
})
.catch((err) => {
// eslint-disable-next-line no-console
console.log(err);
});
},
},
created() {
this.getTopicData(); // 生命周期函数,在页面初始化时要执行资料
},
};
</script>
成功! 如果有看过 Day21 的应该会发现Title跟下面的活动内容都更新了!
而且後续api资料更新,这页的资料也会自动刷新~
这页跟主题推荐差不多,都是回圈渲染组件,所以就不赘述啦
<script>
import Festival from './Festival';
import { getFestival } from '../api/api';
export default {
name: 'FestivalPage',
components: { Festival },
data: () => ({
date: null,
form: {
keyword: null,
start: null,
end: null,
location: [],
},
locations: ['台北市', '基隆市', '新北市', '宜兰县', '桃园市', '新竹市', '新竹县', '苗栗县', '台中市', '彰化县', '南投县', '云林县', '嘉义县', '嘉义市', '台南市', '高雄市', '屏东县', '澎湖县', '花莲县', '台东县', '金门县', '连江县'],
festivalList: [],
}),
methods: {
getFestivalData() {
getFestival()
.then((res) => {
this.festivalList = res.data;
})
.catch((err) => {
// eslint-disable-next-line no-console
console.log(err);
});
},
},
created() {
this.getFestivalData();
},
};
</script>
这页就略为复杂了,他一样是要用节庆专区的api,
但是拿到的是全部资料,还需要再从中筛选出页面对应的那笔
跟上面2个一样,把假资料改为空值,在create()的地方引入api方法
有更改的地方我会用注解标注
<script>
import { getFestival } from '../api/api'; //引入api方法
export default {
name: 'FestivalDetailPage',
data: () => ({
actId: 0,
actData: {},
festivalList: [], // 把原本的假资料改为空值
}),
methods: {
//获取全部资料
getAllData() {
getFestival()
.then((res) => {
this.festivalList = res.data; //先把全部资料存入data()
this.getActData(); // 挑出这页要用的那笔资料
})
.catch((err) => {
// eslint-disable-next-line no-console
console.log(err);
});
},
getActData() {
const actId = this.$route.query.actId;
let selectedAct;
this.festivalList.forEach((obj) => {
if (obj.actId === parseInt(actId, 10)) {
selectedAct = obj;
}
});
this.actData = selectedAct;
},
getImageUrl(imageUrl) {
return `https://cloud.culture.tw/${imageUrl}`;
},
getDateFormat(datetime) {
const newDate = new Date(Date.parse(datetime));
return `${newDate.getFullYear()}/${newDate.getMonth() + 1}/${newDate.getDate()}`;
},
getGrade() {
const { grade1, grade2, grade3, grade4, grade5, grade6 } = this.actData;
const gradeList = [grade1, grade2, grade3, grade4, grade5, grade6];
let gradeResult = '';
gradeList.forEach((grade) => {
if (grade) {
gradeResult += (`${grade} `);
}
});
return gradeResult;
},
},
created() {
this.getAllData(); //在页面初始化时戳api拿资料
},
};
</script>
更改完後,页面可以正常显示了,但是好像有点小问题
错误讯息如下,可以看到本来应该带imageUrl的地方,它却拿到undefined,所以报错
虽然图片显示正常,但是有error我们还是要处理一下!
这个问题是因为我原本的资料是放在data()里,
然後template里用 getImageUrl() 去把图片栏位换成正确的网址,转换後才会渲染页面
<v-img :src='getImageUrl(actData.imageUrl)' />
getImageUrl(imageUrl) {
return `https://cloud.culture.tw/${imageUrl}`;
},
那现在变成页面初始化时,因为data的值我们改成空值了,getImageUrl时会拿不到资料 报错,
然後才执行create() 里的方法,去把api捞到的资料存到data里
用文字讲比较难理解,直接上图!
原本的写法在左边,因为直接拿data的资料所以会正常显示不报错
改拿api资料後,他会先拿一次资料,执行完create()後又拿一次,所以页面会正常显示但是第一次失败後会报错误讯息
既然第二次拿的到资料,就代表第一次的拿资料是不必要的
只要保留让api捞取後可以把资料存进data,再让他渲染这段即可
<!-- 改成直接拿data里的资料 -->
<v-img :src='actData.imageUrl'/>
// 移除getImageUrl(),直接在取得单笔资料时,更改image格式
getActData() {
const actId = this.$route.query.actId;
let selectedAct;
this.festivalList.forEach((obj) => {
if (obj.actId === parseInt(actId, 10)) {
selectedAct = obj;
}
});
this.actData = selectedAct;
this.actData.imageUrl = `https://cloud.culture.tw/${this.actData.imageUrl}`;
},
好惹~ api的部分就先讲到这边啦
後续其实还有挺多东西要做的,不过时间有限真的是讲不完
29天了,明天来讲一下目前的成果总结
快完赛啦 oh ya
https://docs.google.com/forms/d/1YL9riLzCASVo7hkaO...
曾经被系统的地雷,炸得支离破碎 很多好用的应用程序都对Windows不太友善,今天就让你轻松跨越这些...
【YC的迷路青春】 如果不要用预设的路径,例如专案是用tomcat起的,我们不想看tomcat的lo...
方法 程序设计里面 方法太重要了 当然~也有人习惯叫他函数 每个方法我们可以看做一个命令 这其中有...
使用GCP部署机器学习API 此范例使用鸢尾花朵资料集进行 XGBoost 分类器模型训练。将模型储...