事件名

跟组件和 prop 不同,事件名不存在任何自动化的大小写转换。而是触发的事件名需要完全匹配监听这个事件所用的名称。举个例子,如果触发一个 camelCase 名字的事件:

this.$emit('myEvent')

则监听这个名字的 kebab-case 版本是不会有任何效果的:

<my-component v-on:my-event="doSomething"></my-component>

跟组件和 prop 不同,事件名不会被用作一个 JavaScript 变量名或属性名,所以就没有理由使用 camelCase 或 PascalCase 了。并且 v-on 事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以 v-on:myEvent 将会变成 v-on:myevent——导致 myEvent 不可能被监听到。

因此,我们推荐你始终使用 kebab-case 的事件名

Vue事件解读之$emit

Vue事件分两部分,一是DOM绑定事件,二是自定义事件。

DOM事件

在Vue中可通过v-on指令或事件语法糖@来为DOM元素绑定事件

<div v-on:click="doSomething"></div>
<div @click="doSomething"></div>

自定义事件

Vue自定义事件是为组件间通信设计,自定义事件提供$on、$off、$once、$emit、$broadcast、$dispatch 几个 api,只是在2.0版本中,$broadcast、$dispatch已不再使用。

$emit 
参考Vue文档$emit

vm.$emit(eventName,[...args])

参数: 
{string} eventName
[…args]//可选参数 
触发当前实例上的事件。附加参数都会传给监听器回调。

# 只配合一个事件名使用 $emit

<div id="emit-example-simple">
<!-- 父組件中子組件的引用处添加函数v-on:function="function1" 
其中function为子组件中使用函数,function1为父组件赋值函数 -->
  <welcome-button v-on:welcome="sayHi"></welcome-button>
</div>
<script>
Vue.component('welcome-button', {
  template: `
    <button v-on:click="$emit('welcome')">
      Click me to be welcomed
    </button>
    `
})
new Vue({
  el: '#emit-example-simple',
  methods: {
    sayHi: function () {
      alert('Hi!')
    }
  }
})
</script>

# 配合额外的参数使用 $emit:

    <div id="app">		
		<div id="counter-event-example">
		<!-- 父組件中子組件的引用處添加函数v-on:function="function1" 
		其中function为子组件中使用函数,function1为父组件赋值函数 -->
			<magic-eight-ball v-on:give-advice="showAdvice"></welcome-button>
		</div>
	</div>

	<script>
	Vue.component("magic-eight-ball", {
		data:function(){
			return{
				possibleAdvice:["Yes","No","Maybe"]
			}
		},
		methods:{
			giveAdvice:function(){
				var randomAdviceIndex=Math.floor(Math.random()*this.possibleAdvice.length)
				this.$emit('give-advice',this.possibleAdvice[randomAdviceIndex])
			}
		},
		template: `
			<button v-on:click="giveAdvice">
				Click me to for advice
			</button>
		`
	});
	new Vue({
		el: '#counter-event-example',		
		methods: {
			showAdvice: function (advice) {
				alert(advice)
			}  
		}
	})
	</script>

数据传递

<div id="app">		
      <parent></parent>
    </div> 
    <script>
      //定义局部子组件
      var childNode={
        template:`
          <div class="child">
            <div>
              <span>子组件数据</span>
              <input v-model="childMsg" v-on:input="data">
            </div>
            <p>{{childMsg}}</p>
          </div>
        `,
        data(){
          return {
            childMsg:"我不猜"
          }
        },
        methods:{
          data(){
            this.$emit('pass-data',this.childMsg)
          }
        }
      }
      //定义父组件
      var parentNode={
        template:`
          <div class="parent">
            <div>
              <span>父组件数据</span>
              <input v-model="msg">
            </div>
            <p>{{msg}}</p>
            <child v-on:pass-data="getData"></child>
          </div>
        `,
        components:{
          'child':childNode
        },
        data(){
          return {
            msg:"你猜"
          }
        },
        methods:{
          getData(value){
            this.msg=value;
          }
        }
      }
      new Vue({
        el: '#app',		
        components:{
          'parent':parentNode
        }
      })
    </script>

子组件通过数据绑定将自身的信息传递给父组件,从而改变父组件内容。

 

注:

现在在组件上使用 v-on 只会监听自定义事件 (组件用 $emit 触发的事件)。如果要监听根元素的原生事件,可以使用 .native 修饰符,比如:

<my-component v-on:click.native="doSomething"></my-component>
Logo

前往低代码交流专区

更多推荐