Vuejs学习笔记(二)-9.父子组件交互案例

前置:父组件有data.num1,子组件通过props定义了cnum1来接收data.num1的值

需求:在子组件内定义个输入框,希望输入数据时能够改变父组件的data.num1的值。

思路:v-model双向绑定

1.通过v-model将子组件的输入框与props.cnum1双向绑定

代码如下:

 1 <!--
 2 @author:invoker
 3 @project:project_lianxi
 4 @file: 13-父子组件交互南里.html
 5 @contact:invoker2021@126.com
 6 @descript:
 7 @Date:2021/7/4 21:50
 8 @version: html5
 9 -->
10 
11 <!DOCTYPE html>
12 <html lang="en">
13 <head>
14   <meta charset="UTF-8">
15   <title>13-父子组件交互案例</title>
16 </head>
17 <body>
18 <div id="app">
19   <h2>父组件num1的值->data:{{num1}}</h2>
20   <p>-----------------------父子组件分隔符-----------------------------</p>
21   <h2>以下是父组件调用子组件</h2>
22   <cpn :cnum1="num1"></cpn>
23 </div>
24 <template id="cpn">
25   <div>
26     <h2>子组件cnum1的值->props:{{cnum1}}</h2>
27     <label for="input1">子组件的输入框绑定的是cnum1:</label>
28     <input id="input1" type="text" v-model="cnum1">
29   </div>
30 </template>
31 <script src="../js/vue.js"></script>
32 <script>
33   const cpn = {
34     template: '#cpn',
35     props: {
36       cnum1: Number
37     }43   }
44 
45   const app = new Vue({
46     el: '#app',
47     data: {
48       num1: 0
49     },
50     components: {
51       cpn
52     }
53   })
54 </script>
55 </body>
56 </html>

 

界面可以实现输入框与props.cnum1的双向绑定,但是页面报错,vue不希望子组件绑定props内的值,只希望父组件与子组件通信是使用props

 

 

 2.这个时候子组件的input的v-model双向绑定就不能绑定props内的属性了,需要在子组件内部data函数中另外定义一个变量来存放数据。此处用cdnum1

代码如下:

 1 <!--
 2 @author:invoker
 3 @project:project_lianxi
 4 @file: 13-父子组件交互南里.html
 5 @contact:invoker2021@126.com
 6 @descript:
 7 @Date:2021/7/4 21:50
 8 @version: html5
 9 -->
10 
11 <!DOCTYPE html>
12 <html lang="en">
13 <head>
14   <meta charset="UTF-8">
15   <title>13-父子组件交互案例</title>
16 </head>
17 <body>
18 <div id="app">
19   <h2>父组件num1的值->data:{{num1}}</h2>
20   <p>-----------------------父子组件分隔符-----------------------------</p>
21   <h2>以下是父组件调用子组件</h2>
22   <cpn :cnum1="num1"></cpn>
23 </div>
24 <template id="cpn">
25   <div>
26     <h2>子组件cnum1的值->props:{{cnum1}}</h2>
27 <!--    <label for="input1">子组件的输入框绑定的是cnum1:</label>-->
28     <!--    <input id="input1" type="text" v-model="cnum1">-->
29     <h2>子组件的cdnum1的值->data:{{cdnum1}}</h2>
30     <label for="input2">子组件的输入框绑定的是cdnum1:</label>
31     <input id="input2" type="text" v-model="cdnum1">
32 
33   </div>
34 </template>
35 <script src="../js/vue.js"></script>
36 <script>
37   const cpn = {
38     template: '#cpn',
39     props: {
40       cnum1: Number
41     },
42     data() {
43       return {
44         cdnum1: this.cnum1
45       }
46     }
47   }
48 
49   const app = new Vue({
50     el: '#app',
51     data: {
52       num1: 0
53     },
54     components: {
55       cpn
56     }
57   })
58 </script>
59 </body>
60 </html>

子组件cpn定义data.cdnum1,然后在input内使用 v-model双向绑定cdnum1,这么做实现了input输入后直接改变cdnum1的需求。

 

 

 问题又来了,如何变更父组件的num1呢?需要使用v-model的实现原理中@input,监听input事件,再通过Input事件的方法中使用自定义事件发射数据给父组件,父组件再使用自定义事件的方法来改变传过来的值。

代码如下:

 1 <!--
 2 @author:invoker
 3 @project:project_lianxi
 4 @file: 13-父子组件交互南里.html
 5 @contact:invoker2021@126.com
 6 @descript:
 7 @Date:2021/7/4 21:50
 8 @version: html5
 9 -->
