add Vue.js 2.x:子组件给父组件传值
This commit is contained in:
		
							parent
							
								
									2c9259c8fd
								
							
						
					
					
						commit
						2303ff6f8b
					
				@ -137,6 +137,24 @@ git cherry-pick commit1
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## git客户端推荐
 | 
			
		||||
 | 
			
		||||
20180623时,网上看了下Git客户端的推荐排名:
 | 
			
		||||
 | 
			
		||||
20180623_1210.png
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### SmartGit
 | 
			
		||||
 | 
			
		||||
商业用途收费, 个人用户免费:
 | 
			
		||||
 | 
			
		||||
20180623_1305.png
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## 推荐书籍
 | 
			
		||||
 | 
			
		||||
@ -90,8 +90,13 @@ Vue.component('myComponent', myAccount); //第一个参数是组件的名称(
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
所以,为了避免名字不一致的问题,我们注册组件时,组件的名称可以直接写成`my-component`。比如:(避免驼峰不一致的建议写法)
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
    Vue.component('my-component', myAccount);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
`Vue.component('my')`
 | 
			
		||||
 | 
			
		||||
**注意2**、绿框部分,一定要用一个大的根元素(例如`<div>`)包裹起来。如果我写成下面这样,就没有预期的效果:
 | 
			
		||||
 | 
			
		||||
@ -161,7 +166,7 @@ Vue.component('myComponent', myAccount); //第一个参数是组件的名称(
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 写法三
 | 
			
		||||
### 写法三【荐】
 | 
			
		||||
 | 
			
		||||
> 上面的写法一、写法二并不是很智能,因为在定义模板的时候,没有智能提示和高亮,容易出错。我们不妨来看看写法三。
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,7 @@
 | 
			
		||||
 | 
			
		||||
需要注意的是,子组件不能直接使用父组件中的数据。**父组件可以通过`props`属性向子组件传值**。
 | 
			
		||||
 | 
			
		||||
代码举例:
 | 
			
		||||
### 父组件向子组件传值的代码举例
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
@ -23,26 +23,27 @@
 | 
			
		||||
 | 
			
		||||
