จะเริ่มเหตุการณ์เมื่อโมเดล v เปลี่ยนไปได้อย่างไร?


95

ฉันกำลังพยายามเริ่มการfoo()ทำงานของฟังก์ชันด้วย@clickแต่อย่างที่คุณเห็นต้องกดปุ่มตัวเลือกสองครั้งเพื่อเริ่มต้นเหตุการณ์อย่างถูกต้อง จับค่าในครั้งที่สองที่กดเท่านั้น ...

ฉันต้องการเริ่มต้นกิจกรรมโดยไม่@clickเพียง แต่เริ่มการทำงานของเหตุการณ์เมื่อv-model(srStatus) เปลี่ยนแปลง

นี่คือซอของฉัน:

http://fiddle.jshell.net/wanxe/vsa46bw8/


1
ลิงค์ซอไม่ทำงานอีกต่อไป
FrenkyB

หากเจตนาในการโทรfoo()คือการเปลี่ยนแปลงที่ไม่ใช่เทมเพลตให้ใช้ awatcher
Saksham

นี่คือตัวอย่างที่ดีว่าทำไมรหัสเป็นสิ่งจำเป็นในคำถาม โปรดกู้คืนหากเป็นไปได้และแสดงที่นี่
isherwood

ฉันหวังว่าฉันจะได้รับรหัสสำหรับคำถาม แต่เมื่อ 5 ปีที่แล้ว ... โชคดีที่เรามีคำตอบที่ดี
jnieto

คำตอบ:


79

สิ่งนี้เกิดขึ้นเนื่องจากclickตัวจัดการของคุณเริ่มทำงานก่อนที่ค่าของปุ่มตัวเลือกจะเปลี่ยนไป คุณต้องฟังchangeเหตุการณ์แทน:

<input 
  type="radio" 
  name="optionsRadios" 
  id="optionsRadios2" 
  value=""
  v-model="srStatus" 
  v-on:change="foo"> //here

ตรวจสอบให้แน่ใจว่าคุณต้องการเรียกร้องให้foo()พร้อมจริงๆ ...

ready:function(){
    foo();
},

คุณจะจัดการกับ Sliders อย่างไร?
Royi

เหตุการณ์ที่มีอยู่ซึ่งระบุไว้ในเอกสารประกอบอยู่ที่ไหน หาไม่เจอ?
toraman

นี่เป็นเพียงเหตุการณ์ JavaScript มาตรฐานซึ่งคุณสามารถพบได้ที่นี่: developer.mozilla.org/en-US/docs/Web/Events#Standard_events
pherris

ขอบคุณ! แต่พร้อม: ฟังก์ชั่นไม่ได้ผลสำหรับฉัน วิธีการแทน: {foo () {// do something}}
Vince Banzon

โปรดทราบว่าหากคุณต้องการลงทะเบียนเหตุการณ์ "v-on: change" ในคอมโพเนนต์ vue ที่กำหนดเอง (คอมโพเนนต์ไฟล์เดียว) ควรใช้ "v-on: input" แทน
Andrés Biarge

99

คุณสามารถทำให้สิ่งนี้ง่ายขึ้นได้โดยการลบv-onคำสั่ง:

<input type="radio" name="optionsRadios" id="optionsRadios1" value="1" v-model="srStatus">

และใช้watchวิธีการรับฟังการเปลี่ยนแปลง:

new Vue ({
    el: "#app",
    data: {
        cases: [
            { name: 'case A', status: '1' },
            { name: 'case B', status: '0' },
            { name: 'case C', status: '1' }
        ],
        activeCases: [],
        srStatus: ''
    },
    watch: {
        srStatus: function(val, oldVal) {
            for (var i = 0; i < this.cases.length; i++) {
                if (this.cases[i].status == val) {
                    this.activeCases.push(this.cases[i]);
                    alert("Fired! " + val);
                }
            }
        }
    }
});

2
คุณสามารถดูการเปลี่ยนแปลงโมเดลใด ๆ โดยอัตโนมัติได้หรือไม่? ตัวอย่างเช่นสำหรับรูปแบบที่มีอินพุตหลายรายการที่ทุกคนต้องดู?
Eric Burel

@EricBurel ฉันรู้ว่ามันเก่า แต่คำตอบคือไม่ คุณไม่สามารถดูออบเจ็กต์ข้อมูลทั้งหมดที่ทุกฟิลด์ถูกผูกไว้คุณจะต้องดูคุณสมบัติแต่ละรายการของอ็อบเจ็กต์นั้นทีละรายการทำให้วิธีนี้เป็นปัญหาสำหรับเร็กคอร์ดขนาดใหญ่ในฟอร์มที่มีฟิลด์จำนวนมาก
JohnC

1
@EricBurel จริงๆแล้วคุณสามารถดูวัตถุที่ซ้อนกันได้โดยตั้งค่าคุณสมบัติ 'deep' เป็น 'true' -> vuejs.org/v2/api/#watch
SanBen

29

Vue2:หากคุณต้องการตรวจจับการเปลี่ยนแปลงของอินพุตเบลอเท่านั้น (เช่นหลังจากกด Enter หรือคลิกที่อื่น) ให้ทำ (ข้อมูลเพิ่มเติมที่นี่ )

<input @change="foo" v-model... >

หากคุณต้องการตรวจจับการเปลี่ยนแปลงอักขระเดี่ยว (ระหว่างผู้ใช้พิมพ์) ให้ใช้

<input @keydown="foo" v-model... >

คุณยังสามารถใช้@keyupและ@inputเหตุการณ์ต่างๆ @keyDown="foo($event, param1, param2)"หากคุณต้องการที่จะผ่านการใช้พารามิเตอร์เพิ่มเติมในแม่แบบเช่น การเปรียบเทียบด้านล่าง (เวอร์ชันแก้ไขได้ที่นี่ )


keyDown ไม่ทำงานกว่าที่กด 'backspace' ดังนั้นจึงควรใช้ @input
Peretz30

ในซอนี้เราจะเห็นว่า backspace ใช้งานได้กับ@keyDown jsfiddle.net/rLzm0f1q (แต่ฉันไม่ได้บอกว่า@inputไม่ดีหรือดี)
Kamil Kiełczewski

24

คุณควรใช้@input:

<input @input="handleInput" />

@input เริ่มทำงานเมื่อผู้ใช้เปลี่ยนค่าอินพุต

@change จะเริ่มทำงานเมื่อผู้ใช้เปลี่ยนค่าและอินพุตไม่โฟกัส (เช่นคลิกที่อื่นด้านนอก)

คุณสามารถดูความแตกต่างได้ที่นี่: https://jsfiddle.net/posva/oqe9e8pb/


ใช้อะไรแทนเครื่องหมาย @ ได้บ้าง? มีกฎใดเขียนเกี่ยวกับเรื่องนี้หรือไม่? ฉันขอสิ่งนี้เพราะในแบ็กเอนด์ของฉันเครื่องหมาย @ ถูกสงวนไว้สำหรับอย่างอื่น
FrenkyB

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.