父传递子组件信息
父组件发送信息,子组件通过prop接受参数信息
字符串数组,数组中的字符串就是传递时的名称
props:['cmovies','cmessage']
加以类型限制
props:{
cmovies:Arry,
cmessage:String
}
提供一些默认值
props:{
cmessage:{
type:String,
default:'aaaaaa'
}
}
对象可以设置为传递时的类型,也可以设置成默认值
props:{
//不能使用驼峰命名法
cmessage:{
type:String,
default:'aaaaa',
// 意思是使用组件时必须传入'cessmage',要不然会报错
require:true
}
}
}
父组件向子组件发送信息
<div id="app">
//这里是父组件发送的动态信息,如果是静态信息,也可采用不需要v-bind绑定
<c1 v-bind:cmovies="movies" v-bind:cmessage="message"></c1>
</div>
<script>
//构建子组件组件
const c1={
template:`
<div>
<h1>不赖</h1>
<h1>{{cmovies}}</h1>
<h1>{{cmessage}}</h1>
</div>
`,
props:['cmovies','cmessage']
}
//Vue实例也是一个看做是组件
const app=new Vue({
el:'#app',
data:{
message:'真不错',
movies:['海王','神树','斗牛']
},
components:{
c1
}
})
</script>
父组件访问子组件
两种方式
一、通过
c
h
i
l
d
r
e
n
来
访
问
二
、
通
过
children来访问 二、通过
children来访问二、通过refs在组件中加如ref属性(比较常用)
<div id="app">
<cpn></cpn>
<cpn></cpn>
<!-- 注意属性名时ref-->
<cpn ref="a"></cpn>
<cpn ref="b"></cpn>
<button @click="btnclick1">按钮1</button>
<button @click="btnclick2">按钮2</button>
</div>
<template type="text/x-template" id="cpn">
<div>
<h1>我是子组件</h1>
</div>
</template>
<script>
var app=new Vue({
el:"#app",
data:{
message:"你好呀"
},
methods:{
btnclick1(){
// 访问子组件,通过this.$children来访问子组件,会把使用的cpn组件放到一个数组中
//以后开发不同的组件也会放在同一个数组中
console.log(this.$children)
//通过数组来访问到具体哪一个组件,可以拿到子组件的属性和方法等
this.$children[2].showmessage()
},
btnclick2(){
// 也是1放在一个数组里面,只是根据ref属性进行筛选
console.log(this.$refs)
//输出ref属性为 a 的组件
console.log(this.$refs.a)
}
},
components:{
cpn:{
template:'#cpn',
methods:{
showmessage(){
console.log('访问到了')
}
}
}
}
})
</script>
子访问父组件
两种方式
一、通过
p
a
r
e
n
t
来
访
问
二
、
通
过
parent来访问 二、通过
parent来访问二、通过root来访问根组件
<div id="app">
<cpn></cpn>
</div>
<template type="text/x-template" id="cpn">
<div>
<h1>我是子组件</h1>
<button @click="btnclick">按钮</button>
</div>
</template>
<script>
var app=new Vue({
el: "#app",
data: {
message: "你好呀"
},
components: {
cpn: {
template: '#cpn',
methods:{
btnclick(){
//方式一,通过$parent来访问父组件
console.log(this.$parent)
console.log(this.$parent.message)
//方式二,通过$root访问根组件
console.log(this.$root)
console.log(this.$root.message)
}
}
}
}
})
</script>
子组件通过$emit进行向父组件进行传参,也可以触发父组件的事件
Vue中 关于$emit的用法
例如:
子组件
<div class="tab-control-item"
v-for="(item,index) in titles"
:class="{active: index === currentIndex}"
@click="tabItemClick(index)"
>
<span>{{item}}</span>
</div>
//子组件触发父组件事件,index值
methods: {
tabItemClick(index) {
this.$emit('tabItemClick',index)
}
}
父组件
<tab-control class="tab-control-bot"
:titles="['流行','新款','精选']"
@tabItemClick="tabItemClick"
ref="tabControl2" />
tabItemClick(index){
switch(index){
case 0:
this.currentType = 'pop'
break;
case 1:
this.currentType = 'new'
break;
case 2:
this.currentType = 'sell'
break;
}
this.$refs.tabControl1.currentIndex = index;
this.$refs.tabControl2.currentIndex = index;
},
值得注意的一点是
子组件的
this.$emit('tabItemClick',index)
这里的触发父组件的名字是tabItemClick,对应的父组件应是
@tabItemClick=“tabItemClick”。加粗的地方对应
单向数据流(摘自官网)
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。
额外的,每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。 这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
这里有两种常见的试图变更一个 prop 的情形:
这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。在这种情况下,最好定义一个本地的 data property 并将这个 prop 用作其初始值:
props: ['initialCounter'],
data: function () {
return {
counter: this.initialCounter
}
}
这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性:
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}
类型检查
通过VueX进行通信
如果通信比较小,最好不要用VueX来进行通信
碰到的问题:
父组件异步改变了传递的值,但是子组件没有更新值
<div>这是父组件传过来的数字:{{num}}</div>
<div>这是copy父组件传过来的数字:{{num02}}</div>
//在子组件中
props:['num'],
data(){
return{
num02:this.num
}
}
//在父组件中
data: {
num:undefined
},
created() {
setTimeout(()=>{
this.num = 189
},3000)
}
解决办法
computed:{
num02(){
return this.num
}
}