<body>
 | 
			
		||||
    <div id="app">
 | 
			
		||||
        <!--第二步:父组件在引用子组件的时候, 通过 属性绑定(v-bind:)的形式, 把 需要传递给 子组件的数据,以属性绑定的形式,传递到子组件内部,供子组件使用 -->
 | 
			
		||||
        <component1 v-bind:parent-msg="msg"></component1>
 | 
			
		||||
        <!--第三步:父组件在引用子组件的时候, 通过 属性绑定(v-bind:)的形式, 把 需要传递给 子组件的数据,以属性绑定的形式,传递到子组件内部,供子组件使用 -->
 | 
			
		||||
        <component1 v-bind:parent-msg="msg"></component1> 
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <!-- 定义子组件的模板 -->
 | 
			
		||||
    <template id="myTemplate">
 | 
			
		||||
        <h1 @click="change">我是子组件。我想使用父组件中的数据parentMsg: {{ parentMsg }}</h1>
 | 
			
		||||
        <!-- 第二步:在子组件的模板中,使用props中的属性 -->
 | 
			
		||||
        <h2 @click="change">我是子组件。我想使用父组件中的数据parentMsg: {{ parentMsg }}</h2>
 | 
			
		||||
    </template>
 | 
			
		||||
 | 
			
		||||
    <script>
 | 
			
		||||
        // 创建 Vue 实例,得到 ViewModel
 | 
			
		||||
        var vm = new Vue({
 | 
			
		||||
            el: '#app',
 | 
			
		||||
            el: '#app', 
 | 
			
		||||
            data: {
 | 
			
		||||
                msg: '父组件中的数据123'
 | 
			
		||||
            },
 | 
			
		||||
            }, 
 | 
			
		||||
            methods: {},
 | 
			
		||||
            components: {
 | 
			
		||||
                // 子组件默认无法访问到 父组件中的 data 中的数据 和 methods 中的方法
 | 
			
		||||
                component1: {
 | 
			
		||||
                component1: { //将子组件的名称定义为 component1
 | 
			
		||||
                    template: '#myTemplate',
 | 
			
		||||
                    data() { // 注意: 子组件中的 data 数据,并不是通过 父组件传递过来的,而是子组件自身私有的,比如: 子组件通过 Ajax ,请求回来的数据,都可以放到 data 身上;
 | 
			
		||||
                        // data 上的数据,都是可读可写的
 | 
			
		||||
@ -50,7 +51,7 @@
 | 
			
		||||
                            title: '子组件私有的数据 title',
 | 
			
		||||
                            content: '子组件私有的数据 content'
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                    }, 
 | 
			
		||||
                    // 注意: 组件中的 所有 props 中的数据,都是通过 父组件 传递给子组件的
 | 
			
		||||
                    // props 中的数据,都是只读的,无法重新赋值(也就是说,)
 | 
			
		||||
                    props: ['parentMsg'], // 第一步:把父组件传递过来的 parentmsg 属性,先在 props 数组中,定义一下,这样,才能使用这个数据
 | 
			
		||||
@ -82,17 +83,269 @@
 | 
			
		||||
20180618_2355.png
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
**父组件给字组件传值的步骤**:
 | 
			
		||||
**父组件给子组件传值的步骤**:
 | 
			
		||||
 | 
			
		||||
> 根据上方截图,我们可以总结出父组件给子组件传值的步骤。
 | 
			
		||||
> 根据上方截图,我们可以总结出父组件给子组件传值的步骤如下。
 | 
			
		||||
 | 
			
		||||
子组件中,data中的数据和props中的数据的区别:
 | 
			
		||||
(1)在子组件的`props`属性中声明父亲传递过来的数据
 | 
			
		||||
 | 
			
		||||
-
 | 
			
		||||
(2)定义子组件的模板时,使用props中的属性
 | 
			
		||||
 | 
			
		||||
(3)父组件在引用子组件时,进行属性绑定。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
**子组件中,data中的数据和props中的数据的区别**:
 | 
			
		||||
 | 
			
		||||
- 子组件中的 data 数据,并不是通过 父组件传递过来的,而是子组件自身私有的,比如: 子组件通过 Ajax ,请求回来的数据,都可以放到 data 身上。props 中的数据,都是通过 父组件 传递给子组件的。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- data中的数据是可读可写的;props中的属性只是可读的,无法重新赋值,重新赋值会报错(也就是说,子组件不要直接去修改父组件中的数据)。
 | 
			
		||||
 | 
			
		||||
### 父组件将方法传递给子组件
 | 
			
		||||
 | 
			
		||||
> 父组件通过事件绑定机制,将父组件的方法传递给子组件
 | 
			
		||||
 | 
			
		||||
代码举例:
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
 | 
			
		||||
<head>
 | 
			
		||||
    <meta charset="UTF-8">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
			
		||||
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
 | 
			
		||||
    <title>Document</title>
 | 
			
		||||
    <script src="vue2.5.16.js"></script>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body>
 | 
			
		||||
    <div id="app">
 | 
			
		||||
        <!-- 父组件向子组件 传递 方法,是通过 事件绑定机制; v-on。当我们自定义了 一个 事件属性 parent-show(这个地方不能用驼峰命名)之后,那么,子组件就能够,通过 emit 来调用 传递进去的 这个 方法了 -->
 | 
			
		||||
        <!-- 【第一步】。意思是说,`show`是父组件的方法名,`parent-show`是自定义的时间属性,稍后要在子组件中用到 -->
 | 
			
		||||
        <component1 @parent-show='show'></component1>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <!-- 定义子组件的模板 -->
 | 
			
		||||
    <template id="myTemplate">
 | 
			
		||||
        <!-- 【第二步】按照正常的写法来:点击按钮,调用子组件的方法 -->
 | 
			
		||||
        <h2 @click="childClick">我是子组件,点击调用父组件的方法</h2>
 | 
			
		||||
    </template>
 | 
			
		||||
 | 
			
		||||
    <script>
 | 
			
		||||
        // 创建 Vue 实例,得到 ViewModel
 | 
			
		||||
        var vm = new Vue({
 | 
			
		||||
            el: '#app',
 | 
			
		||||
            data: { //父组件的data
 | 
			
		||||
                // msg: '父组件中的数据'
 | 
			
		||||
            },
 | 
			
		||||
            methods: {
 | 
			
		||||
                show: function () { // 定义父组件的show方法
 | 
			
		||||
                    console.log('父组件提供的方法');
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            components: {
 | 
			
		||||
                component1: { //将子组件的名称定义为 component1
 | 
			
		||||
                    template: '#myTemplate',
 | 
			
		||||
                    data() { // 子组件的data
 | 
			
		||||
                        return {
 | 
			
		||||
                            // content: '子组件私有的数据 content'
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                    props: [''],
 | 
			
		||||
                    directives: {},
 | 
			
		||||
                    filters: {},
 | 
			
		||||
                    components: {},
 | 
			
		||||
                    methods: {
 | 
			
		||||
                        childClick() {
 | 
			
		||||
                            // 当点击子组件的按钮时,如何 拿到 父组件传递过来的 func 方法,并调用这个方法???
 | 
			
		||||
                            //  emit 英文原意: 是触发,调用、发射。意思是,触发父组件的方法
 | 
			
		||||
                            // 【第三步】 在子组件的方法中,通过 emit 触发父组件的方法
 | 
			
		||||
                            this.$emit('parent-show');
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    </script>
 | 
			
		||||
</body>
 | 
			
		||||
 | 
			
		||||
</html>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
效果如下:(点击子组件,触发了父组件的方法)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
根据上面的代码,我们可以总结出,父组件将方法传递给子组件,分为三步,具体可以看上方代码的注释。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## 子组件向父组件传值
 | 
			
		||||
 | 
			
		||||
上面的一段中,我们再看一遍**父组件将方法传递给子组件**的这段代码(一定要再看一遍,因为我们是要在此基础之上做修改)。
 | 
			
		||||
 | 
			
		||||
如果要实现**子组件向父组件传值**,代码是类似的,我们只需要在子组件通过`emit`触发父组件的方法时,把子组件的参数带出去就可以了。代码如下。
 | 
			
		||||
 | 
			
		||||
**代码举例1**:(将子组件中的常量传递给父组件)
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
 | 
			
		||||
<head>
 | 
			
		||||
    <meta charset="UTF-8">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
			
		||||
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
 | 
			
		||||
    <title>Document</title>
 | 
			
		||||
    <script src="vue2.5.16.js"></script>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body>
 | 
			
		||||
    <div id="app">
 | 
			
		||||
        <component1 @parent-show='show'></component1>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <!-- 定义子组件的模板 -->
 | 
			
		||||
    <template id="myTemplate">
 | 
			
		||||
        <h2 @click="childClick">我是子组件,点击调用父组件的方法</h2>
 | 
			
		||||
    </template>
 | 
			
		||||
 | 
			
		||||
    <script>
 | 
			
		||||
        // 创建 Vue 实例,得到 ViewModel
 | 
			
		||||
        var vm = new Vue({
 | 
			
		||||
            el: '#app',
 | 
			
		||||
            data: { //父组件的data
 | 
			
		||||
                // msg: '父组件中的数据'
 | 
			
		||||
            },
 | 
			
		||||
            methods: { // 定义父组件的方法
 | 
			
		||||
                show: function (arg1, arg2) { //【第二步】父组件里放两个参数,这个两个参数就代表着子组件中的`child 123`、`child 789`
 | 
			
		||||
                    console.log('父组件提供的方法');
 | 
			
		||||
                    console.log('打印子组件传递过来的参数。参数一:' + arg1 + ',参数二:'+ arg2);
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            components: {
 | 
			
		||||
                component1: { //将子组件的名称定义为 component1
 | 
			
		||||
                    template: '#myTemplate',
 | 
			
		||||
                    data() { // 子组件的data
 | 
			
		||||
                        return {
 | 
			
		||||
                            // content: '子组件私有的数据 content'
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                    props: [''],
 | 
			
		||||
                    directives: {},
 | 
			
		||||
                    filters: {},
 | 
			
		||||
                    components: {},
 | 
			
		||||
                    methods: {
 | 
			
		||||
                        childClick() {
 | 
			
		||||
                            // 子组件如果要给父组件传递参数,在触发 emit 的时候,通过参数的形式带出去就可以了
 | 
			
		||||
                            // 【第一步】在子组件里,我们带两个参数出去,传给父组件
 | 
			
		||||
                            this.$emit('parent-show', 'child 123', 'child 789');
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    </script>
 | 
			
		||||
</body>
 | 
			
		||||
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
运行结果:(点击`<h2>`之后)
 | 
			
		||||
 | 
			
		||||
20180623_1640.png
 | 
			
		||||
 | 
			
		||||
**代码举例2**:(将子组件中的data数据传递给父组件,存放到父组件的data中)
 | 
			
		||||
 | 
			
		||||
> 在上方代码的基础之上,做改进。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
 | 
			
		||||
<head>
 | 
			
		||||
    <meta charset="UTF-8">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
			
		||||
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
 | 
			
		||||
    <title>Document</title>
 | 
			
		||||
    <script src="vue2.5.16.js"></script>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body>
 | 
			
		||||
    <div id="app">
 | 
			
		||||
        <component1 @parent-show='show'></component1>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <!-- 定义子组件的模板 -->
 | 
			
		||||
    <template id="myTemplate">
 | 
			
		||||
        <h2 @click="childClick">我是子组件,点击调用父组件的方法</h2>
 | 
			
		||||
    </template>
 | 
			
		||||
 | 
			
		||||
    <script>
 | 
			
		||||
        // 创建 Vue 实例,得到 ViewModel
 | 
			
		||||
        var vm = new Vue({
 | 
			
		||||
            el: '#app',
 | 
			
		||||
            data: { //父组件的data
 | 
			
		||||
                parentData: null
 | 
			
		||||
            },
 | 
			
		||||
            methods: { // 定义父组件的方法
 | 
			
		||||
                show: function (arg) { //【第二步】父组件里放参数,这个参数就代表着子组件中的 child.data
 | 
			
		||||
                    console.log('父组件提供的方法');
 | 
			
		||||
                    this.parentData = arg; //将参数arg传递给父组件的data,也就达到了目的:子组件传递数据,赋值给父组件
 | 
			
		||||
                    console.log('打印父组件的数据(这是子组件传过来的):'+ JSON.stringify(this.parentData));
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            components: {
 | 
			
		||||
                component1: { //将子组件的名称定义为 component1
 | 
			
		||||
                    template: '#myTemplate',
 | 
			
		||||
                    data() { // 子组件的data
 | 
			
		||||
                        return {
 | 
			
		||||
                            childData: { //定义自组件的数据
 | 
			
		||||
                                name: 'smyhvae',
 | 
			
		||||
                                age: 26
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                    props: [''],
 | 
			
		||||
                    directives: {},
 | 
			
		||||
                    filters: {},
 | 
			
		||||
                    components: {},
 | 
			
		||||
                    methods: {
 | 
			
		||||
                        childClick() {
 | 
			
		||||
                            // 子组件如果要给父组件传递参数,在触发 emit 的时候,通过参数的形式带出去就可以了
 | 
			
		||||
                            // 【第一步】在子组件里,通过传参的形式,把子组件的data,传给父组件
 | 
			
		||||
                            this.$emit('parent-show', this.childData);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    </script>
 | 
			
		||||
</body>
 | 
			
		||||
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
运行结果:(点击`<h2>`之后)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
20180623_1655.png
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## 案例:发表评论功能的实现
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,8 @@
 | 
			
		||||
 | 
			
		||||
前端入门和进阶学习笔记。从零开始学前端,做一个web全栈工程师。持续更新...
 | 
			
		||||
 | 
			
		||||
更多内容,请点开文件夹。
 | 
			
		||||
 | 
			
		||||
维护这个项目的初衷,可以看这篇文章:[裸辞两个月,海投一个月,从Android转战Web前端的求职之路](https://mp.weixin.qq.com/s/fr_NwtghRQagc_3ubk-hKQ)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
另外,欢迎关注本人的公众号「生命团队」,会分享一些技术之外的软技能(和代码完全无关)。公众号里的每篇文章,自认为写得还算用心。“全栈”不应该只是体现在技术上,而是全方位。
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								推荐链接-互联网相关.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								推荐链接-互联网相关.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 2018-06-23
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- [王兴:今年移动互联网会非常惨烈,很多想象不到的公司都会死掉](http://www.ctoutiao.com/136601.html?from=timeline&isappinstalled=0)
 | 
			
		||||
 | 
			
		||||
@ -159,5 +159,15 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 2018-06-23
 | 
			
		||||
 | 
			
		||||
- [技术的热门度曲线](http://www.ruanyifeng.com/blog/2017/03/gartner-hype-cycle.html)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user