In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-25 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)05/31 Report--
In this article, Xiaobian introduces in detail the method of communication between Vue3 father and son components and the method of two-way binding between components. The content is detailed, the steps are clear, and the details are handled properly. I hope that this article "communication between Vue3 father and son components, two-way binding between components" can help you solve your doubts.
Parent and child components can communicate through events
Event sending and listening callback with parameters
Use the component's emits plate to organize component events
Use the Object form of the component emits plate to verify the parameter values transmitted outside.
Realize the communication between parent and child components by combining $emit, v-bind and v-model (two-way data binding)
Realize the communication between parent and child components by combining $emit, v-bind and v-model (the application case of multiple fields)
Set your own modifiers
Test the role of this.modelModifiers
Below, in the click callback handleClick () of the subcomponent, through this.modelModifiers. [set modifier name by yourself] implement your own modifier logic
Slot [slot] [example of transmitting components]
Note that events (modifiers) cannot be added directly to the slot tag. If necessary, you can wrap the tag in the outer layer, plus the event.
Slot [string example]
Slot [send an example of setting sub-components by yourself]
Slot scope issu
Slot UI default
Flexible split and application of slots [named slots]
Abbreviation of v-slot instruction
List rendering with ordinary v-for examples
V-for combines v-bind and v-slot to do list rendering.
Use deconstruction concepts for shorthand
Dynamic component
Conventional use of two-way binding feature, through the click event to switch the writing of UI
Dynamic component writing method
Asynchronous component
Parent and child components can communicate through events
The previous note-- "Vue3 | definition and reusability of components, local components, global components, values passed between components and their verification, single data flow, Non-props properties", the concept of unidirectional data flow
That is, the child component cannot modify the data field from the parent component
If you do want to modify it, you can communicate in the following way:
First, in the UI click callback method of the child component, call this.$emit ('[set the event name yourself]')
Send an event out
Then all levels of parent components will receive this event
The child component tag is invoked in the parent component
Listen for the event and configure the callback method in the form of @ [event name] = "callback method name"
In the callback method, you can modify the parent component data field that the child component intends to modify.
Be careful,
Name the trigger event using the hump nomenclature (heHeDa below)
The monitoring event is named using the bar spacing method (he-he-da below).
Code:
Hello World! Heheheheheheda const app = Vue.createApp ({data () {return {count: 1}}, methods: {handleItemEvent () {this.count + = 1;}, template: ``}) App.component ('counter', {props: [' count'], methods: {handleItemClick () {this.$emit ('heHeDa');}}, template: `{{count}}`}); const vm = app.mount (' # heheApp')
Run, click on the component:
Event sending and listening callback with parameters
This.$emit () can increase the parameter bit
The listening callback of the parent component
Can be added to receive parameters (such as param in handleItemEvent (param))
Code:
Const app = Vue.createApp ({data () {return {count: 1}}, methods: {handleItemEvent (param) {this.count + = param;}}, template: ``}) App.component ('counter', {props: [' count'], methods: {handleItemClick () {this.$emit ('addCount', 8);}}, template: `{{count}}`}); const vm = app.mount (' # heheApp')
Run, click the effect:
The sub-component needs to send multiple parameters, just add the parameter bits in this.$emit () as needed.
In the listening callback of the parent component, add the corresponding parameter to receive:
Const app = Vue.createApp ({data () {return {count: 1}}, methods: {handleItemEvent (param1, param2, param3) {this.count = this.count + param1 + param2 + param3; console.log (this.count) }, template: ``}); app.component ('counter', {props: [' count'], methods: {handleItemClick () {this.$emit ('addCount', 8,2,6)) }}, template: `{{count}}`}); const vm = app.mount ('# heheApp')
Effect:
Of course, the calculation logic of the parent component after receiving the parameters of the child component
You can complete the calculation when the subcomponent passes parameters and then pass it to this.$emit ()!
When the parent component receives it, it can receive the value directly (handleItemEvent (count))
Const app = Vue.createApp ({data () {return {count: 1}}, methods: {handleItemEvent (count) {this.count = count; console.log (this.count);}}, template: ``}) App.component ('counter', {props: [' count'], methods: {handleItemClick () {this.$emit ('addCount', this.count + 16);}}, template: `{{count}}`}); const vm = app.mount (' # heheApp')
The effect is the same as the previous example.
Use the component's emits plate to organize component events
In the actual development scenario, there may be a lot of trigger events set by one of our components
It is impossible for us to comb and verify one by one.
At this point, you can use the emits section of the component to organize the events of the component.
You can write all the events set to in the component here to facilitate combing and improve readability.
Or write down the event you want to define here.
In this way, if you don't remember to write the corresponding self-setting event
The Vue system warns you at run time:
Const app = Vue.createApp ({data () {return {count: 1}}, methods: {handleItemEvent (count) {this.count = count; console.log (this.count);}}, template: ``}) App.component ('counter', {props: [' count'], emits: ['hehehe'], methods: {handleItemClick () {this.$emit (' addCount', this.count + 16);}, template: `{{count}}`}) Const vm = app.mount ('# heheApp')
If you don't remember to write the corresponding self-setting event, the Vue system warns you at run time:
Use the Object form of the component emits plate to verify the parameter values transmitted outside.
You can use the Object form of the component emits to verify the parameter values that are transmitted out as needed.
As follows, the emits plate of the sub-component
The 'key' value defines the corresponding event name, and the' value' value defines a check function.
Return true to indicate that you agree to the external transmission of values.
Return false to indicate disagreement and give a warning.
Const app = Vue.createApp ({data () {return {count: 1}}, methods: {handleItemEvent (count) {this.count = count; console.log (this.count);}}, template: ``}) App.component ('counter', {props: [' count'], emits: {addCount: (count) = > {if (count)
< 0) { return true; } return false; } }, methods: { handleItemClick() { this.$emit('addCount', this.count + 16); } }, template:` {{count}} ` }); const vm = app.mount('#heheApp'); 运行,点击效果: 结合$emit、v-bind与v-model 实现 父子组件通信(数据双向绑定) v-model可以实现数据字段与DOM节点内容的双向绑定, 也可以实现数据字段与数据字段之间的双向绑定; 而v-bind只能是实现单向数据流; 若不自己设置承接的字段名,则需要用modelValue作为默认的承接字段名; 同时,$emit()的一参默认为update:modelValue,二参为绑定的数据; 如下代码, 子组件 的承接变量modelValue 同父组件的count字段 双向绑定, (实际上就是v-model的特性 -- 将 子组件的内容即modelValue 同 父组件的数据字段双向绑定) 而后显示在子组件的DOM中({{modelValue}}): const app = Vue.createApp({ data() { return {count: 1} }, template: ` ` }); app.component('counter', { props: ['modelValue'], methods: { handleItemClick() { this.$emit('update:modelValue', this.modelValue + 16); console.log(vm.$data.count); } }, template:` {{modelValue}} ` }); const vm = app.mount('#heheApp'); 效果: 当然也可以自己设置字段名, 这种方式需要给v-model字段接一个字段名, 同时将这个字段名替代子组件中所有modelValue的位置: const app = Vue.createApp({ data() { return {count: 1} }, template: ` ` }); app.component('counter', { props: ['testField'], methods: { handleItemClick() { this.$emit('update:testField', this.testField + 16); console.log(vm.$data.count); } }, template:` {{testField}} ` }); const vm = app.mount('#heheApp'); 实现效果与上例相同; 结合$emit、v-bind与v-model 实现 父子组件通信(多个字段的应用案例) 如下代码, 父组件的count与子组件承接的testField字段, 父组件的count1与子组件承接的testField1字段, 分别实现了双向绑定: const app = Vue.createApp({ data() { return { count: 1, count1: 1 } }, template: ` ` }); app.component('counter', { props: ['testField','testField1'], methods: { handleItemClick() { this.$emit('update:testField', this.testField + 16); console.log("vm.$data.count", vm.$data.count); }, handleItemClick1() { this.$emit('update:testField1', this.testField1 + 8); console.log("vm.$data.count1", vm.$data.count1); } }, template:` {{testField}} {{testField1}} ` }); const vm = app.mount('#heheApp'); 效果: 自己设置修饰符 机制:在父组件调用处,在v-model后 使用自己设置修饰符, 在实现修饰符逻辑的地方,如点击事件中, 通过this.modelModifiers.[自己设置修饰符名]返回的布尔值, 判断客户能否使用了修饰符, 进而分别对使用与否做相应的解决; 另外'modelModifiers'板块中可以指定默认值(下代码指定为一个空对象{}); 试验this.modelModifiers的作用 首先下面是一个空的解决,'modelModifiers'板块中指定默认值(下代码指定为一个空对象{}), mounted函数中打印 子组件modelModifiers属性的内容, 代码如下, 运行后,可以见打印了一个对象{captalize: true}, 正是我们传入的自己设置修饰符.captalize(这里未做解决) 【假如这里v-model不接修饰符, console.log(this.modelModifiers);将打印一个空对象{}】: const app = Vue.createApp({ data() { return { char: 'a' } }, template: ` ` }); app.component('counter', { props: { 'modelValue': String, 'modelModifiers': { default: () =>({})}, mounted () {console.log (this.modelModifiers);}, methods: {handleClick () {this.$emit ('update:modelValue', this.modelValue +' h'); console.log ("vm.$data.count", vm.$data.char) }}, template: `{{modelValue}}`}); const vm = app.mount ('# heheApp')
Below, in the click callback handleClick () of the subcomponent, through this.modelModifiers. [set modifier name by yourself] implement your own modifier logic
The effect is to capitalize the corresponding string after clicking.
Const app = Vue.createApp ({data () {return {testString:'a'}}, template: ``}) App.component ('counter', {props: {' modelValue': String, 'modelModifiers': {default: () = > ({})}}, mounted () {console.log (this.modelModifiers)) }, methods: {handleClick () {let newValue = this.modelValue + 'hackers; if (this.modelModifiers.heheda) {newValue = newValue.toUpperCase ();} this.$emit (' update:modelValue', newValue) Console.log ("vm.$data.count", vm.$data.testString);}, template: `{{modelValue}}`}); const vm = app.mount ('# heheApp')
Effect:
Slot [slot] [example of transmitting components]
The key to use is mainly divided into two parts:
Set up the subcomponents yourself:
Where the component needs to be inserted by the parent component
Use tags for temporary occupancy
Parent component:
When calling a subcomponent tag pair
To the subcomponent label pair
Write down the component in which you want to replace the subcomponent label alignment
Emergence of [slot]
Facilitate the transmission of data between parent and child components
Facilitate the transmission of DOM
Hello World! Heheheheheheda const app = Vue.createApp ({template: `submission `}); app.component ('myform', {template:`)
`}); const vm = app.mount ('# heheApp')
Running effect:
Note that events (modifiers) cannot be directly added to the slot tag. If necessary, you can wrap the tag in an outer layer, followed by the event const app = Vue.createApp ({template: `submit `}) App.component ('myform', {methods: {handleClick () {console.log ("hehedaxiaxiaoqiao =");}}, template: `
`}); const vm = app.mount ('# heheApp')
To run, click the submit text or button:
Slot [string example] const app = Vue.createApp ({template: `66666 88888 `}); app.component ('myform', {methods: {handleClick () {console.log ("hehedaxiaxiaxiangzhouxian =") }}, template: `
`}); const vm = app.mount ('# heheApp')
Slot [send an example of configuring sub-components] const app = Vue.createApp ({template: `88888 `}) App.component ('test', {template: `test principent`}) app.component (' myform', {methods: {handleClick () {console.log ("hehedaxiaxiaxiaoqiao =");}}, template: `
`}); const vm = app.mount ('# heheApp')
Run:
Slot scope issu
Although, the component inserted between the child component tags in the parent component replaces the slot of the child component
But the component in the parent component that is inserted between the child component tags
The data fields it uses are still parent components, not child components.
The data called in the template of the parent component is the data in the parent component
The data called in the template of the subcomponent is the data in the subcomponent
Const app = Vue.createApp ({data () {return {text: 'submit'}}, template: `{{text}} {{text}`}) App.component ('myform', {methods: {handleClick () {console.log ("hehedaxiaxiaoqiao =");}}, template: `
`}); const vm = app.mount ('# heheApp')
Slot UI default
You can write default values between slot labels of sub-components
If the parent component does not use the component to inject the slot
The default value is displayed at the corresponding location:
Const app = Vue.createApp ({data () {return {text: 'submit'}}, template: `{{text}} {{text}}`}) App.component ('myform', {methods: {handleClick () {console.log ("hehedaxiaxiaozhuo =");}}, template: `default value
`}); const vm = app.mount ('# heheApp')
Effect:
Flexible split and application of slots [named slots]
So that the injection part of the parent component and the occupying part of the child component of the slot can be arranged more flexibly.
You can name a group of slots by v-slot: [slot name]
After the definition of the parent component, the slot name and its corresponding components
As long as the subcomponents are in the place where they want to be occupied
Use the corresponding named tag with the name attribute
The corresponding parent component slot component can be occupied.
The component of the slot injection part of the parent component
It needs to be wrapped in a label group.
Use v-slot: [slot name] to name a set of slots
The form used by sub-components for the temporary occupation of slot component blocks
Const app = Vue.createApp ({template: `head tail `}) App.component ('layout', {template: `content `}); const vm = app.mount (' # heheApp')
Effect:
Abbreviation of v-slot instruction
V-slot: [slot name] can be simplified to # [slot name]
Const app = Vue.createApp ({template: `head tail `}) App.component ('layout', {template: `content `}); const vm = app.mount (' # heheApp')
The effect achieved is the same as the example above.
List rendering with ordinary v-for examples
Below in the subcomponents
Use the v-for instruction to cycle through the data of the subcomponent to create the DOM component:
Const app = Vue.createApp ({template: ``}); app.component ('test-list', {data () {return {list: ["heheda", "xixi", "lueluelue"]}}, template: `{item}}) Const vm = app.mount ('# heheApp')
Running effect:
V-for combines v-bind and v-slot to do list rendering.
Function: to provide data by sub-components
But the list UI implementation is provided by the parent component caller
Similar to the design logic of callback interface!
Subcomponents use v-for loops to get data
Sub-item data obtained in each iteration
Set to the placeholder tag through v-bind
In the parent component, on the referenced child component tag
Use v-slot to accept all data fields sent by subcomponents through v-bind
At the same time, package these fields into a structural field similar to JSONObject.
And specify a formal parameter name for this field (mySlotProps in the following code)
Attention!
The front is
Use v-slot to name the components in the parent component that are to be filled with slots
The child component is on the label, and the slot is flexibly filled with the naming of the parent component through name=.
And this is...
Instead, slot plays the role of a props-like rather than a named component! ]
In the DOM components that are to be filled with slots
Use the parameter specified by v-slot to get the data out of the box:
Const app = Vue.createApp ({template: `{{mySlotProps.item}}`}) App.component ('test-list', {data () {return {list: ["heheda", "xixi", "lueluelue"]}}, template: ``}); const vm = app.mount (' # heheApp')
The running effect is the same as the above example.
Use deconstruction concepts for shorthand
Replace the structural logic form of the previous props with vMurslott = "{item}"
The meaning is to take mySlotProps, the field that accepts the property.
The item attribute in it is directly deconstructed and stripped out and used directly.
Const app = Vue.createApp ({template: `{{item}}`}) App.component ('test-list', {data () {return {list: ["heheda", "xixi", "lueluelue"]}}, template: ``}); const vm = app.mount (' # heheApp')
The running effect is the same as the above example.
Dynamic components routinely make use of the bidirectional binding feature to switch UI by clicking the event: const app = Vue.createApp ({data () {return {currentItem: 'input-item'}, methods: {handlerClick () {this.currentItem =' input-item'? This.currentItem = 'div-item': this.currentItem =' input-item'}}, template: `switch DOM components`}); app.component ('input-item', {template: ``}); app.component (' div-item', {template: `heda`}) Const vm = app.mount ('# heheApp')
Running effect:
Dynamic component writing method
Syntax:
Generally in the parent component
Use placeholder label
The effect is the placeholder, and the subcomponents of the component name specified by the is attribute are displayed
In addition,
Use labels, packages
When switching components, the data of components can be cached.
For example, when a component with input data is switched to a remaining component and then switched back,
You can retain the initial input data:
Const app = Vue.createApp ({data () {return {currentItem: 'input-item'}}, methods: {handlerClick () {console.log ("handlerClick -"); this.currentItem =' input-item'? This.currentItem = 'div-item': this.currentItem =' input-item'}}, template: `switch DOM components`}); app.component ('input-item', {template: ``}); app.component (' div-item', {template: `heda`}) Const vm = app.mount ('# heheApp')
Running effect:
Initially an input box with input data:
Click to switch to text component: click again to switch to the input box with input data
Because of the role, the data is cached and is not lost.
If it is not added, there will be an empty input box:
Asynchronous component
First,
All cases prior to this case in this article are synchronous components.
It renders and a thread runs.
Here are the asynchronous (self-setting child) components
You can set to start at a certain time, postpone a delay, and then perform the rendering:
Const app = Vue.createApp ({template: ``}); app.component ('div-item', {template: `heheda heda`}) App.component ('my-async-item', Vue.defineAsyncComponent () = > {return new Promise ((resolve, reject) = > {setTimeout (()) = > {resolve ({template: `this is my async implement`)}, 4000)})) const vm = app.mount (' # heheApp')
Key code [async (self-setting child) component]:
App.component ('my-async-item', Vue.defineAsyncComponent (() = > {return new Promise ((resolve, reject) = > {setTimeout (()) = > {resolve ({template: `this is my async implement`)}, 4000)})
Running effect:
After reading this, the article "the method of communication between Vue3 parent and son components and two-way binding between components" has been introduced. If you want to master the knowledge points of this article, you still need to practice and use it before you can understand it. If you want to know more about related articles, welcome to follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.