Vue控制的表单输入

I'm used to creating controlled components in react using state; however, I'm new to Vue and would like to learn how I could recreate my code from react into something Vue could use. I want the input fields values to be store in a piece of data so that I could do something with them.

// TextInput.vue
<template>
  <div class="col-md-6">
    <div class="form-group">
      <input :value="value" @input="handleChange" ... >
      <label for="name">Name <sub*</sub></label>
    </div>
  </div>
</template>

<script>
  export default {
    props: {
      value: {
        required: true,
        type: String,
      }
    },
    methods: {
      handleChange(e) {
        this.$emit('handleChange', e.target.value);
      }
    }
  }
</script>








// Form.vue

<template>
  /* ... */
  <text-input :value="value" @handleChange="handleChange($event)">
  /* ... */
</template>

<script>
  export default {
    data() {
      return {
        value: '',
      }
    },
    methods: {
      handleChange(payload) {
        this.value = payload;
      }
    }
  }
</script>
评论
俄对花儿笑
俄对花儿笑

This is how it would look like in Vue

Vue.config.devtools = false;
Vue.config.productionTip = false;

const SignIn = Vue.component('sign-in', {

  template: `<form @submit="handleSubmit" className="form form--signin">
            <h2 className="form__h2">Log into your account</h2>

            <label htmlFor="email">Email address</label>
            <input v-model="email" type="email" id="email" autoComplete="off"/>

            <label htmlFor="password">Password</label>
            <input v-model="password" type="password" id="password" autoComplete="off"/>

            <button className="form__btn">Login</button>
        </form>`,
  data() {
    return {
      user: null,
      email: null,
      password: null,
    }
  },
  methods: {
    handleSubmit(event) {

      this.login(this.email, this.password)
      this.email = '';
      this.password = '';
      
      event.preventDefault();
    },
    login(email, password) {

    }
  },
  mounted() {
    if (!this.user)
      return;

    console.log('Writing to session storage...');
    sessionStorage.setItem('user', JSON.stringify(user));
  }
})

var app = new Vue({
  el: '#app'
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <sign-in></sign-in>
</div>
点赞
评论
给爷站住
给爷站住

这就是我可能会在Vue中编写相同组件的方式:

<template>
  <form @submit.prevent="handleSubmit" class="form form--signin">
    <h2 class="form__h2">Log into your account</h2>

    <label for="email">Email address</label>
    <input v-model="email" type="email" id="email" autocomplete="off">

    <label for="password">Password</label>
    <input v-model="password" type="password" id="password" autocomplete="off">

    <button class="form__btn">Login</button>
  </form>
</template>

<script>
const login = async (email, password) => {
  // make the api call and return a promise
};

export default {
  name: "SignIn",
  data: () => ({
    email: "",
    password: ""
  }),
  methods: {
    async handleSubmit(event) {
      console.log("Getting user from API...");

      try {
        const user = await login(this.email, this.password);

        console.log("Writing to session storage...");
        sessionStorage.setItem("user", JSON.stringify(user));

        this.email = "";
        this.password = "";
      } catch (e) {
        // handle login errors
      }
    }
  }
};
</script>

The form controls' state is stored on the data property of the component, and a two-way binding is set up on the controls with the v-model directive. Any changes to the inputs will be synced to the component's state, and vice versa.

Vue provides some handy modifiers when adding event listeners to the template, so by writing @submit.prevent the default submit handler is prevented from firing.

I've created a sandbox example, so you can easily play around with the code and see it in action.

点赞
评论