programing

사용자가 [Submit]버튼을 클릭할 때까지 폼 입력 바인딩을 연기하려면 어떻게 해야 합니까?

goodcopy 2022. 7. 23. 13:31
반응형

사용자가 [Submit]버튼을 클릭할 때까지 폼 입력 바인딩을 연기하려면 어떻게 해야 합니까?

Vue.js 2.3에서 입력한 양식에 양방향 데이터 바인딩을 만들고 싶었습니다.단, 이 기능을 사용할 수 없습니다.v-modeldirective를 선택합니다.Submit 버튼을 클릭했을 때만 데이터를 갱신합니다.한편 입력값은 다른 Vue 메서드에서 업데이트될 수 있으므로 데이터 속성에 바인딩해야 합니다.text저는 이런 을 지어냈습니다.

<div id="demo">
  <input :value="text" ref="input">
  <button @click="update">OK</button>
  <p id="result">{{text}}</p>
</div>
new Vue({
  el: '#demo',
  data: function() {
    return {
      text: ''
    };
  },
  methods: {
    update: function () {
        this.text = this.$refs.input.value;
    }
  }
});

동작은 하지만 입력이 많아지면 확장이 잘 되지 않습니다.$refs를 사용하지 않고 이를 수행할 수 있는 더 간단한 방법이 있습니까?

개체를 사용하여 해당 속성을 입력에 바인딩할 수 있습니다.그럼, 네 안에서updatemethod를 사용하여 속성을 다른 객체에 복사하여 표시할 수 있습니다.그런 다음 개체가 변경될 때마다 입력 값을 업데이트하도록 딥 워처를 설정할 수 있습니다.를 사용해야 합니다.this.$set변경 내용이 Vue에 등록되도록 속성을 복사할 때.