10 
11 <!DOCTYPE html>
12 <html lang="en">
13 <head>
14   <meta charset="UTF-8">
15   <title>13-父子组件交互案例</title>
16 </head>
17 <body>
18 <div id="app">
19   <h2>父组件num1的值->data:{{num1}}</h2>
20   <p>-----------------------父子组件分隔符-----------------------------</p>
21   <h2>以下是父组件调用子组件</h2>
22   <cpn :cnum1="num1" @childcdnumchange="num1change"></cpn>
23 </div>
24 <template id="cpn">
25   <div>
26     <h2>子组件cnum1的值->props:{{cnum1}}</h2>
27     <!--    <label for="input1">子组件的输入框绑定的是cnum1:</label>-->
28     <!--    <input id="input1" type="text" v-model="cnum1">-->
29     <h2>子组件的cdnum1的值->data:{{cdnum1}}</h2>
30     <!--    <label for="input2">子组件的输入框绑定的是cdnum1:</label>-->
31     <!--    <input id="input2" type="text" v-model="cdnum1">-->
32     <label for="input3">子组件的输入框绑定的是cdnum1:</label>
33     <input id="input3" type="text" :value="cdnum1" @input="emitCdnumToFather">
34 
35   </div>
36 </template>
37 <script src="../js/vue.js"></script>
38 <script>
39   const cpn = {
40     template: '#cpn',
41     props: {
42       cnum1: Number
43     },
44     data() {
45       return {
46         cdnum1: this.cnum1
47       }
48     },
49     methods:{
50       emitCdnumToFather(event){
51         this.cdnum1 = event.target.value
52         this.$emit('childcdnumchange',this.cdnum1)
53       }
54     }
55   }
56 
57   const app = new Vue({
58     el: '#app',
59     data: {
60       num1: 0
61     },
62     components: {
63       cpn
64     },
65     methods:{
66       num1change(value){
67         this.num1 = value
68       }
69     }
70   })
71 </script>
72 </body>
73 </html>

代码解释:

1.input中不使用v-model,因为v-model只能双向绑定数据,暂时无法使用自定义事件。

2.input中使用 v-bind:value="cdnum1"来绑定cdnum1的数据。

3.input中使用 v-on:input来监听input事件。

4.监听到input事件则调用emitCdnumToFather方法,这个方法做了2件事件,第一,将实时输入事件的值传给cdnum1,实现了v-model的双向绑定。第二件事件,定义了自定义事件childcdnumchange,即子组件中的cdnum1发送改变,则将cdnum1的值作为事件参数传给父组件。

5.父组件在使用子组件时,创建监听该自定义事件 <cpn @childcdnumchange="num1change"  :cnum1="num1"/>,并创建一个方法执行 num1change

6.在父组件的num1change中将传入的cdnum1的值value赋值给父组件的num1

 

结果如下:实现了子组件双向绑定,且改变子组件的值可以同时改变父组件的值。

第一步改变子组件input内的值cdnum1

第二步双向绑定改变父组件num1的值

第三步父组件通过props将父组件的值传给子组件的props

 

 

报错原因:因为子组件输入框输入的是string类型,需要传唤成Number类型。

因此,在父组件的num1change方法中需要使用类型转换

 

 

代码如下:

 1 <!--
 2 @author:invoker
 3 @project:project_lianxi
 4 @file: 13-父子组件交互南里.html
 5 @contact:invoker2021@126.com
 6 @descript:
 7 @Date:2021/7/4 21:50
 8 @version: html5
 9 -->
10 
11 <!DOCTYPE html>
12 <html lang="en">
13 <head>
14   <meta charset="UTF-8">
15   <title>13-父子组件交互案例</title>
16 </head>
17 <body>
18 <div id="app">
19   <h2>父组件num1的值->data:{{num1}}</h2>
20   <p>-----------------------父子组件分隔符-----------------------------</p>
21   <h2>以下是父组件调用子组件</h2>
22   <cpn :cnum1="num1" @childcdnumchange="num1change"></cpn>
23 </div>
24 <template id="cpn">
25   <div>
26     <h2>子组件cnum1的值->props:{{cnum1}}</h2>
27     <!--    <label for="input1">子组件的输入框绑定的是cnum1:</label>-->
28     <!--    <input id="input1" type="text" v-model="cnum1">-->
29     <h2>子组件的cdnum1的值->data:{{cdnum1}}</h2>
30     <!--    <label for="input2">子组件的输入框绑定的是cdnum1:</label>-->
31     <!--    <input id="input2" type="text" v-model="cdnum1">-->
32     <label for="input3">子组件的输入框绑定的是cdnum1:</label>
33     <input id="input3" type="text" :value="cdnum1" @input="emitCdnumToFather">
34 
35   </div>
36 </template>
37 <script src="../js/vue.js"></script>
38 <script>
39   const cpn = {
40     template: '#cpn',
41     props: {
42       cnum1: Number
43     },
44     data() {
45       return {
46         cdnum1: this.cnum1
47       }
48     },
49     methods:{
50       emitCdnumToFather(event){
51         this.cdnum1 = event.target.value
52         this.$emit('childcdnumchange',this.cdnum1)
53       }
54     }
55   }
56 
57   const app = new Vue({
58     el: '#app',
59     data: {
60       num1: 0
61     },
62     components: {
63       cpn
64     },
65     methods:{
66       num1change(value){
67         this.num1 = parseInt(value)
68       }
69     }
70   })
71 </script>
72 </body>
73 </html>

 

posted @ 2021-07-04 23:46  kaer_invoker  阅读(82)  评论(0编辑  收藏  举报