首页 > 解决方案 > 从 onSSR 加载数据后如何更新输入中的数据?

问题描述

我正在尝试从服务器(onSSR)加载我的运输数据并更新到我的输入表单。但即使我将代码放在 onSSR 中,它也不会更新,例如:

onSSR(async () => {
      await load();
      await loadCountries();
      if (shipping !== undefined) {
        form.firstName = shipping.value.firstName;
      }
    });

请帮忙。

<template>
  <ValidationObserver v-slot='{ handleSubmit }'>
    <SfHeading
      :level='3'
      :title="$t('Shipping')"
      class='sf-heading--left sf-heading--no-underline title'
    />
    <div v-if='shipping!=null'>{{ shipping.firstName }}</div>

    <form @submit.prevent='handleSubmit(handleFormSubmit)'>
      <div class='form'>
        <ValidationProvider
          v-if='!isAuthenticated'
          name='email'
          rules='required|email'
          v-slot='{ errors }'
          slim
        >
          <SfInput
            v-model='form.email'
            label='Email'
            name='email'
            class='form__element'
            required
            :valid='!errors[0]'
            :errorMessage='errors[0]'
          />
        </ValidationProvider>
        <ValidationProvider
          name='firstName'
          rules='required|min:2'
          v-slot='{ errors }'
          slim
        >
          <SfInput
            v-model='form.firstName'
            label='First name'
            name='firstName'
            class='form__element form__element--half'
            required
            :valid='!errors[0]'
            :errorMessage='errors[0]'
          />
        </ValidationProvider>
        <ValidationProvider
          name='lastName'
          rules='required|min:2'
          v-slot='{ errors }'
          slim
        >
          <SfInput
            v-model='form.lastName'
            label='Last name'
            name='lastName'
            class='form__element form__element--half form__element--half-even'
            required
            :valid='!errors[0]'
            :errorMessage='errors[0]'
          />
        </ValidationProvider>
        <ValidationProvider
          name='streetName'
          rules='required|min:2'
          v-slot='{ errors }'
          slim
        >
          <SfInput
            v-model='form.addressLine1'
            label='Street name'
            name='streetName'
            class='form__element form__element--half'
            required
            :valid='!errors[0]'
            :errorMessage='errors[0]'
          />
        </ValidationProvider>
        <ValidationProvider
          name='apartment'
          rules='required|min:2'
          v-slot='{ errors }'
          slim
        >
          <SfInput
            v-model='form.addressLine2'
            label='House/Apartment number'
            name='apartment'
            class='form__element form__element--half form__element--half-even'
            required
            :valid='!errors[0]'
            :errorMessage='errors[0]'
          />
        </ValidationProvider>
        <ValidationProvider
          name='city'
          rules='required|min:2'
          v-slot='{ errors }'
          slim
        >
          <SfInput
            v-model='form.city'
            label='City'
            name='city'
            class='form__element form__element--half'
            required
            :valid='!errors[0]'
            :errorMessage='errors[0]'
          />
        </ValidationProvider>
        <ValidationProvider
          name='state'
          slim
        >
          <SfInput
            v-model='form.state'
            label='State/Province'
            name='state'
            class='form__element form__element--half form__element--half-even'
          />
        </ValidationProvider>
        <ValidationProvider
          name='country'
          rules='required|min:2'
          v-slot='{ errors }'
          slim
        >
          <SfSelect
            v-model='form.country'
            label='Country'
            name='country'
            class='form__element form__element--half form__select sf-select--underlined'
            required
            :valid='!errors[0]'
            :errorMessage='errors[0]'
          >
            <SfSelectOption
              v-for='countryOption in countries'
              :key='countryOption.key'
              :value='countryOption.key'
            >
              {{ countryOption.label }}
            </SfSelectOption>
          </SfSelect>
        </ValidationProvider>
        <ValidationProvider
          name='zipCode'
          rules='required|min:2'
          v-slot='{ errors }'
          slim
        >
          <SfInput
            v-model='form.postalCode'
            label='Zip-code'
            name='zipCode'
            class='form__element form__element--half form__element--half-even'
            required
            :valid='!errors[0]'
            :errorMessage='errors[0]'
          />
        </ValidationProvider>
        <ValidationProvider
          name='phone'
          rules='required|digits:9'
          v-slot='{ errors }'
          slim
        >
          <SfInput
            v-model='form.phone'
            label='Phone number'
            name='phone'
            class='form__element form__element--half'
            required
            :valid='!errors[0]'
            :errorMessage='errors[0]'
          />
        </ValidationProvider>
      </div>
      <div class='form'>
        <div class='form__action'>
          <SfButton
            v-if='!isFormSubmitted'
            :disabled='loading'
            class='form__action-button'
            type='submit'
          >
            {{ $t('Select shipping method') }}
          </SfButton>
        </div>
      </div>
      <VsfShippingProvider
        v-if='isFormSubmitted'
        @submit="$router.push('/checkout/billing')"
      />
    </form>
  </ValidationObserver>
</template>

<script>
import {
  SfHeading,
  SfInput,
  SfButton,
  SfSelect
} from '@storefront-ui/vue';
import { ref } from '@vue/composition-api';
import { onSSR, useVSFContext } from '@vue-storefront/core';
import { useShipping, useCountry, useUser } from '@vue-storefront/spree';
import { required, min, digits } from 'vee-validate/dist/rules';
import { ValidationProvider, ValidationObserver, extend } from 'vee-validate';

extend('required', {
  ...required,
  message: 'This field is required'
});
extend('min', {
  ...min,
  message: 'The field should have at least {length} characters'
});
extend('digits', {
  ...digits,
  message: 'Please provide a valid phone number'
});

export default {
  name: 'Shipping',
  components: {
    SfHeading,
    SfInput,
    SfButton,
    SfSelect,
    ValidationProvider,
    ValidationObserver,
    VsfShippingProvider: () => import('~/components/Checkout/VsfShippingProvider')
  },
  setup() {
    const isFormSubmitted = ref(false);
    const {
      shipping,
      load,
      save,
      loading
    } = useShipping();
    const {
      countries,
      load: loadCountries
    } = useCountry();
    const { isAuthenticated } = useUser();
    const { $spree } = useVSFContext();

    const form = ref({
      email: '',
      firstName: '',
      lastName: '',
      streetName: '',
      apartment: '',
      city: '',
      state: '',
      country: '',
      postalCode: '',
      phone: null
    });
    const handleFormSubmit = async () => {
      if (!isAuthenticated.value) await $spree.api.saveGuestCheckoutEmail(form.value.email);
      await save({ shippingDetails: form.value });
      isFormSubmitted.value = true;
    };

    onSSR(async () => {
      await load();
      await loadCountries();
      if (shipping !== undefined) {
        form.firstName = shipping.value.firstName;
      }
    });

    return {
      shipping,
      loading,
      isFormSubmitted,
      isAuthenticated,
      form,
      countries,
      handleFormSubmit
    };
  }
};
</script>

标签: vue.jsvue-storefront

解决方案


推荐阅读