工做筆記七——vue項目中使用ref屬性刷新當前子路由

最近項目上有這樣一個需求,作統計圖表的展現,可是要在一個頁面實現圖表的切換和按日期條件的查詢。
javascript

相似這樣的。點擊圖標選擇器會彈出一個列表供用戶選擇要看的圖表類型,圖表選定後,點擊右上角的選擇日期會查詢數據刷新當前的圖表。
css

其實,這種需求最簡單的作法,就是將全部的圖表寫在一個界面中。可是每一個圖表的配置項不一樣,圖表一多的話,界面代碼將會很是臃腫且難以維護。因此我沒有使用這種方法。我採起了子路由的方式。vue

首先配置路由:java

{
      path: '/chartBox',
      name: 'chartBox',
      component: chartBox,
      children: [
        {
          name:'',
          path:'',
          component: CustomerCategory
        },
        {
          name: 'CustomerCategory',
          path: 'CustomerCategory',
          component: CustomerCategory
        },
        {
          name: 'MonthlySalesStatistics',
          path: 'MonthlySalesStatistics',
          component: MonthlySalesStatistics
        },
        {
          name: 'MonthlyTask',
          path: 'MonthlyTask',
          component: MonthlyTask
        },
        {
          name: 'OppFunnel',
          path: 'OppFunnel',
          component: OppFunnel
        },
        {
          name: 'SaleRank',
          path: 'SaleRank',
          component: SaleRank
        }
      ]
    }
能夠看到,這五張圖表都在chartBox這個父路由下,這就構成了一個父子路由的關係。另外,配置一個空路由,可讓用戶點擊進來的時候能夠看到一個默認展現的圖表,若是不設置,那麼進入chartBox頁面將會只顯示一個選擇器,只有再手動選擇圖表纔會有相應的顯示。

咱們知道,當咱們切換圖表的時候,會調用對應圖表界面的指定方法,這裏的圖表數據展現不會有問題。可是,當咱們選定一張圖表後,想要根據日期來查詢其它數據,可就沒這麼簡單了。你怎麼觸發數據更新呢?git

咱們來看看父路由界面的編碼:github

<!--
    @CreationDate:2018/3/14
    @Author:Joker
    @Usage:圖表展現主界面,根據picker切換展現不一樣的子路由界面
-->
<template>
  <div class="chart-box">


    <mt-header fixed title="圖表首頁">
      <router-link to="/tool" slot="left">
        <mt-button icon="back">返回</mt-button>
      </router-link>
      <mt-button slot="right" @click="togglePicker">選擇日期</mt-button>
    </mt-header>

    <div class="chart-selector">
      <span>請選擇</span>
      <div class="input-box">
        <input v-model="chartTypeText" readonly/>
        <span @click="openPicker"><i class="fa fa-chevron-down" style="color: #73ccff"></i></span>
      </div>
    </div>

    <!--路由出口-->
    <div class="chart-container">
      <router-view ref="chartView"></router-view>
    </div>

    <!--圖表類型Picker-->
    <mt-popup
      style="width:100%;"
      :closeOnClickModal="false"
      v-model="popupVisible"
      position="bottom">
      <div class="picker-toolbar">
        <span @click="cancelSelect">取消</span>
        <span @click="confirmSelect">肯定</span>
      </div>
      <mt-picker :slots="slots" @change="onValuesChange" valueKey="text"></mt-picker>
    </mt-popup>

    <!--日期picker-->
    <mt-popup
      style="width: 100%"
      :closeOnClickModal="false"
      v-model="popupDateVisible"
      position="bottom">
      <div class="picker-toolbar">
        <span @click="cancelSelectDate">取消</span>
        <span @click="confirmSelectDate">肯定</span>
      </div>
      <mt-picker :slots="dateSlots" @change="onDateValuesChange" valueKey="text"></mt-picker>
    </mt-popup>

  </div>
</template>
<style scoped lang="scss">
  .chart-box {
    .chart-container {
      text-align: center;
      margin-top: 10px;
    }
    .picker-toolbar {
      height: 45px !important;
      width: 100%;
      line-height: 45px;
      background: #f5f8fa;
      border-bottom: 0.03rem solid #eaeaea;
      font-size: 15px;
      span {
        display: inline-block;
        width: 50%;
        text-align: center;
        color: #26a2ff;
        font-size: 15px;
        line-height: 45px;
      }
      span:first-child {
        float: left;
      }
      span:last-child {
        float: right;
      }
    }
    .chart-selector {
      background-color: white;
      margin: 50px 10px 0 10px;
      display: flex;
      line-height: 40px;
      border-radius: 10px;
      span:first-child {
        text-align: center;
        vertical-align: middle;
        padding: 0 10px;
      }
      .input-box {
        flex: 1;
        display: flex;
        font-size: 15px;
        align-items: center;
        background-color: #b8bbbf55;
        border-bottom-right-radius: 8px;
        border-top-right-radius: 8px;
        input {
          flex: 1;
          height: 40px;
          line-height: 40px;
          border: none;
          padding-left: 5px;
        }
        span {
          width: 25px;
          text-align: center;
        }
      }

    }
  }
