[前端暴龙机,Vue2.x 进化 Vue3 ] Day20. 『小专题◕ᴥ◕』 Vue 旅游小帮手(一)

话说~ 从疫情到现在,已经不知道多久没出去玩了~
好想出去玩玩喔~ /images/emoticon/emoticon67.gif

从开赛到现在已经默默地来到第二十天了~
以目前所学习的内容,已经可以开发一个小小 Vue 的专题了,所以现在跟着一起做吧

串接 API 资料

在之前的开发,我们通常是使用 ajax 来取得资料,不过在 Vue 中,比较常使用的方式为 axios

使用 axios

一样的我们先将 axios 套件 CDN 引入到档案内

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

接着就与 ajax 的使用方式差不多罗~ 以 GET 为范例

new Vue({
  el: '#app',
  data () {
    return {
    }
  },
  mounted () {
    axios
      .get('https://www.runoob.com/try/ajax/json_demo.json')
      .then(response => {
          // 请求成功处理
      })
      .catch(function (error) { 
          // 请求失败处理
      });
  }
})

目标一,取得景点资料

这次的小专题,会使用到 高雄市政府的 API资料开放平台,先取得景点资料
高雄市政府的 API资料开放平台
高雄旅游网-景点资料
https://ithelp.ithome.com.tw/upload/images/20210818/20120722mn0MECtkj4.jpg

<div id="app">
<ul>
  <li v-for="item in attractions" :key="item.Id">{{ item.Name }}</li>
</ul>
</div>

<script>
var app = new Vue({
  el: '#app',
  data:{
    attractions: []
  },
  mounted() {
    this.getDatas();
  },
  methods:{
    getDatas(){
      axios.get("https://api.kcg.gov.tw/api/service/Get/9c8e1450-e833-499c-8320-29b36b7ace5c").then( res => {
        this.attractions = res.data.data.XML_Head.Infos.Info;
      }).catch( error => { })
    }
  }
})
</script>

目前就可以印出所有的旅游景点了

目标二,制作这些旅游景点的地区列表

这边使用到切割字串( substring )、判断是否在阵列内( includes )的手法来制作

var app = new Vue({
  el: '#app',
  data:{
    attractions: [], // 原始资料
    areaList: [], // 地区列表
  },
  mounted() {
    this.getDatas();
  },
  methods:{
    getDatas(){
      axios.get("https://api.kcg.gov.tw/api/service/Get/9c8e1450-e833-499c-8320-29b36b7ace5c").then( res => {
        this.attractions = res.data.data.XML_Head.Infos.Info;
        this.getAreaList();
      }).catch( error => { })
    },
    getAreaList(){
      this.attractions.forEach(ele => {
      
        // 因为没有地区栏位,所以自己切割出来
        let areaName = ele.Add.substring(6,9); 
        
        // 如果地区列表内不存在当前地区,就 push 进去 ( 过滤重复 )
        if(!this.areaList.includes(areaName)) this.areaList.push(areaName);
      })
    }
  }
})

目标三,筛选并渲染符合选择地区的列表

这边使用到 match 做判断,记录当前选中地区并套用选中样式

HTML 部份

<div id="app">
  <div class="flexbox areaList">
    <div class="areaBtn" :class="{activeArea: selectArea === '全景点'}" @click="setArea('全景点')">全景点</div>
    <div class="areaBtn" :class="{activeArea: selectArea === item }" v-for="item in areaList" :key="item" @click="setArea(item)"> {{ item }} </div>
  </div>
  <hr>

  <ul>
    <li v-for="item in renderAttractions" :key="item.Id">{{ item.Name }}</li>
  </ul>
</div>

套用 css 来凸显目前选择的地区或状态,并改成根据选择条件做列表渲染

JS 部份

var app = new Vue({
  el: '#app',
  data:{
    attractions: [],
    areaList: [],
    selectArea: '全景点', // 预设选中全景点
  },
  mounted() {
    this.getDatas();
  },
  computed:{
    // 根据选择条件做即时列表渲染
    renderAttractions(){
      if(this.selectArea === '全景点'){
        return this.attractions;
      }else{
        return this.attractions.filter(ele => ele.Add.match(this.selectArea))
      }
    }
  },
  methods:{
    getDatas(){
      axios.get("https://api.kcg.gov.tw/api/service/Get/9c8e1450-e833-499c-8320-29b36b7ace5c").then( res => {
        this.attractions = res.data.data.XML_Head.Infos.Info;
        this.getAreaList();
      }).catch( error => { })
    },
    getAreaList(){
      this.attractions.forEach(ele => {
        let areaName = ele.Add.substring(6,9);
        if(!this.areaList.includes(areaName)) this.areaList.push(areaName);
      })
    },
    setArea(item){
      // 储存选中选项
      this.selectArea = item;
    }
  }
})

目前就先完成到可依照选择条件查看该地区的景点了~
https://ithelp.ithome.com.tw/upload/images/20210818/201207224I9n0RlgLl.jpg


小结

  1. 复习 v-bind:class
  2. 复习 v-for 列表渲染
  3. 复习 如何使用 computed 做动态列表渲染
  4. 复习 @click 事件处理

<<:  Day-28 番外篇:现身於电视上的掌中精灵 PSP

>>:  Day 17:今天来部署你的 Angular 应用程序吧!

Day 27:Blazor x Chart.js

Chart.js是一款open source的图表制作library,支援多种图表,包括Pie ch...

Day 29: Dynamic Programming, DP

这是什麽 Memoization + Divide and Conquer = Dynamic Pr...

Day60 (React)

1.跟资料库连线(目前抓data.json) 影片react06.mp4 (1)Lab_WebAPI...

Day5 Let's ODOO: Model(2) Fields

延续前日介绍,今天我们来讲Model内的fields延续昨日范例 # -*- coding: utf...

[Day22] 在 GCP 的 VM 上安装 MySQL

MySQL or MariaDB CentOS 的 rpm 套件管理器预设没有 MySQL repo...