四.Vue中事件处理函数绑定、v-model

(1).事件处理函数绑定

1.data中得事件

事件可以写在data中,但是里面的this是指向window的

<body>
    <div id="app">
        <div @click="onClick">xx</div>
    </div>
    <script src="vue2引入"></script>
    <script>
       let vm = new Vue({
           el:'#app',
           data(){
               return{
                  onClick(){
                      console.log(this)//window
                  }
               }
           },
           methods:{
               onClick(e){
                   console.log(this);//这个实例
                   console.log(e.target,e.currentTarget)//都是事件do'm,没有在父级,没有做代理
               }
           }
       })

    </script>
</body> 

vue会自动给你bind一次,你再自己bind第二次是无效的

2.发送自定义事件

通过$emit监听 @响应

子组件
<template>
    <div class="hello">
        <button @click="onButtonClick"></button>
    </div>
</template>
<script>
    export default{
        name:'hello',
        methods:{
            onButtonClick(){
                this.$emit('myClick')
            }
        }
    }
</script>

父组件
<template>
    <div id="app">
        <HelloWorld @myClick="onHellWorld"/>
    </div>
</template>
<script>
import HelloWorld  from '../xx.vue'
    export default{
        name:'App',
        components:{
            HelloWorld
        },
        methods:{
            onHellWorld(){
                console.log('我响应了')
            }
        }
    }
</script>

3.监听原生事件

通过@事件名.native来监听

子组件
<template>
    <div class="hello">
        <button></button>
    </div>
</template>
<script>
    export default{
        name:'hello',
      
    }
</script>

父组件
<template>
    <div id="app">
        <HelloWorld @click.native="onHellWorld"/>//默认会传递事件源对象
    </div>
</template>
<script>
import HelloWorld  from '../xx.vue'
    export default{
        name:'App',
        components:{
            HelloWorld
        },
        methods:{
            onHellWorld(){
                console.log('我响应了')
            }
        }
    }
</script>

$event传递事件源对象

|如果()里什么都不写则打印un 无法打印事件对象

默认会自动传递,$evnet 同时也可以获取到子组件携带的参数

父组件
<template>
    <div id="app">
        <HelloWorld @click.native="onHellWorld($event)"/>
    </div>
</template>
<script>
import HelloWorld  from '../xx.vue'
    export default{
        name:'App',
        components:{
            HelloWorld
        },
        methods:{
            onHellWorld(e){
                console.log(e)
            }
        }
    }
</script>

4.阻止默认冒泡

会有默认的冒泡

点击随便一个li都会响应ul的事件

<template>
    <ul @click="onUlclick">
        <li @click="onLiClick">1</li>
        <li @click="onLiClick">2</li>
    </ul>
</template>

可以通过@click.stop阻止默认的冒泡

原生阻止就是stopProgation

<template>
    <ul @click="onUlclick">
        <li @click.stop="onLiClick">1</li>
        <li @click="onLiClick">2</li>
    </ul>
</template>

5.阻止默认行为

通过@click.prevent来阻止默认事件响应

<a href="wwwxxx" @click.prevent>xx</a>

router-link点击的时候并不会刷新,其实也是默认阻止事件了

原生就是preventDefault

<router-link to="/">连接1</router-link>//点击后不会响应

6.router-link标签响应事件

这个是不响应的,因为组件监听的是自定义事件,所以必需要加上.native

<router-link to="/" @click="onClick"/></router-link>//不行
<router-link to="/" @click.native="onClick"/></router-link>//可以响应

(2).v-model双向绑定

1.基础

input输入改变,显示值也改变

<div id = "app">
    <input type="text" :value="message" @input="onInput"/>//方法1
    <input type="text" v-model="message"/>//双向绑定
    <p>{{message}}</p>
</div>
<script src="vue2引入"></script>
<script>
    let vm = new Vue({
        el:'#app',
        data(){
            return{
                message:'Hello JS++'
            }
        },
        methods:{
            oninput(e){
                this.message = e.target.value
            }
        }
    })
</script>    

双向绑定的原理就是在input框上绑定:value值为data 数据,再绑定一个输入事件,响应体则为改变data中的值从而实现双向绑定

.lazy效果就为change事件一样,等输入完再响应

<div id = "app">
    <input type="text" :value="message" @change="onInput"/>//方法1
    <input type="text" v-model.lazy="message"/>//双向绑定
    <p>{{message}}</p>
</div>
<script src="vue2引入"></script>
<script>
    let vm = new Vue({
        el:'#app',
        data(){
            return{
                message:'Hello JS++'
            }
        },
        methods:{
            oninput(e){
                this.message = e.target.value
            }
        }
    })
