树结构

  1. 创建组件构造对象

  2. 注册组件

  3. 全局组件和局部组件

  4. 可以在构造器当中,除了模版 template 属性,还可以添加 components 属性 这样就形成了父子组件
    在构造器中添加了components 属性后可以注册外面的组件,并自已调用

组件通信父向子传递消息

首先会在Vue实列中把数据给到v-bind, 再从这里传给注册组件 里的cpn ,cpn此时收到数据并返回给模版
image.png

组件通信子向父传递消息

开始时我们先来用之前的父组件向子组件传递数据的知识完成下面这个问题
1. 父组件如何向子组件传递一个方法呢?
总结来说就一句话: 通过事件绑定机制,将父组件上的方法传递给子组件

我们需要用到的东西

  1. vue实例,并在实例上定义一个方法
    2. 创建子组件
  1. // 1
  2. var vm = new Vue({
  3. el : "#app",
  4. methods: {
  5. show(){
  6. console.log(’我是父组件上的方法‘);
  7. },
  8. })
  9. // 2
  10. <template id="tem">
  11. <div>
  12. <h3>我是子组件</h3>
  13. // 点击button按钮,通过$emit实例api自定义方法
  14. <button @click="button">触发父组件传递过来的方法</button>
  15. </div>
  16. </template>
  17. Vue.component('tem-app',{
  18. template : '#tem',
  19. methods: {
  20. button(){
  21. // vm.$emit( eventName, […args] ) :
  22. // 触发当前实例上的事件
  23. // 参数一,实例[父组件]定义的方法【事件名称】
  24. // 参数二,可选的,子组件向父组件传递的数据,可以是多个,
  25. this.$emit('func')
  26. }
  27. }
  28. })
  29. // 3 ok ,再来看看我们vue实例所要控制的区域
  30. // 父组件通过绑定了一个由子组件定义的方法,将自己身上的方法传递过去
  31. <div id="app">
  32. <tem-app @func="show"></tem-app>
  33. </div>
  34. // 这样我们就完成了,父组件向子组件传递一个方法的问题了

我通过上面的例子再来看看
1.如何往父组件传递数据?
1.这其实很简单
2.通过 $meit方法的第二个参数,将数据传递过去,父组件方法接收子组件传递过来的数据即可

  1. var obj = {
  2. name : "张三",
  3. age : 18,
  4. sex : "男"
  5. }// vue实例var vm = new Vue({
  6. el : "#app",
  7. methods: {
  8. show(obj){
  9. // 父组件拿到子组件传递过来的数据
  10. console.log(obj)
  11. }
  12. },
  13. })

完整代码

  1. <body>
  2. <!--
  3. 通过事件绑定机制,将父组件上的方法传递给子组件,
  4. 子组件通过第二的参数将数据传递给父组件
  5. -->
  6. <div id="app">
  7. <tem-app @func="show"></tem-app>
  8. </div>
  9. <template id="tem">
  10. <div>
  11. <h3>我是子组件</h3>
  12. <button @click="button">触发父组件传递过来的方法</button>
  13. </div>
  14. </template>
  15. <script>
  16. var obj = {
  17. name : '张三',
  18. age : 12,
  19. sex : '男'
  20. }
  21. Vue.component('tem-app',{
  22. template : '#tem',
  23. data : function(){
  24. return {
  25. msg : '我是子组件上的数据'
  26. }
  27. },
  28. methods: {
  29. button(){
  30. // vm.$emit( eventName, […args] ) :
  31. // 触发当前实例上的事件
  32. // 参数一,实例[父组件]定义的方法
  33. // 参数二,可选的,子组件向父组件传递的数据,可以是多个,
  34. this.$emit('func',obj)
  35. }
  36. },
  37. })
  38. var vm = new Vue({
  39. el : "#app",
  40. methods: {
  41. show(obj){
  42. // 父组件拿到子组件传递过来的数据
  43. console.log(obj)
  44. }
  45. },
  46. })
  47. </script>
  48. </body>

组件通信监听子组件点击事件

@click=”$emit(‘back’)” 子组件点击事件
:back=”xiangyin” 父组件监听

子组件调用父组件方法

首先子组件中有监听事件,比如点击事件 @click=”Btn”

  1. Btn:funtions(){
  2. this.$parent.父组件的方法名() ;
  3. }

父组件调用子组件方法

首先在父组件中设置事件监听, @click=”Btn”

  1. Btn:funtions(){
  2. this.$refs.child.childFn() ; //调用了子组件名称
  3. }

子组件

  1. childFn:funtions(){
  2. }

组件化高级

Slot插槽扩展

  1. 插槽的基本使用 放到templase 模版标签里
    2. 插槽的默认值 按钮
    3. 如果有多个值,同时放到插槽里

Slot具名插槽

有多个插槽,给指定的插槽替换
给插槽定义名字,相当于一个身份id

  1. <body>
  2. <div id="app">
  3. <cpm>
  4. <span slot="left"> 左边的插槽改变了 </span>
  5. </cpm>
  6. </div>
  7. <template id='cpm'>
  8. <div>
  9. <h2>我是组件</h2>
  10. <slot name='left'><span>左边</span></slot><br>
  11. <slot name='center'><span>中间</span></slot><br>
  12. <slot name='right'><span>右边</span></slot><br>
  13. </div>
  14. </template>

编译作用域

在父级的变量,只对父级有效果
在子级的变量,只对子级有次效果

插槽作用域

数据是从子组件来的, 所以遍历循环数据也因改在模版中循环,并 在slot标签中自定义属性,绑定shuju
然后再父组件中的标签使用 slot-scope 属性来对接,然后展示数据

  1. <body>
  2. <!-- 目标: 从子组件中获取数据 显示到父组件 -->
  3. <div id="app">
  4. <cpm>
  5. <template slot-scope='slot'>
  6. <!-- <span v-for='item in slot.data2'>{{item}}-</span> -->
  7. <span>{{slot.data2.join("-")}}</span>
  8. </template>
  9. </cpm>
  10. <cpm>
  11. <div slot-scope='slot'>
  12. <span>{{slot.data2.join(" * ")}}</span>
  13. </div>
  14. </cpm>
  15. </div>
  16. <template id='cpm'>
  17. <div>
  18. <slot :data2='shuju'>
  19. <h2 v-for='item in shuju'>{{item}}</h2>
  20. </slot>
  21. </div>
  22. </template>
  23. <script>
  24. const app = new Vue({
  25. el: '#app',
  26. data: {
  27. message: '你好世界',
  28. ishow: true
  29. },
  30. components: {
  31. cpm: {
  32. template: '#cpm',
  33. data() {
  34. return {
  35. shuju: ['网络验证', '自动发卡', 'QQ计数器', "微信计数器"]
  36. }
  37. }
  38. }
  39. }
  40. })
  41. </script>
  42. </body>