二、Vue组件(component):组件的相互引用、通过props实现父子组件互传值
一、组件各部分说明及互相引用
1.一个vue组件由三个部分组成
Template
只能存在一个根元素
2.Script
3.Style
scoped:样式只在当前组件内生效
1.1 组件的基本引用代码示例
重点:第1步,app.vue;第2步,father.vue
0、src/main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'//【重点1】引入vue.js
import App from './App'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({//【重点】创建vue组件实例
el: '#app', //[1]:在index.html里id为#app标签里写入组件内容
components: { App },//[2]:写入的组件
template: '<App/>' //[3]:写入的模板名(也可看成一个完整组件)
})
第1步,src/APP.vue引入子组件示例
<template>
<div id="app">
<img src="./assets/logo.png">
<Father /> <!-- 【2】第2步,调用子组件 -->
</div>
</template>
<script>
import Father from './components/father' //【1】第1步,引入子组件
export default {
name: 'App',
components: {
Father //【3】第3步,把组件写到此处,目的是把它暴露出去
},
data () {//【data必须是一个函数】此为标准es6写法,也可写成data:function(),这样才能对每个实例可以维护一份被返回对象的独立的拷贝
return {
msg: 'hello',
}
},
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
第2步,src/components/father.vue
<template>
<div> <!-- 第一层只能有一个根标签 -->
父组件
<Child /> <!-- 【2】第2步,调用子组件 -->
</div>
</template>
<script>
import Child from './child' //【1】第1步,引入子组件
export default{//需要暴露出去的内容都要写在此处,这样才能被其它组件使用用
name:'Father',//当前组件名
components:{//【3】第3步,把组件写到此处,目的是把它暴露出去(其对应import xxx)中的xxx
Child,
},
data(){//data必须是一个函数】此为标准es6写法,也可写成data:function(),这样每个实例可以维护一份被返回对象的独立的拷贝
return{msg:'father'} //此处一定要记得return
},
}
</script>
<style scoped> /* [4]知识点4,此处写的样式只对当前father.vue组件生效 */
</style>
第3步,src/components/child.vue
<template>
<div>
子组件
</div>
</template>
<script>
export default{
name:'child',
data(){
return{ tit:'child'}
}
}
</script>
<style scoped>
</style>
效果:
父组件
子组件
二、父-->子组件通信(交互)props----父传子
1.通过设置子组件的Props(道具)接收父组件的传值代码示例
father.vue
1、父组件设置一个属性:(如name=xxx)
<template>
<div>
<h1>主题:父组件向子组件传值</h1>
<Child title='父组件的数据' /> <!-- 【1】第1步,建一个属性title=xx,写入xx数据 -->
</div>
</template>
<script>
import Child from './child'
export default{
name:'Father',
components:{
Child,
},
data(){
return {msg:'father'}
},
}
</script>
<style scoped>
</style>
child.vue
2、子组件通过设置props接收父组件传过来的内容:props:[ 'name' ]或 props:{name:{type:String,default:''}}
3、显示父组件传的内容:{{name}}
<template>
<div>
<!-- 【3】显示父组件传过来的值 -->
<h2>子组件:{{title}}</h2>
</div>
</template>
<script>
export default{
name:'child',
data(){
return{}
},
props:["title"] #【2】通过props接收父组件传的数据
}
</script>
<style scoped>
</style>
效果:箭头部分即父组件title=xxx,传过来的值
2.向子组件传data里的动态数据
father.vue
1、在data(){title:'title content'}
2、把<child title=xxx />
中的xx换成data里的title
<template>
<div>
<h1>主题:父组件向子组件传data里的动态值</h1>
<Child v-bind:title="msg" /> <!-- 【1】第1步,title=xx,的内容写成data里的属性名 -->
</div>
</template>
<script>
import Child from './child'
export default{
name:'Father',
components:{
Child,
},
data(){
return {
msg:"父组件data内的动态的数据",//【1】数据里写一个属性:值;
}
},
}
</script>
<style scoped>
</style>
child.vue
3、child里不变
<template>
<div>
<!-- 【2】显示父组件传过来的值 -->
<h2>子组件:{{title}}</h2>
</div>
</template>
<script>
export default{
name:'child',
data(){
return{tit:'child'}
},
props:["title"]//[1]接收父组件的属性名(在father.vue里的<child title=xx /> )
}
</script>
<style scoped>
</style>
3.改变data里的msg,将自动传给子组件示例
<template>
<div>
<h1>主题:父组件向子组件传data里的动态值</h1>
<Child v-bind:title="msg" /> <!-- 【1】第1步,title=xx,的内容写成data里的属性名 -->
<button v-on:click="change_msg">改变一下</button>
</div>
</template>
<script>
import Child from './child'
export default{
name:'Father',
components:{
Child,
},
data(){
return {
msg:"父组件data内的动态的数据",//【1】数据里写一个属性:值;
}
},
methods:{
change_msg(event){//按键的处理函数
this.msg='改变一下msg消息'
}
}
}
</script>
<style scoped>
</style>
效果:
4.子组件通过props,父组件的v-model,随时获取表单数据示例
father.vue
【1】第1步,再定义一个数据,初始数据随便设置
【2】第2步,再v-bind绑定第2个属性msg(此可随便设置,子组件的props对应即可)为data里的msg2
【3】第3步,在表单里绑定data里的msg2
<template>
<div>
<h1>主题:父组件通过v-model实时向子组件传data里的值</h1>
<input v-model="msg2" /> <!-- 【3】第3步,在表单里绑定data里的msg2 -->
<Child v-bind:title="msg" v-bind:msg='msg2' /> <!-- 【2】第2步,再v-bind绑定第2个属性msg(此可随便设置,子组件的props对应即可)为data里的msg2 -->
<button v-on:click="change_msg">改变一下</button>
</div>
</template>
<script>
import Child from './child'
export default{
name:'Father',
components:{
Child,
},
data(){
return {
msg:"父组件data内的动态的数据",//数据里写一个属性:值;
msg2:'父向子组件传递的第2个数据'//【1】第1步,再定义一个数据,初始数据随便设置
}
},
methods:{
change_msg(event){
this.msg='改变一下msg消息'
}
}
}
</script>
<style scoped>
</style>
child.vue
【1】接收父组件的属性1、2的名字title,msg(在father.vue里的<child title= msg= />
【2】显示父组件传过来的属性1,属性2
<template>
<div>
<!-- 【2】显示父组件传过来的属性1,属性2 -->
<h2>子组件:{{title}}--{{msg}}</h2>
</div>
</template>
<script>
export default{
name:'child',
data(){
return{ tit:'child'}
},
props:["title","msg"]//[1]接收父组件的属性1、2的名子(在father.vue里的<child title=xx msg=xxx /> )
}
</script>
<style scoped>
</style>
效果:输入框值变动,子组件随时跟着变动
5.通过子组件的props限制父组件传过来的数据类型
father.vue
【1】再定义一个数据
【2】第2步,对子组件,再加个v-bind绑定第2个属性age(此可随便设置,子组件的props对应即可)为data里的num
<template>
<div>
<h1>主题:父组件通过v-model实时向子组件传data里的值</h1>
<input v-model="msg2" />
<Child v-bind:title="msg" v-bind:msg='msg2' :age='num' /> <!-- 【2】第2步,再v-bind绑定第2个属性age(此可随便设置,子组件的props对应即可)为data里的num -->
<button v-on:click="change_msg">改变一下</button>
</div>
</template>
<script>
import Child from './child'
export default{
name:'Father',
components:{
Child,
},
data(){
return {
msg:"父组件data内的动态的数据",//数据里写一个属性:值;
msg2:'父向子组件传递的第2个数据',
num:'hello'//【1】再定义一个数据
}
},
methods:{
change_msg(event){
this.msg='改变一下msg消息'
}
}
}
</script>
<style scoped>
</style>
child.vue
【1】把props改成字典写法,逐个对其属性的数据类型进行限定,把age的数据类型限定为数字
【2】显示父组件传过来的属性3:age
<template>
<div>
<!-- 【2】显示父组件传过来的属性1,属性2,属性3:age -->
<h2>子组件:{{title}}--{{msg}}----{{age*2}}</h2>
</div>
</template>
<script>
export default{
name:'child',
data(){
return{tit:'child'}
},
props:{//【1】把props改成字典写法,逐个对其属性的数据类型进行限定
title:String,
msg:String,
age:Number //此处把age的数据类型限定为数字
}//["title","msg","age"]//[1]接收父组件的属性1、2的名子(在father.vue里的<child title=xx msg=xxx /> )
}
</script>
<style scoped>
</style>
效果:
- 因为fahter.vue里的data的num数据类型为'hello'是字符串类型
- 又child.vue里的props限定了num必须为数字
- 所以控制台会报错:Invalid prop: type check failed for prop "age". Expected Number with value NaN, got String with value "hello".
- 只有父组件里的数据为数字(如Num=10),此处才能正确运行显示:20(num2=102)
5.2 子组件用props把父组件传过来的数据[限定为多种数据类型]、[设置为必需选项]
【1】设置为支持多种数据类型 title:[String,Number],父组件传的title值可以为字符串,或数字
【2】设置为是否必须选项,如果父组件没有传msg=xx这个属性,就报错
msg:{//【2】设置为是否必须选项
type:String,
required:true
}
原码:
<template>
<div>
<!-- 显示父组件传过来的属性1,属性2,属性3:age -->
<h2>子组件:{{title}}--{{msg}}----{{age*2}}</h2>
</div>
</template>
<script>
export default{
name:'child',
data(){
return {tit:'child'}
},
props:{
title:[String,Number],//【1】设置为支持多种数据类型
msg:{//【2】设置为是否必须选项
type:String,
required:true
},
age:Number,
}
}
</script>
<style scoped>
</style>
效果:父组件没传msg,警告信息
5.3在子组件props设置默认值(如果父不传,则使用默认值)
child.vue
<template>
<div>
<!-- 【2】显示父组件传过来的属性1,属性2,属性3:age -->
<h2>子组件:{{title}}--{{msg}}----{{age*2}}</h2>
</div>
</template>
<script>
export default{
name:'child',
data(){
return {tit:'child'}
},
props:{
title:[String,Number],
msg:{
type:String,
required:true
},
age:{//【1】设置默认值
type:Number,
default:5
}
}
}
</script>
<style scoped>
</style>
结果:父组件没传num,子组件用默认值5计算出来的值5*2=10
6.父组件data数据为字典时,向子组件props传值
father.vue
【1】第1步,设置一个字典的数据
【2】第2步,再v-bind绑定ojbData为data里的fatherObj
<template>
<div>
<h1>主题:父组件通过v-model实时向子组件传data里的【对象类型数据】值</h1>
<input v-model="msg2" />
<Child v-bind:title="msg" :msg="msg2" :objData="fatherObj" /> <!-- 【2】第2步,再v-bind绑定ojbData为data里的fatherObj -->
<button v-on:click="change_msg">改变一下</button>
</div>
</template>
<script>
import Child from './child'
export default{
name:'Father',
components:{
Child,
},
data(){
return {
msg:"父组件data内的动态的数据",
msg2:'父向子组件传递的第2个数据',
num:10,
fatherObj:{//【1】第1步,设置一个字典的数据
name:'flying',
age:22
}
}
},
methods:{
change_msg(event){
this.msg='改变一下msg消息'
}
}
}
</script>
<style scoped>
</style>
child.vue
【1】父组件传值是字典时,props的特殊写法
- 【1.1】此处数据类型必须设置为Object
- 【1.2】这里返回值"未知"、0等可随意,目的是如果父组件没有传对应的值,就用此默认的值
【2】显示父组件传过来的字典类型数据
<template>
<div>
<h2>子组件:{{title}}--{{msg}}----{{age*2}}</h2>
<!-- 【2】显示父组件传过来的字典类型数据 -->
<h3>子组件:父组件传的对象{{objData}}---名字是:{{objData.name}}</h3>
</div>
</template>
<script>
export default{
name:'child',
data(){
return {tit:'child'}
},
props:{
title:[String,Number],
msg:{
type:String,
required:true
},
age:{
type:Number,
default:5
},
objData:{//【1】父组件传值是字典时,props的特殊写法
type:Object, //【1.1】此处数据类型必须设置为Object
default:function(){
return{//【1.2】这里返回值"未知"、0等可随意,目的是如果父组件没有传对应的值,就用此默认的值
name:"未知",
age:0,
}
}
}
}
}
</script>
<style scoped>
</style>
效果:
子组件:父组件传的对象{ "name": "flying", "age": 22 }---名字是:flying
三、子 -> 父组件通信——子传父
3.1简单的子--->父通信
第1步:child.vue
【0】此处通过点击鼠标触发的函数向父组件发消息
【1】重点:传数据给父组件:this.$emit(键名,键值); 键名随便,父组件接收时要对应;键值此处用data里数据:this.msg
<template>
<div>
<!-- 【0】此处通过点击鼠标触发的函数向父组件发消息 -->
<button v-on:click="sendMsg">点此向父组件发消息</button>
</div>
</template>
<script>
export default{
name:'child',
data(){
return{
msg:'子组件发的消息'
}
},
methods:{
sendMsg(event){
/*【1】重点:固定写法:this.$emit(键名,键值); 键名随便。键值此处用data里数据:this.msg
父组件<child @sendmsg='处理函数'/>接收时@sendmsg处要对应;(把sendmsg当成一个自定义事件)
*/
this.$emit("sendmsg",this.msg)
}
}
}
</script>
<style>
</style>
第2步,parent.vue
【1】用监听事件命令v-on(简写@sendmsg(此名随便写)),监听到之后触发一个函数getMsg,用它来测试子组件发来的消息
[2]定义一个空数据用来接收子组件传来的消息
【3】把接收到的数据传给data里的msg
【4】展示子组件传过来的消息
<template>
<div>
父组件
<Child v-on:sendmsg='getMsg' /><!-- 【1】把sendmsg当自定义事件,所以要用监听事件命令v-on(简写@sendmsg(此名随便写)),监听到之后触发一个函数getMsg,用它来测试子组件发来的消息 -->
{{msg}}<!-- 【4】展示子组件传过来的消息 -->
</div>
</template>
<script>
import Child from './child';
export default{
name:'parent',
data(){
return{
msg:'' //[2]定义一个空数据用来接收子组件传来的消息
}
},
components:{
Child,
},
methods:{
getMsg(data){//此处data可随便写,下面和其对应即可
console.log(data); //测试【3】把子组件传的数据输出到控制台
this.msg=data;//【3】把接收到的数据传给data里的msg
}
}
}
</script>
<style>
</style>
效果:点击按钮之后,子组件即会发一个消息过来,父组件即接收,展示。
3.2父-->子-->父:父子组件的交互通信
parent.vue
【2.1】绑定data里的num(输入变<==>data.num变)
【2.2】把data的数据转换为Number类型,(this.num - 0,即是把此数据转为数字类型)
【2.3】向子组件传送的数据变为computed的toNum()函数处理后的值,即转为数字再传送给子组件
<template>
<div>
父组件
<!-- 【1】用监听事件命令v-on(简写@sendmsg(此名随便写)),监听到自定义事件sedmsg发生之后触发一个函数getMsg,用它来接收子组件发来的消息;
v-bind为向子组件发送的数据; -->
<Child v-on:sendmsg='getMsg' v-bind:num='toNum' /> <!-- 【2.3】向子组件传送的数据变为computed的toNum()函数处理后的值,即转为数字再传送给子组件 -->
<input type="text" v-model="num" /> <!-- 【2.1】绑定data里的num(输入变<==>data.num变) -->
{{msg}}<!-- 【5】展示子组件传过来的消息 -->
</div>
</template>
<script>
import Child from './child';
export default{
name:'parent',
data(){
return{
msg:'', //[3]定义一个空数据用来接收子组件传来的消息
num:5,
}
},
components:{
Child,
},
computed:{
toNum(){//【2.2】把data的数据转换为Number类型,(this.num -0,即是把此数据转为数字类型)
return this.num - 0;
}
},
methods:{//【2】用函数来接收子组件消息输出到控制台进行测试
getMsg(data){
console.log(data);
this.msg=data;//【4】把接收到的数据传给data里的msg
}
}
}
</script>
<style>
</style>
child.vue
[2.1]接收父组件传来的数据num()
【2.2】触发发送函数,向父组件发送数据
【2.3】调用computed里的addNum对收到父组件的数据处理处理后,再发给父组件
【2.4】把props里收到的num进行处理的函数
<template>
<div>
<!-- 【0】此处通过点击鼠标触发的函数,sendMsg通过其向父组件发消息 -->
<button v-on:click="sendMsg">点此向父组件发消息</button> 【2.2】触发
</div>
</template>
<script>
export default{
name:'child',
data(){
return{
msg:'子组件发的消息'
}
},
props:{//接收父组件数据道具
num:{//[2.1]接收父组件传来的数据num(<child v-bind:num='toNum'/>)
type:Number,
default:8
}
},
computed:{
addNum(){//【2.4】把props里收到的num进行处理的函数
return this.num*10;
}
},
methods:{
sendMsg(event){
//【1】重点:固定写法:this.$emit(键名,键值); 键名随便,父组件接收时要对应;键值此处用data里数据:this.msg
this.$emit("sendmsg",this.addNum) //【2.3】调用computed里的addNum对收到父组件的数据处理处理后,再发给父组件
}
},
}
</script>
<style>
</style>
效果:在输入框输入数字,子组件接收,处理后,发回父组件显示
二、Vue组件(component):组件的相互引用、通过props实现父子组件互传值的更多相关文章
- vue.js使用props在父子组件之间传参
本篇文章是我参考官方文档整理的,供大家参考,高手勿喷! prop 组件实例的作用域是孤立的.这意味着不能 (也不应该) 在子组件的模板内直接引用父组件的数据.要让子组件使用父组件的数据,我们需要通过子 ...
- Vue.js-----轻量高效的MVVM框架(十、父子组件通信)
#1.父链 html: <h3>#父链</h3> <div> <div>子组件可以用 this.$parent 访问它的父组件.根实例的后代可以用 th ...
- vue 父子组件相互传递数据
例子一 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta ...
- Vue父子组件之间的相互通信
组件是Vue知识体系中最重要的一部分之一,父子组件由于作用域的不同,无法直接对对方的数据进行操作.它们之间的数据传递都是通过中间介质进行的,父组件给子组件传值是通过props属性,而子组件给父组件传值 ...
- 【Vue】Vue中的父子组件通讯以及使用sync同步父子组件数据
前言: 之前写过一篇文章<在不同场景下Vue组件间的数据交流>,但现在来看,其中关于“父子组件通信”的介绍仍有诸多缺漏或者不当之处, 正好这几天学习了关于用sync修饰符做父子组件数据双向 ...
- vue父子组件(1.0)
1.父子组件 在上一篇随笔中展示了vue的组件,当我们继续在组件中写组件,形成组件嵌套的时候,就是我们所说的父子组件了. <!DOCTYPE html> <html lang=&qu ...
- Vue的父子组件间通信及借助$emit和$on解除父子级通信的耦合度高的问题
1.父子级间通信,父类找子类非常容易,直接在子组件上加一个ref,父组件直接通过this.$refs操作子组件的数据和方法 父 这边子组件中 就完成了父 => 子组件通信 2. 子 =&g ...
- vue 父子组件通信详解
这是一篇详细讲解vue父子组件之间通信的文章,初始学习vue的时候,总是搞不清楚几个情况 通过props在父子组件传值时,v-bind:data="data",props接收的到底 ...
- vue组件通信之父子组件通信
准备工作: 首先,新建一个项目,如果这里有不会的同学,可以参考我转载过的文章 http://www.cnblogs.com/Sky-Ice/p/8875958.html vue 脚手架安装及新建项目 ...
随机推荐
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 排版:地址(Address)
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- Java基础 -2.4
字符型char类型 在任何的编程语言之中,字符都可以与int进行互相转换,也就是这个字符中所描述的内容可以通过int获取其内容所在的系统编码 public class ddd { public sta ...
- Python组合类型笔记
Python中常用的三种组合数据类型,分别是: - 集合类型 - 序列类型 - 字典类型 1. 集合类型: -集合用大括号{}表示,元素间用逗号分隔 -建立集合类型用{}或set() -建立空集合类型 ...
- 布线问题&魔法花园_最短路径
布线问题 问题描述:印刷电路板将布线区域划分成n×m个方格阵列,精确的电路布线问题要求确定连接方格a到方格b的最短布线方案:布线时,电路只能沿着直线或直角(方格)布线:已经布线的方格被锁定,即不允许其 ...
- vmware 因误删Linux 虚拟机磁盘,无法启动处理方法
有可能我们在做了以下误操作,导致Linux系统无法启动: 1). 磁盘损坏或虚拟机磁盘被我们删除了,而fstab文件没有更新: 2). 由于误操作或其它原因使动态库错误. 1. 首先准备好系统安装盘, ...
- centos7中redis安装
官网地址:http://redis.io/ 官网下载地址:http://redis.io/download 1. 下载Redis源码(tar.gz),并上传到Linux:或 wget http://d ...
- 深浅copy浅析
Python代码在开始执行的时候,代码会被系统从硬盘调入内存,等候CPU执行,至于怎么个调入逻辑,还不清楚. 在高级语言中,变量是对内存及其地址的抽象.也就是说变量就是内存地址. 那么我们先来介绍两种 ...
- 移动端300毫秒事件响应延迟解决方法[fastclick]
vue-cli[2.x]中: 安装 npm install fastclick --save 使用: 在main.js中 :先 import fastClick from 'fastclick' 然后 ...
- Py西游攻关之基础数据类型(四)-字典
Py西游攻关之基础数据类型 - Yuan先生 https://www.cnblogs.com/yuanchenqi/articles/5782764.html 七 Dictionary(字典) 字典是 ...
- JavaScript图形实例:图形的平移和对称变换
1.1 六瓣花平移变换 平移变换是指图形从一个位置到另一个位置所作的直线移动.如果要把一个位于P(x,y)的点移到新位置P’(x’,y’),如图1,则只要在原坐标上加上平移距离Tx和Ty即可. 即 ...