** 组件进阶**
一、组件通信
一)、父传子
总结:
1.父传子:传递基础数据类型 给父组件中的子组件绑定属性,此时属性的值在父组件中已经定义,子组件需要通过porps接收,要用数组接收 在子组件中直接渲染接收到的值即可
2.父传子:子修改父组件传递的值报错,如果解决,把父组件传递过来的值变为自己的属性,直接修改自己属性即可。后果:父组件修改不会影响自己的数据
3.父传子:父变,子变,子变,父变,需要在父组件中定义对象,传递给子组件的就是对象的方式,子组件正常接收即可
父:
<v-child :gift="msg" :money="money" :info='info'></v-child>
子:
<div>这是父亲给我的礼物----{{ gift }}</div>
<div>这是父亲给我的钞票----{{ money }}</div>
props: ["gift", "money",'info'],
课堂例子:
<1>.parent.vue
<template>
<div>
parent
<div>这是给儿子的礼物----{{ msg }}</div>
<input type="text" v-model="msg" />
<div>{{info}}</div>
<input type="text" v-model='info.name'>
<v-child :gift="msg" :money="money" :info='info'></v-child>
</div>
</template>
<script>
import vChild from "./child";
export default {
components: {
vChild,
},
data() {
return {
msg: "大奔",
money: 2000,
info:{
name:'张三'
},
};
},
methods: {},
mounted() {},
};
<2>.child.vue
<template>
<div>
child
<div>这是父亲给我的礼物----{{ gift }}</div>
<div>这是父亲给我的钞票----{{ money }}</div>
<input type="text" v-model="gift" />
<input type="text" v-model="myCar" />
<button @click="change">点击修改mycar</button>
<div>
这是父组件传递过来的对象-----{{info}}
</div>
<div>info----- <input type="text" v-model='info.name'></div>
</div>
</template>
<script>
export default {
props: ["gift", "money",'info'],
components: {},
data() {
return {
myCar: "",
};
},
methods: {
change(){
this.myCar = 'yellow car'
}
},
mounted() {
// 这是查看一下是否拿到传过来的值
console.log(this.$props);
this.myCar = this.$props.gift;
},
};
</script>
<style scoped>
</style>
案例:java、ui、web讲师介绍
<1>.case.vue
<template>
<div>
<v-java></v-java>
<v-ui></v-ui>
<v-web></v-web>
</div>
</template>
<script>
import vJava from './java'
import vUi from './ui'
import vWeb from './web'
export default {
components:{
vJava,
vUi,
vWeb
},
data () {
return {
}
},
methods:{
},
mounted(){
}
}
</script>
<style scoped>
</style>
<2>.java.vue
<template>
<div>
<h2>java讲师</h2>
//这是循环添加的 key必须要绑定 由于card里面渲染的是具体的数据,所以传递过去对象即可
<v-card v-for='item in arr' :key='item.id' :teachers='item'></v-card>
<!-- <v-card></v-card> -->
</div>
</template>
<script>
import vCard from './card'
export default {
components:{
vCard
},
data () {
return {
arr:[
{
id:1,
img:'http://www.ujiuye.com/uploadfile/2019/0109/20190109071725808.jpg',
name:'李老师',
job:'院长'
},
{
id:2,
img:'http://www.ujiuye.com/uploadfile/2019/0423/20190423094745162.jpg',
name:'张老师',
job:'副院长'
},
{
id:3,
img:'http://www.ujiuye.com/uploadfile/2019/0423/20190423105110779.jpg',
name:'伍老师',
job:'高级讲师'
},
]
}
},
methods:{
},
mounted(){
}
}
</script>
<style scoped>
</style>
<3>.card.vue
<template>
<div class="card">
<img :src="teachers.img" alt="">
<div>姓名:{{teachers.name}}</div>
<div>职位:{{teachers.job}}</div>
</div>
</template>
<script>
// [{},{},{}]
export default {
props:['teachers'],
components:{
},
data () {
return {
}
},
methods:{
},
mounted(){
console.log(this.$props.teachers)
}
}
</script>
<style>
.card{
width: 200px;
height: 360px;
border: 1px solid blue;
display: inline-block;
}
.card img{
width: 200px;
}
.card div{
text-align: center;
margin: 10px
}
</style>
二)、子传父
子组件通过this.$emit触发方法
子:
<button @click="send">点击给父亲打钱</button>
methods:{
send(){
// $emit 用来触发子传父的方法的
this.$emit('giveTo',this.money)
}
},
父:
<v-child @giveTo='own'>123</v-child>
data () {
return {
myMoney:''//先自己定义一个变量
}
},
methods:{
own(e){
console.log(e)
this.myMoney = e//将传过来的值赋值给自己定义的自己用
}
},
课堂例子:
<1>.child.vue
<template>
<div>
child
<button @click="send">点击给父亲打钱</button>
</div>
</template>
<script>
export default {
components:{
},
data () {
return {
money:'2万'
}
},
methods:{
send(){
// $emit 用来触发子传父的方法的
this.$emit('giveTo',this.money)
}
},
mounted(){
}
}
</script>
<style scoped>
</style>
<2>.parent.vue
<template>
<div>
parent
这是儿子给的钱----{{myMoney}}
<v-child @giveTo='own'>123</v-child>
</div>
</template>
<script>
import vChild from './child'
export default {
components:{
vChild
},
data () {
return {
myMoney:''
}
},
methods:{
own(e){
console.log(e)
this.myMoney = e
}
},
mounted(){
}
}
</script>
<style scoped>
</style>
三)、非父子:
1.首先创造关系 main.js->Vue.prototype.Event=new Vue()
2.在其中一个组件发送数据用 e m i t 触 发 条 件 在 另 一 个 组 件 中 接 收 数 据 用 emit触发条件 在另一个组件中接收数据用 emit触发条件在另一个组件中接收数据用on
课堂例子:
<1>a.vue
<template>
<div>
aaaaa
<button @click="sendB">把数据发送给B</button>
</div>
</template>
<script>
export default {
components:{
},
data () {
return {
msgA:'我是a的数据'
}
},
methods:{
sendB(){
// 发送数据
this.Event.$emit('sendB',this.msgA)
}
},
mounted(){
console.log(this.Event) //Vue
}
}
</script>
<style scoped>
</style>
<2>b.vue
<template>
<div>
bbbbb----fromA{{fromA}}
</div>
</template>
<script>
export default {
components:{
},
data () {
return {
fromA:''
}
},
methods:{
},
mounted(){
// 接收数据 $on()
this.Event.$on('sendB',(e)=>{
console.log(e)
this.fromA = e
})
}
}
</script>
<style scoped>
</style>
<3>b—>c的数据
<template>
<div>
bbbbb----fromA{{fromA}}
<button @click="sendC">发送给C</button>
</div>
</template>
<script>
export default {
components:{
},
data () {
return {
fromA:''
}
},
methods:{
sendC(){
this.Event.$emit('sendC',this.fromA)
}
},
mounted(){
// 接收数据 $on()
this.Event.$on('sendB',(e)=>{
console.log(e)
this.fromA = e
})
}
}
</script>
<style scoped>
</style>
<4>c.vue
<template>
<div>
cccccc -----{{fromA}}
</div>
</template>
<script>
export default {
components:{
},
data () {
return {
fromA:''
}
},
methods:{
},
mounted(){
this.Event.$on('sendC',(e)=>{
this.fromA = e
})
}
}
</script>
<style scoped>
</style>
二、其他知识点
1.is
<1>.解决标签的固定搭配问题
<2>.动态组件
课堂案例:
<template>
<div>
<!-- is 1.解决标签的固定搭配 ul>li
2.动态组件
-->
<ul>
<li is='vOne'>我是li的内容-------- <v-one></v-one></li>
</ul>
<hr>
<!-- one two 动态组件切换-->
<button @click="name='vOne'">one</button><button @click="name='vTwo'">two</button>
<div :is='name'></div>
</div>
</template>
<script>
import vOne from './one'
import vTwo from './two'
export default {
components:{
vOne,
vTwo
},
data () {
return {
name:'vOne'
}
},
methods:{
},
mounted(){
}
}
</script>
<style scoped>
</style>
2.jquery
<1>.npm install jquery --save
<2>.哪个页面需要直接导入即可
a.局部导入
import $ from 'jquery'
mounted(){
$('button').click(()=>{
$('.box').width()
})
}
b.全局导入
在main.js
import $ from 'jquery'
Vue.prototype.$ = $;
//此时这个$是vue实例中的一个属性,所以需要通过this调用
this.$('button').click(()=>{
this.$('.box').width()
})
课堂例子:
<template>
<div>
<div class="box"></div>
<button @click="getWidth">点击获取</button>
</div>
</template>
<script>
import $ from 'jquery'//局部导入
export default {
components:{
},
data () {
return {
}
},
methods:{
getWidth(){
}
},
mounted(){//全局导入
this.$('button').click(()=>{
this.$('.box').fadeOut(2000)
})
}
}
</script>
<style>
.box{
width: 100px;
height: 100px;
background: red;
}
</style>
3.slot
<1>.无名插槽:在子组件中添加
a.slot.vue
<v-one>
<div>我就是插入到one组件中的内容1111</div>
<div>我就是插入到one组件中的内容22222</div>
</v-one>
b.one.vue
<!-- 无名插槽 -->
<slot></slot>
one
<slot></slot>
<2>.具名插槽
a.在slot.vue中
<v-two>
<div slot="aa">白日依山尽</div>
<div slot="bb">黄河入海流</div>
<div slot="cc">欲穷千里目</div>
<div slot="dd">更上一层楼</div>
<p>我是新增加的</p>//不会显示,要么加一个slot='dd',或者加一个无名插槽,(一个可以显示所有)
</v-two>
b.在two.vue中
<div>
<slot name='aa'></slot>
<slot name='bb'></slot>
two
<slot name='cc'></slot>
<slot name='dd'></slot>
<slot></slot>
</div>
4.ref(不建议使用)
<1>.ref 操作普通元素 就是获取到的dom元素
<2>.ref 操作的组件 获取的就是组件的数据和方法
<3>.使用ref 需要通过this.$refs来获取
<template>
<div>
<div class="box" ref='box'></div>
<v-one ref='one'></v-one>
这是从one组件拿回来的数据{{myMsg}}
</div>
</template>
<script>
import vOne from './one'
export default {
components:{
vOne
},
data () {
return {
myMsg:''
}
},
methods:{
},
mounted(){
// 总结:1.对于普通元 ref ->$refs来获取元素,获取之后就是普通的dom元素.
// console.log(this.$refs.box.offsetWidth)
console.log(this.$refs.one.fn())
console.log(this.$refs.one.msg)
this.myMsg = this.$refs.one.msg
}
}
</script>
<style>
.box{
width: 100px;
height: 100px;
background: red;
}
</style>