</style>
<script>

  import {Indicator} from 'mint-ui'

  export default {
    name: 'chartBox',
    created(){
      let _footer = this.$store.state.footerVisible;
      if (_footer) {
        this.$store.commit('TOGGLE_FOOTER');
      }
    },
    data(){
      return {
        popupDateVisible: false,
        popupVisible: false,
        slots: [{
          flex: 1,
          values: [
            {text: '每個月銷量統計', value: 'MonthlySalesStatistics'},
            {text: '銷售排名狀況', value: 'SaleRank'},
            {text: '客戶分類結構', value: 'CustomerCategory'},
            {text: '商機漏斗圖', value: 'OppFunnel'},
            {text: '每個月任務量及完成狀況', value: 'MonthlyTask'},
          ],
          textAlign: 'center'
        }],
        goChart: '',
        tmp: '',
        dateSlots: [{
          flex: 1,
          values: [],
          textAlign: 'center'
        },
          {
            divider: true,
            content: '-',
          }, {
            flex: 1,
            values: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'],
            textAlign: 'center'
          }],
        yearRange: [],
      }
    },
    computed: {
      'chartTypeText': function () {
        return this.$store.state.chartType;
      }
    },
    mounted(){
      for (let i = 2017; i < 2117; i++) {
        this.yearRange.push(i);
      }
      this.dateSlots[0].values = this.yearRange;
    },
    methods: {
      //表格picker
      openPicker(){
        this.popupVisible = true
      },
      cancelSelect(){
        this.popupVisible = false
      },
      confirmSelect(){
        this.$router.replace({name: this.goChart});
        this.popupVisible = false;
        this.$store.commit('setChartType', this.tmp);
      },
      onValuesChange(picker, values){
        if (values[0]) {
          this.goChart = values[0]['value'];
          this.tmp = values[0]['text']
        }
      },
      //日期Picker
      togglePicker(){
        this.popupDateVisible = true;
      },
      cancelSelectDate(){
        this.popupDateVisible = false
      },
      confirmSelectDate(){
        //刷新當前子路由界面
        if (this.goChart === 'MonthlySalesStatistics') {
          let data = {x1: [], x2: []};
          for (let i = 0; i < 12; i++) {
            data.x1.push(Math.floor(Math.random() * 100 + 1));
            data.x2.push(Math.floor(Math.random() * 100 + 1));
          }
          this.$refs.chartView.drawLine(data)
        }else if(this.goChart === 'SaleRank'){
          let data = {x: []};
          for (let i = 0; i < 7; i++) {
            data.x.push(Math.floor(Math.random() * 100 + 1));
          }
          this.$refs.chartView.drawLine(data)
        }
        this.popupDateVisible = false
      },
      onDateValuesChange(picker, values){
        let year = values[0];
        let month = values[1];
        if (year && month) {
          let d = new Date(year + '-' + month);
          console.info(d)
        }
      }
    }
  }
</script>
上面的代碼,最核心的,是配置路由出口的時候,給了一個ref的屬性:

<router-view ref="chartView"></router-view>
ref屬性呢,能夠幫助咱們拿到當前使用組件,也就是說,ref表明了當前展現的子路由對應的組件。咱們可使用this.$refs.chartView 來調用對應組件的方法。爲了節省代碼量,我給每個圖表界面都提供了一個drawLine的方法用於渲染展現圖表,這樣,在咱們選擇日期的時候,點擊確認,就能夠刷新當前路由了。

confirmSelectDate(){
        //刷新當前子路由界面
        if (this.goChart === 'MonthlySalesStatistics') {
          let data = {x1: [], x2: []};
          for (let i = 0; i < 12; i++) {
            data.x1.push(Math.floor(Math.random() * 100 + 1));
            data.x2.push(Math.floor(Math.random() * 100 + 1));
          }
          this.$refs.chartView.drawLine(data)
        }else if(this.goChart === 'SaleRank'){
          let data = {x: []};
          for (let i = 0; i < 7; i++) {
            data.x.push(Math.floor(Math.random() * 100 + 1));
          }
          this.$refs.chartView.drawLine(data)
        }
        this.popupDateVisible = false
      },
這裏用隨機數來模擬前兩張圖的數據變化。

看看效果:app

完美解決!dom

項目地址:https://github.com/JerryYuanJ/a-vue-app-template/tree/master/src/pages/tool/chartide

歡迎star~~~
flex

相關文章
相關標籤/搜索