</script>    

2.组件间的双向绑定

原始方式

在input中输入 触发父组件事件的响应,所以输入一个就会打印一个hello JS++

子组件
<template>
    <div>
        <input type="text" :value="value" @input="onMyInput"
    </div>
</template>
<script>
    export default{
        name:'hello',
        props:['value'],
        methods:{
            onMyInput(e){
                this.$emit('myInput',e.target.value)
            }
        }
      
    }
</script>

父组件
<template>
    <div id="app">
        <HelloWorld :value="message" @myInput="onInput" />
    </div>
</template>
<script>
import HelloWorld  from '../xx.vue'
    export default{
        name:'App',
        components:{
            HelloWorld
        },
        data(){
            return{
                message:'Hello'
            }
        },
        methods:{
            onInput(value){
                this.message = value
            }
        }
    }
</script>

v-model绑定

子组件
<template>
    <div>
        <input type="text" :value="value"  @input="onMyInput"
    </div>
</template>
<script>
    export default{
        name:'hello',
        props:['value'],
         methods:{
            onMyInput(e){
                this.$emit('myInput',e.target.value)
            }
        }
      
    }
</script>

父组件
<template>
    <div id="app">
        <HelloWorld v-model="message"/>
        {{message}}
    </div>
</template>
<script>
import HelloWorld  from '../xx.vue'
    export default{
        name:'App',
        components:{
            HelloWorld
        },
        data(){
            return{
                message:'Hello'
            }
        }
    }
</script>

总结:

  组件中得双向绑定中,父组件只监听$emit抛出input的事件,直接在父组件中v-model绑定响应

自己设置prop和event是什么

这个用处就可以将Props接收的参数多余出来用了,prop接收传递过来的参数,event设置抛出的监听函数名

  默认情况下,一个组件上的 v-model 会把 value 用作 prop 且把 input 用作 event,

 

  但是一些输入类型比如单选框和复选框按钮可能想使用 value prop 来达到不同的目的。使用 model 选项可以回避这些情况产生的冲突。

子组件
<template>
    <div>
        <input type="text" :value="test"  @input="onMyInput"
    </div>
</template>
<script>
    export default{
        name:'hello',
        props:['value'],
        model:{
            prop:'test',
            event:'testevent'
        },
         methods:{
            onMyInput(e){
                this.$emit('testevent',e.target.value)
            }
        }
      
    }
</script>

示例二

<template>
    <div>
        <h1>Child</h1>
        <input type="checkbox" :checked="checked" @change="handleChange"/>
    </div>
</template>
<script>
    export default{
        model:{
            prop:'checked',
            event:'check'
        },
        props:['checked'],
        methods:{
            handleChange(e){
                this.$emit('check',e.target.checked)
            }
        }
    }
</script>

3.绑定多个属性可以用sync

只能使用在组件间

下面也可以实现双向绑定

子组件
<template>
    <div>
        <input type="text" :value="value"  @input="onMyInput"
    </div>
</template>
<script>
    export default{
        name:'hello',
        props:['value'],
         methods:{
            onMyInput(e){
                this.$emit('update:value',e.target.value)//update是固定写法
            }
        }
      
    }
</script>

父组件
<template>
    <div id="app">
        <HelloWorld  :value.sync="message"/>
        {{message}}
    </div>
</template>
<script>
import HelloWorld  from '../xx.vue'
    export default{
        name:'App',
        components:{
            HelloWorld
        },
        data(){
            return{
                message:'Hello'
            }
        }
    }
</script>

绑定多个属性

子组件
<template>
    <div>
        <input type="text" :value="value"  @input="onMyInput"
        <input type="text" :value="name" @input="onAgeInput"> 
    </div>
</template>
<script>
    export default{
        name:'hello',
        props:['value','name'],
         methods:{
            onMyInput(e){
                this.$emit('input',e.target.value)//update是固定写法
            },
            onAgeInput(e){
                this.$emit('update:fn',e.target.value)//update是固定写法
            }
        }
      
    }
</script>

父组件
<template>
    <div id="app">
        <HelloWorld v-model="message"  :fn.sync="name"/>
        {{message}}
        {{name}}
    </div>
</template>
<script>
import HelloWorld  from '../xx.vue'
    export default{
        name:'App',
        components:{
            HelloWorld
        },
        data(){
            return{
                message:'Hello',
                name:'xx'
            }
        }
    }
</script>
vue3中的绑定方式
<Child v-model:checked="checked" v-model:message="message"/>

 

Logo

前往低代码交流专区

更多推荐