组件进阶

** 组件进阶**

一、组件通信

一)、父传子

总结:

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>
上一篇:VUE引入第三方js包及调用方法讲解


下一篇:vue中使用refs出现undefined的解决方法