Example of API with Vue.js in firefly-iii/firefly-iii

File app/Api/V1/Controllers/Chart/AccountController.php (link to Github)
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Data\DateRequest;
use FireflyIII\Models\AccountType;
use Illuminate\Http\JsonResponse;

class AccountController extends Controller
{
    //
    public function overview(DateRequest $request): JsonResponse
    {
        $dates = $request->getAll();
        $start = $dates['start'];
        $end = $dates['end'];

        $defaultSet = $this->repository->getAccountsByType([AccountType::ASSET])->pluck('id')->toArray();
        $frontPage  = app('preferences')->get('frontPageAccounts', $defaultSet);
        $default    = app('amount')->getDefaultCurrency();

        if (empty($frontPage->data)) {
            $frontPage->data = $defaultSet;
            $frontPage->save();
        }

        $accounts  = $this->repository->getAccountsById($frontPage->data);
        $chartData = [];
        foreach ($accounts as $account) {
            $currency = $this->repository->getAccountCurrency($account);
            if (null === $currency) {
                $currency = $default;
            }
            $currentSet   = [
                'label'                   => $account->name,
                'currency_id'             => (string)$currency->id,
                'currency_code'           => $currency->code,
                'currency_symbol'         => $currency->symbol,
                'currency_decimal_places' => $currency->decimal_places,
                'start_date'              => $start->toAtomString(),
                'end_date'                => $end->toAtomString(),
                'type'                    => 'line', // line, area or bar
                'yAxisID'                 => 0, // 0, 1, 2
                'entries'                 => [],
            ];
            $currentStart = clone $start;
            $range        = app('steam')->balanceInRange($account, $start, clone $end);
            $previous     = round((float)array_values($range)[0], 12);
            while ($currentStart <= $end) {
                $format   = $currentStart->format('Y-m-d');
                $label    = $currentStart->toAtomString();
                $balance  = array_key_exists($format, $range) ? round((float)$range[$format], 12) : $previous;
                $previous = $balance;
                $currentStart->addDay();
                $currentSet['entries'][$label] = $balance;
            }
            $chartData[] = $currentSet;
        }

        return response()->json($chartData);
    }
}
File routes/api.php (link to Github)
//
Route::group(
    ['namespace' => 'FireflyIII\Api\V1\Controllers\Chart', 'prefix' => 'chart/account',
     'as'        => 'api.v1.chart.account.',],
    static function () {
        Route::get('overview', ['uses' => 'AccountController@overview', 'as' => 'overview']);
    }
);
//
File frontend/src/components/dashboard/MainAccount.vue (link to Github)
<template>
  <div class="card">
    <div class="card-header">
      <h3 class="card-title">{{ $t('firefly.yourAccounts') }}</h3>
    </div>
    <div class="card-body">
      <div>
        <canvas id="canvas" ref="canvas" width="400" height="400"></canvas>
      </div>
      <div v-if="loading && !error" class="text-center">
        <span class="fas fa-spinner fa-spin"></span>
      </div>
      <div v-if="error" class="text-center">
        <span class="fas fa-exclamation-triangle text-danger"></span>
      </div>
    </div>
    <div class="card-footer">
      <a class="btn btn-default button-sm" href="./accounts/asset"><span class="far fa-money-bill-alt"></span> {{ $t('firefly.go_to_asset_accounts') }}</a>
    </div>
  </div>
</template>

<script>
//
export default {
  data() {
    return {
      loading: true,
      error: false,
      ready: false,
      initialised: false,
      dataCollection: {},
      chartOptions: {},
      _chart: null,
    }
  },
  //
  methods: {
    initialiseChart: function () {
      this.loading = true;
      this.error = false;
      //let startStr = this.start.toISOString().split('T')[0];
      //let endStr = this.end.toISOString().split('T')[0];
      let startStr = format(this.start, 'y-MM-dd');
      let endStr = format(this.end, 'y-MM-dd');
      let url = './api/v1/chart/account/overview?start=' + startStr + '&end=' + endStr;
      axios.get(url)
          .then(response => {
            let chartData = DataConverter.methods.convertChart(response.data);
            chartData = DataConverter.methods.colorizeLineData(chartData);
            this.dataCollection = chartData;
            this.loading = false;
            this.drawChart();
          })
          .catch(error => {
            console.error('Has error!');
            console.error(error);
            this.error = true;
          });
    },
    //
  }
}
</script>

Additional resources on API with Vue.js: