10 [Component coding process component custom event global event bus]

1. Component coding process

  1. Component coding process:

    ​ (1). Split static components: components should be split according to function points, and the naming should not conflict with html elements.

    ​ (2). Realize dynamic components: consider the storage location of the data, whether the data is used by a component or some components:

    ​ 1). A component is in use: just put it in the component itself.

    2). Some components are in use: put them on their common parent component (state promotion).

    ​ (3). Realize interaction: start from binding events.

  2. props apply to:

    ​ (1). Parent component ==> child component communication

    ​ (2). Child component ==> parent component communication (requires the parent to give the child a function first)

  3. When using v-model, remember: the value bound by v-model cannot be the value passed by props, because props cannot be modified!

  4. If the value passed by props is an object type, Vue will not report an error when modifying the properties in the object, but this is not recommended.

2. Component custom events

Component custom events are a way of communication between components, applicable to: child components ===> parent components

scenes to be used

A is the parent component, B is the child component, and B wants to pass data to A, then it must bind custom events to B in A (event callbacks are in A).

2.1 Binding custom events

The first way, in the parent component: <Demo @atguigu="test"/>or<Demo v-on:atguigu="test"/>

specific code

app.vue

<template>
	<div class="app">
		<!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第一种写法,使用@或v-on) -->
		<Student @atguigu="getStudentName"/> 
	</div>
</template>

<script>
	import Student from './components/Student'

	export default {
		name:'App',
		components:{Student},
		data() {
			return {
				msg:'你好啊!',
				studentName:''
			}
		},
		methods: {
			getStudentName(name,...params){
				console.log('App收到了学生名:',name,params)
				this.studentName = name
			}
		}
	}
</script>

<style scoped>
	.app{
		background-color: gray;
		padding: 5px;
	}
</style>

Student.view

<template>
	<div class="student">
		<button @click="sendStudentlName">把学生名给App</button>
	</div>
</template>

<script>
	export default {
		name:'Student',
		data() {
			return {
				name:'张三',
			}
		},
		methods: {
			sendStudentlName(){
				//触发Student组件实例身上的atguigu事件
				this.$emit('atguigu',this.name,666,888,900)
			}
		},
	}
</script>

<style lang="less" scoped>
	.student{
		background-color: pink;
		padding: 5px;
		margin-top: 30px;
	}
</style>

The second way, in the parent component:

Use this.refs.xxx.refs.xxx .ref s . xxx . on() It is more flexible to write like this, for example, you can add a timer or something .

specific code

app.vue

<template>
	<div class="app">
		<!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第二种写法,使用ref) -->
		<Student ref="student"/>
	</div>
</template>

<script>
	import Student from './components/Student'

	export default {
		name:'App',
		components:{Student},
		data() {
			return {
				studentName:''
			}
		},
		methods: {
			getStudentName(name,...params){
				console.log('App收到了学生名:',name,params)
				this.studentName = name
			},
		},
		mounted() {
			this.$refs.student.$on('atguigu',this.getStudentName) //绑定自定义事件
			// this.$refs.student.$once('atguigu',this.getStudentName) //绑定自定义事件(一次性)
		},
	}
</script>

<style scoped>
	.app{
		background-color: gray;
		padding: 5px;
	}
</style>

Student.view

<template>
	<div class="student">
		<button @click="sendStudentlName">把学生名给App</button>
	</div>
</template>

<script>
	export default {
		name:'Student',
		data() {
			return {
				name:'张三',
			}
		},
		methods: {
			sendStudentlName(){
				//触发Student组件实例身上的atguigu事件
				this.$emit('atguigu',this.name,666,888,900)
			}
		},
	}
</script>

<style lang="less" scoped>
	.student{
		background-color: pink;
		padding: 5px;
		margin-top: 30px;
	}
</style>

If you want a custom event to be triggered only once, you can use oncemodifiers, or $oncemethods.

Trigger a custom event:this.$emit('atguigu',数据)

Use this.$emit() to pass data from child components to parent components

Note: When this.$refs.xxx.$on('atguigu',回调)binding a custom event, the callback must either be configured in methods or use an arrow function, otherwise this will cause problems!

2.2 Unbind custom events

this.$off('atguigu')

the code

this.$off('atguigu') //解绑一个自定义事件
// this.$off(['atguigu','demo']) //解绑多个自定义事件
// this.$off() //解绑所有的自定义事件

2.3 Components use native events

Components can also be bound to native DOM events, requiring the use of nativemodifiers.

If you don't use the .native modifier, it will be treated as a custom event

<!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第二种写法,使用ref) -->
    <Event1 @click.native="handler1"></Event1>

1: Native DOM—button can be bound to system events——click events, etc.

2: Component label - event1 can bind system events (does not work, because it is a custom event) ----native (can turn custom events into native DOM events)

Using native triggering - the principle is event delegation

in views/Communication/EventTest/Event1.vue:

Its structure is like this, but in the page, whether we click on the Event1 component or other content, we can trigger printing. That is because the current native DOMclick event actually binds the click event to the root node div of the subcomponent ---- Use event delegation, so the h2 and span inside can also trigger printing

image-20220720154327319

Note: It is meaningless to bind custom events to native DOM , because there is no way to trigger the $emit function

Generally, custom events are bound to components in combination with on, on,o n , emit uses

2.4 $event in custom components

Generally, the value passed from the child component to the parent component is received by the function in the methods object. However, sometimes you want to pass some data from the current component, but in this way you cannot receive the data from the child component.

At this time you can use $event

子组件 传值
export default {
    
    
    methods: {
    
    
        customEvent() {
    
    
            this.$emit( custom-event ,  value )
        }
    }
}
 
 
父组件 
接收自定义事件
<template>
    <div>
        <my-item v-for="(item, index) in list" @custom-event="customEvent(index, $event)">
            </my-list>
    </div>
</template>
 
 
接收$event
export default {
    
    
    methods: {
    
    
        //e就是接收过来的$event 现在他就是子组件传过来的值 不再是 对象事件 
        customEvent(index, e) {
    
    
            console.log(e) //  some value
        }
    }
}

3. Global event bus

A way to communicate between arbitrary components is essentially an object that must satisfy the following conditions

  1. All component objects must be able to see him
  2. This object must be able to use on ono n emit$off method to bind, trigger and unbind events

Steps for usage

  1. A way of communication between components, suitable for any communication between components.

  2. Install the global event bus:

    new Vue({
          
          
    	......
    	beforeCreate() {
          
          
    		Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm
    	},
        ......
    }) 
    
  3. Using the event bus:

    1. Receive data: If component A wants to receive data, then bind a custom event to $bus in component A, and the callback of the event stays in component A itself.

      methods(){
              
              
        demo(data){
              
              ......}
      }
      ......
      mounted() {
              
              
        this.$bus.$on('xxxx',this.demo)
      }
      
    2. provide data:this.$bus.$emit('xxxx',数据)

  4. It is best beforeDestroyto use $off in the hook to unbind the events used by the current component.

    Because when it is destroyed, it will only destroy the components, not the ones on the $bus, and you have to take things away when you get off the bus.

Guess you like

Origin blog.csdn.net/Instanceztt/article/details/131052772