main.js
php
//引入Vue
import Vue from "vue";
//引入App
import App from './App';
//关闭Vue的生产提示
Vue.config.productionTip = false;
new Vue({
el:'#app',
render: h => h(App),
mounted() {
setTimeout(() => {
//注意此时this代表vm
//过三秒自动销毁vm => root
//销毁后子组件以及子组件身上的自定义事件已经没了
//但是原生事件还是可以被调用,不过已经没用了
this.$destroy();
}, 3000);
}
});
App.vue
php
<template>
<div class="app">
<h1>{{ msg }},学生姓名是:{{ studentName }}</h1>
<!--通过绑定一个自定义事件实现了子给父传递数据(自定义事件绑在子组件上) 第一种写法使用@或v-on-->
<!--once代表改事件只执行一次-->
<!-- <Student @personalEvent="getStudentName" @demo="demo"/>-->
<!--第二种写法使用ref绑定事件--->
<Student ref="student" @click.native="show"/>
<!--通过父组件给子组件传递函数类型的props实现了子给父传递数据-->
<School :getSchoolName="getSchoolName"/>
</div>
</template>
<script>
import Student from "@/components/Student";
import School from "@/components/School";
export default {
name: "App",
components:{
School,
Student,
},
data(){
return {
msg: 'helloこんにちは',
studentName:''
}
},
methods:{
getSchoolName(name){
console.log(`app收到了学校名,${name}`);
},
getStudentName(name, ...params){
console.log('自定义');
console.log(`app收到了学生名, ${name}`);
this.studentName = name;
console.log(`剩余参数,${params}`);
},
demo(){
console.log('demo事件被触发了');
},
show(){
console.log(`123`);
}
},
mounted() {
//可以通过ref拿到组件实例对象
// setTimeout(() => {
// this.$refs.student.$on('personalEvent', this.getStudentName); //当App组件一挂载完毕经过三秒我就在Student组件上绑定事件
// //this.$refs.student.$once('personalEvent', this.getStudentName); //注意此时事件只执行一次就不执行了(once),一次性
// },3000)
//注意这里回调要写成剪头函数,不然this会丢失,这个this就是(vc)app,而不是(vc)student
this.$refs.student.$on('personalEvent', (name) => {
console.log(this);
console.log(name);
this.studentName = name;
});
}
}
</script>
<style>
/*
全局的样式是不需要加scoped
全局共享
*/
.app{
background: gray;
padding: 5px;
}
</style>
Student.vue
php
<template>
<div class="student">
<h2>姓名:{{ name }}</h2>
<h2>性别: {{ sex }}</h2>
<h2>当前求和为:{{ number }}</h2>
<button @click="add">点我加一</button>
<button @click="sendStudentName">把学生名传递给app</button>
<button @click="unbind">解绑自定义(personalEvent)事件</button>
<button @click="death">销毁当前student组件的实例对象</button>
</div>
</template>
<script>
export default {
name: "Student",
data(){
console.log(this);
return {
name: '张三',
sex: '男',
number: 0
}
},
methods:{
add(){
console.log(`add回调被调用了`);
this.number ++;
},
sendStudentName(){
//emit触发绑定在指定vc上的自定义事件 vc实例对象可以使用该方法
//后面多余参数演示es6的参数收集
this.$emit('personalEvent',this.name,666,777,888);
// this.$emit('demo'); //同时触发两个事件
// this.$emit('click'); 如果在组件身上使用原生事件不加native修饰符则会让vue认为你这是自定义事件
},
unbind(){
//解绑事件
this.$off('personalEvent'); //这种写法只能解绑一种自定义事件
//this.$off([ 'personalEvent', 'demo' ]);// 解绑多个事件,参数为包含多个事件名的数组
// this.$off(); //比较暴力,有几个自定义事件就全给你解绑了
},
death(){
this.$destroy(); //销毁当前组件实例,销毁后所有该实例的自定义事件都不奏效了
}
}
}
</script>
<style scoped>
.student{
background: orange;
padding: 5px;
margin-bottom: 10px;
}
</style>
School.vue
php
<template>
<div class="demo">
<h2>学校名称:{{ name }}</h2>
<h2>学校地址: {{ address }}</h2>
<button @click="sendSchoolName">把学校名传递给app</button>
</div>
</template>
<script>
export default {
name: "School",
data(){
console.log(this);
return {
name: 'wust university',
address: '武汉科技大学'
}
},
methods:{
sendSchoolName(){
this.getSchoolName(this.name);
}
},
props: ['getSchoolName'],
}
</script>
<style scoped>
/*scoped代表局部的*/
.demo{
background: skyblue;
padding:5px
}
</style>