new Vue({
  el: '#demo',
  data: function() {
    return {
      inputVals: {
        text: '',
        number: 0
      },
      displayVals: {}
    };
  },
  methods: {
    update() {
      this.copyObject(this.displayVals, this.inputVals);
    },
    copyObject(toSet, toGet) {
      Object.keys(toGet).forEach((key) => {
        this.$set(toSet, key, toGet[key]);
      });
    }
  },
  watch: {
    displayVals: {
      deep: true,
      handler() {
        this.copyObject(this.inputVals, this.displayVals);
      }
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<div id="demo">
  <input v-model="inputVals.text">
  <input v-model="inputVals.number">
  <button @click="update">OK</button>
  <input v-for="val, key in displayVals" v-model="displayVals[key]">
</div>

ES2015를 사용하는 경우 개체를 직접 복사할 수 있으므로 자세한 내용은 다음과 같습니다.

new Vue({
  el: '#demo',
  data() {
    return {
      inputVals: { text: '', number: 0 },
      displayVals: {}
    };
  },
  methods: {
    update() {
      this.displayVals = {...this.inputVals};
    },
  },
  watch: {
    displayVals: {
      deep: true,
      handler() {
        this.inputVals = {...this.displayVals};
      }
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<div id="demo">
  <input v-model="inputVals.text">
  <input v-model="inputVals.number">
  <button @click="update">OK</button>
  <input v-for="val, key in displayVals" v-model="displayVals[key]">
</div>

2개의 개별 데이터 속성을 사용할 수 있습니다.하나는,<input>의 값, [OK]버튼을 클릭한 후 커밋된 값에 대한 값입니다.

<div id="demo">
  <input v-model="editText">
  <button @click="update">OK</button>
  <p id="result">{{text}}</p>
</div>
new Vue({
  el: '#demo',
  data: function() {
    return {
      editText: '',
      text: ''
    };
  },
  methods: {
    update: function () {
      this.text = this.editText;
    }
  }
});

업데이트된 바이올린

다른 답변과는 조금 다른 접근법으로 쉽게 확장할 수 있다고 생각합니다.

이것은 첫 번째 패스입니다만, 컴포넌트를 사용하면, 필요에 따라서 정확하게 송신하는 독자적인 입력 요소를 작성할 수 있습니다.다음에 나타내는 것은 입력 요소가 외부일 때 일반 입력 요소와 같이 동작하는 입력 요소의 예입니다.t-form컴포넌트, 단 업데이트만v-modelsubmit안에 있을 때t-form.

Vue.component("t-input", {
  props:["value"],
  template:`
    <input type="text" v-model="internalValue" @input="onInput">
  `,
  data(){
    return {
      internalValue: this.value,
      wrapped: false
    }
  },
  watch:{
    value(newVal){
      this.internalValue = newVal
    }
  },
  methods:{
    update(){
      this.$emit('input', this.internalValue)
    },
    onInput(){
      if (!this.wrapped)
        this.$emit('input', this.internalValue)
    }
  },
  mounted(){
    if(this.$parent.isTriggeredForm){
      this.$parent.register(this)
      this.wrapped = true      
    }
  }
})

의 예를 다음에 나타냅니다.t-form.

Vue.component("t-form",{
  template:`
    <form @submit.prevent="submit">
      <slot></slot>
    </form>
  `,
  data(){
    return {
      isTriggeredForm: true,
      inputs:[]
    }
  },
  methods:{
    submit(){
      for(let input of this.inputs)
        input.update()
    },
    register(input){
      this.inputs.push(input)
    }
  }
})

그것들을 갖추면, 당신의 일은 매우 간단해진다.

<t-form>
  <t-input v-model="text"></t-input><br>
  <t-input v-model="text2"></t-input><br>
  <t-input v-model="text3"></t-input><br>
  <t-input v-model="text4"></t-input><br>
  <button>Submit</button>
</t-form>

이 템플릿은 버튼을 클릭했을 때만 바인딩된 식을 업데이트합니다.몇 개라도 가질 수 있다.t-inputs당신이 원하듯이.

여기 작업 예가 있습니다.포함했습니다.t-input양식 내부와 외부 모두에서 모델이 제출 시에만 업데이트되고 양식 외부에서는 요소가 일반적인 입력과 동일하게 작동함을 알 수 있습니다.

console.clear()
//
Vue.component("t-input", {
  props: ["value"],
  template: `
    <input type="text" v-model="internalValue" @input="onInput">
  `,
  data() {
    return {
      internalValue: this.value,
      wrapped: false
    }
  },
  watch: {
    value(newVal) {
      this.internalValue = newVal
    }
  },
  methods: {
    update() {
      this.$emit('input', this.internalValue)
    },
    onInput() {
      if (!this.wrapped)
        this.$emit('input', this.internalValue)
    }
  },
  mounted() {
    if (this.$parent.isTriggeredForm) {
      this.$parent.register(this)
      this.wrapped = true
    }
  }
})

Vue.component("t-form", {
  template: `
    <form @submit.prevent="submit">
      <slot></slot>
    </form>
  `,
  data() {
    return {
      isTriggeredForm: true,
      inputs: []
    }
  },
  methods: {
    submit() {
      for (let input of this.inputs)
        input.update()
    },
    register(input) {
      this.inputs.push(input)
    }
  }
})


new Vue({
  el: "#app",
  data: {
    text: "bob",
    text2: "mary",
    text3: "jane",
    text4: "billy"
  },
})
<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
<div id="app">
  <t-form>
    <t-input v-model="text"></t-input><br>
    <t-input v-model="text2"></t-input><br>
    <t-input v-model="text3"></t-input><br>
    <t-input v-model="text4"></t-input><br>
    <button>Submit</button>
  </t-form>
  Non-wrapped:
  <t-input v-model="text"></t-input>
  <h4>Data</h4>
  {{$data}}
  <h4>Update Data</h4>
  <button type="button" @click="text='jerome'">Change Text</button>
</div>

언급URL : https://stackoverflow.com/questions/45058462/how-to-defer-form-input-binding-until-user-clicks-the-submit-button

반응형