• 4.组件间数据交互


    目录

    4.1 父组件向子组件传值

            1.组件内部通过props接收传递过来的值

            2.父组件通过属性将值传递给子组件

             3.props 属性名规则 

            4.props属性值类型

    4.2 子组件向父组件传值

    4.3 非父子组件间传值

    4.4 组件插槽

    4.5 具名插槽

    4.6 作用域插槽


    4.1 父组件向子组件传值

            1.组件内部通过props接收传递过来的值

            2.父组件通过属性将值传递给子组件

    1.组件内部通过props接收传递过来的值
            Vue.component('menu-item', {
                props: ['title'],
                template: '

    {{title}}
    '
            })
        2.父组件通过属性将值传递给子组件
            
            

    1. html>
    2. <html>
    3. <head>
    4. <meta charset="utf-8">
    5. <title>title>
    6. head>
    7. <body>
    8. <div id="app">
    9. <div>{{pmsg}}div>
    10. <menu-item title='来自父组件的值'>menu-item>
    11. <menu-item :title='ptitle' content='hello'>menu-item>
    12. div>
    13. body>
    14. <script type="text/javascript" src="../js/vue.js">script>
    15. <script type="text/javascript" >
    16. /*
    17. 父组件向子组件传值
    18. 1.组件内部通过props接收传递过来的值
    19. Vue.component('menu-item', {
    20. props: ['title'],
    21. template: '<div>{{title}}div>'
    22. })
    23. 2.父组件通过属性将值传递给子组件
    24. <menu-item title='来自父组件的值'>menu-item>
    25. <menu-item :title='ptitle' content='hello'>menu-item>
    26. */
    27. Vue.component('menu-item', {
    28. props: ['title', 'content'],
    29. data: function(){
    30. return {
    31. msg: '子组件本身的数据'
    32. }
    33. },
    34. template: '<div>{{msg + "--" + title + content}}div>'
    35. })
    36. var vm = new Vue({
    37. el:'#app',
    38. data:{
    39. pmsg: "父组件内容",
    40. ptitle: '动态绑定属性'
    41. },
    42. methods: {
    43. handle: function (event) {
    44. }
    45. }
    46. });
    47. script>
    48. html>

             3.props 属性名规则 

    父组件向子组件传值
        3.props 属性名规则
            1.在props中使用驼峰形式,模板中需要使用短横线的形式(html页面标签)
            Vue.component('menu-item', {
                props: ['xyzTitle'],
                template: '

    {{xyzTitle}}
    '
            })
            
            2.字符串形式的模板中没有这个限制
            Vue.component('menu-item', {
                props: ['xyzTitle'],
                template: '
    {{xyzTitle}}
    '
            });

    1. html>
    2. <html>
    3. <head>
    4. <meta charset="utf-8">
    5. <title>title>
    6. head>
    7. <body>
    8. <div id="app">
    9. <div>{{pmsg}}div>
    10. <menu-item xyz-title="父组件静态">menu-item>
    11. div>
    12. body>
    13. <script type="text/javascript" src="../js/vue.js">script>
    14. <script type="text/javascript" >
    15. /*
    16. 父组件向子组件传值
    17. 3.props 属性名规则
    18. 1.在props中使用驼峰形式,模板中需要使用短横线的形式(html页面标签)
    19. Vue.component('menu-item', {
    20. props: ['xyzTitle'],
    21. template: '<div>{{xyzTitle}}div>'
    22. })
    23. <menu-item xyz-title="父组件静态">menu-item>
    24. 2.字符串形式的模板中没有这个限制
    25. Vue.component('menu-item', {
    26. props: ['xyzTitle'],
    27. template: '<div>{{xyzTitle}}<third-com testTitle="hello">third-com>div>'
    28. });
    29. */
    30. Vue.component('third-com', {
    31. props: ['testTitle'],
    32. template: '<div>{{testTitle}}div>'
    33. });
    34. Vue.component('menu-item', {
    35. props: ['xyzTitle'],
    36. template: '<div>{{xyzTitle}}<third-com testTitle="hello">third-com>div>'
    37. });
    38. var vm = new Vue({
    39. el:'#app',
    40. data:{
    41. pmsg: "父组件内容1",
    42. ptitle: '父组件内容2',
    43. },
    44. methods: {
    45. handle: function (event) {
    46. }
    47. }
    48. });
    49. script>
    50. html>

            4.props属性值类型

            4.1父组件向子组件传值
            4.props属性值类型
                1. 字符串String
                    
                2. 数值Number (要加: v-bind绑定,否则是字符串)
                    
                3. 布尔值Boolean (要加: v-bind绑定,否则是字符串)
                    
                4. 数组Array
                    data:{
                         parr: ['apple', 'orange', 'banana']
                    },
                    
                5. 对象Object
                    data:{
                         pobj: {
                             name: 'lili',
                             age: 12,
                             gender: 'male'
                         }
                    },
                    

    1. html>
    2. <html>
    3. <head>
    4. <meta charset="utf-8">
    5. <title>title>
    6. head>
    7. <body>
    8. <div id="app">
    9. <div>{{pmsg}}div>
    10. <menu-item :pstr='pstr' :pnum='12' :pboo='true' :parr='parr' :pobj='pobj'>
    11. menu-item>
    12. div>
    13. body>
    14. <script type="text/javascript" src="../js/vue.js">script>
    15. <script type="text/javascript" >
    16. /*
    17. 4.1父组件向子组件传值
    18. 4.props属性值类型
    19. 1. 字符串String
    20. <menu-item :pstr='pstr' >menu-item>
    21. 2. 数值Number (要加: v-bind绑定,否则是字符串)
    22. <menu-item :pnum='12'>menu-item>
    23. 3. 布尔值Boolean (要加: v-bind绑定,否则是字符串)
    24. <menu-item :pboo='true'>menu-item>
    25. 4. 数组Array
    26. data:{
    27. parr: ['apple', 'orange', 'banana']
    28. },
    29. <menu-item :parr='parr'>menu-item>
    30. 5. 对象Object
    31. data:{
    32. pobj: {
    33. name: 'lili',
    34. age: 12,
    35. gender: 'male'
    36. }
    37. },
    38. <menu-item :pobj='pobj'>menu-item>
    39. */
    40. Vue.component('menu-item', {
    41. props: ['pstr', 'pnum', 'pboo', 'parr', 'pobj'],
    42. template:
    43. `<div>
    44. <div>{{pstr}}div>
    45. <div>{{typeof pnum}}div>
    46. <div>{{ typeof pboo}}div>
    47. <ul>
    48. <li :key='index' v-for='(item, index) in parr'>{{item}}li>
    49. ul>
    50. <div>
    51. <span>{{pobj.name}}span>
    52. <span>{{pobj.age}}span>
    53. <span>{{pobj.gender}}span>
    54. div>
    55. div>
    56. `
    57. })
    58. var vm = new Vue({
    59. el:'#app',
    60. data:{
    61. pmsg: "父组件内容",
    62. pstr: 'hello',
    63. parr: ['apple', 'orange', 'banana'],
    64. pobj: {
    65. name: 'lili',
    66. age: 12,
    67. gender: 'male'
    68. }
    69. },
    70. methods: {
    71. handle: function (event) {
    72. }
    73. }
    74. });
    75. script>
    76. html>

    4.2 子组件向父组件传值

    基本用法:
            props传递数据原则:单向数据流;
            1.子组件通过自定义事件向父组件传递信息
                
                
            2.父组件监听子组件的事件
                
            
            3.子组件通过自定义事件向父组件传递信息 5就是传递的参数
                
                
            4.父组件监听子组件的事件 $event参数接受固定写法
                

    1. html>
    2. <html>
    3. <head>
    4. <meta charset="utf-8">
    5. <title>title>
    6. head>
    7. <body>
    8. <div id="app">
    9. <div :style='{fontSize: fontSize + "px"}'>{{pmsg}}div>
    10. <menu-item :parr1='parr' @enlarge-text='handle($event)'>menu-item>
    11. div>
    12. body>
    13. <script type="text/javascript" src="../js/vue.js">script>
    14. <script type="text/javascript" >
    15. /*
    16. 子组件向父组件传值-基本用法
    17. props传递数据原则:单向数据流;
    18. 1.子组件通过自定义事件向父组件传递信息
    19. <button @click='$emit("enlarge-text")'>扩大字体button>
    20. 2.父组件监听子组件的事件
    21. <menu-item :parr='parr' @enlarge-text='handle'>menu-item>
    22. 3.子组件通过自定义事件向父组件传递信息 5就是传递的参数
    23. <button @click='$emit("enlarge-text", 5)'>扩大字体button>
    24. 4.父组件监听子组件的事件 $event参数接受固定写法
    25. <menu-item :parr1='parr' @enlarge-text='handle($event)'>menu-item>
    26. */
    27. Vue.component('menu-item', {
    28. props: ['parr1'],
    29. template:
    30. `
    31. <div>
    32. <ul>
    33. <li :key='index' v-for='(item, index) in parr1'>
    34. {{item}}li>
    35. ul>
    36. <button @click='parr1.push("lemon")'>点击button>
    37. <button @click='$emit("enlarge-text", 5)'>扩大字体button>
    38. <button @click='$emit("enlarge-text", 10)'>扩大字体button>
    39. div>
    40. `
    41. })
    42. var vm = new Vue({
    43. el:'#app',
    44. data:{
    45. pmsg: "hello",
    46. parr: ['apple', 'orange', 'banana'],
    47. fontSize: 10,
    48. },
    49. methods: {
    50. handle: function (val) {
    51. //扩大字体大小
    52. this.fontSize +=val;
    53. }
    54. }
    55. });
    56. script>
    57. html>

    4.3 非父子组件间传值

             1.单独的事件中心管理组件间的通信
                var hub = new Vue();
            2.监听事件与销毁事件
                监听:eventHub.$on('add-todo', addTodo); 
                销毁:eventHub.$off('add-todo'); 
            3.触发事件
                event.$emit('add-todo', 参数1)

    1. html>
    2. <html>
    3. <head>
    4. <meta charset="utf-8">
    5. <title>title>
    6. head>
    7. <body>
    8. <div id="app">
    9. <div>
    10. <button @click="handle">销毁tombutton>
    11. div>
    12. <test-tom>test-tom>
    13. <test-jerry>test-jerry>
    14. div>
    15. body>
    16. <script type="text/javascript" src="../js/vue.js">script>
    17. <script type="text/javascript" >
    18. /*
    19. 4.3 非父子组件间传值
    20. 1.单独的事件中心管理组件间的通信
    21. var hub = new Vue();
    22. 2.监听事件与销毁事件
    23. 监听:eventHub.$on('add-todo', addTodo);
    24. 销毁:eventHub.$off('add-todo');
    25. 3.触发事件
    26. event.$emit('add-todo', 参数1)
    27. */
    28. //提供事件中心
    29. var hub = new Vue();
    30. Vue.component('test-tom', {
    31. data: function(){
    32. return {
    33. num: 0
    34. }
    35. },
    36. template:
    37. `
    38. Tom:{{num}}
  • `,
  • methods: {
  • handle: function(){
  • //触发兄弟组件的事件
  • hub.$emit('jerry', 2);
  • }
  • },
  • mounted: function(){
  • hub.$on('tom-event', (val) =>{
  • this.num +=val;
  • });
  • },
  • });
  • Vue.component('test-jerry', {
  • data: function(){
  • return {
  • num: 0
  • }
  • },
  • template:
  • `
  • Jerry:{{num}}
  • `,
  • methods: {
  • handle: function(){
  • //触发兄弟组件的事件
  • hub.$emit('tom-event', 1);
  • }
  • },
  • mounted: function(){
  • hub.$on('jerry', (val) =>{
  • this.num +=val;
  • });
  • },
  • });
  • var vm = new Vue({
  • el:'#app',
  • data:{
  • pmsg: "hello",
  • ptitle: "动态绑定属性",
  • ptitle2: "动态2"
  • },
  • methods: {
  • handle: function () {
  • hub.$off('tom-event');
  • }
  • }
  • });
  • script>
  • html>
  • 4.4 组件插槽

    组件插槽的作用
            1.父组件向子组件传递内容
            
        组件插槽基本用法
            1.插槽位置
                Vue.component('alert-box', {
                    template: `
                        


                            ERROR:
                            默认内容
                        

                    `,
                                                    
                });
            2.插槽内容
                 无内容为插槽的默认内容
                有bug发生
                有2个bug发生

     

    1. html>
    2. <html>
    3. <head>
    4. <meta charset="utf-8">
    5. <title>title>
    6. head>
    7. <body>
    8. <div id="app">
    9. <alert-box>alert-box>
    10. <alert-box>有bug发生alert-box>
    11. <alert-box>有2个bug发生alert-box>
    12. div>
    13. body>
    14. <script type="text/javascript" src="../js/vue.js">script>
    15. <script type="text/javascript" >
    16. /*
    17. 组件插槽的作用
    18. 1.父组件向子组件传递内容
    19. 组件插槽基本用法
    20. 1.插槽位置
    21. Vue.component('alert-box', {
    22. template: `
    23. <div>
    24. <strong>ERROR:strong>
    25. <slot>默认内容slot>
    26. div>
    27. `,
    28. });
    29. 2.插槽内容
    30. <alert-box>alert-box> 无内容为插槽的默认内容
    31. <alert-box>有bug发生alert-box>
    32. <alert-box>有2个bug发生alert-box>
    33. */
    34. Vue.component('alert-box', {
    35. template: `
    36. <div>
    37. <strong>ERROR:strong>
    38. <slot>默认内容slot>
    39. div>
    40. `,
    41. });
    42. var vm = new Vue({
    43. el:'#app',
    44. data:{
    45. msg: "hello",
    46. },
    47. methods: {
    48. handle: function (event) {
    49. }
    50. }
    51. });
    52. script>
    53. html>

    4.5 具名插槽

    具名插槽
            1.插槽定义
                Vue.component('base-layout', {
                    template: `
                        


                            

                                
                            

                            

                                
                            

                            

                                
                            

                        

                    `,
                });
            2.插槽内容
                
                    

    标题信息


                    

    主要内容1


                    

    主要内容2


                    

    底部信息


                    
                

            3.template标签用于包裹多个标签
                    

     

    1. html>
    2. <html>
    3. <head>
    4. <meta charset="utf-8">
    5. <title>title>
    6. head>
    7. <body>
    8. <div id="app">
    9. <base-layout>
    10. <p slot='header'>标题信息p>
    11. <p>主要内容1p>
    12. <p>主要内容2p>
    13. <p slot='footer'>底部信息p>
    14. base-layout>
    15. <base-layout>
    16. <template slot='header'>
    17. <p>标题信息1p>
    18. <p>标题信息2p>
    19. template>
    20. <p>主要内容1p>
    21. <p>主要内容2p>
    22. <template slot='footer'>
    23. <p >底部信息1p>
    24. <p >底部信息2p>
    25. template>
    26. base-layout>
    27. div>
    28. body>
    29. <script type="text/javascript" src="../js/vue.js">script>
    30. <script type="text/javascript" >
    31. /*
    32. 具名插槽
    33. 1.插槽定义
    34. Vue.component('base-layout', {
    35. template: `
    36. <div>
    37. <header >
    38. <slot name='header'>slot>
    39. header>
    40. <main>
    41. <slot>slot>
    42. main>
    43. <footer>
    44. <slot name='footer'>slot>
    45. footer>
    46. div>
    47. `,
    48. });
    49. 2.插槽内容
    50. <base-layout>
    51. <p slot='header'>标题信息p>
    52. <p>主要内容1p>
    53. <p>主要内容2p>
    54. <p slot='footer'>底部信息p>
    55. base-layout>
    56. 3.template标签用于包裹多个标签
    57. <template slot='header'>
    58. <p>标题信息1p>
    59. <p>标题信息2p>
    60. template>
    61. */
    62. Vue.component('base-layout', {
    63. template: `
    64. <div>
    65. <header >
    66. <slot name='header'>slot>
    67. header>
    68. <main>
    69. <slot>slot>
    70. main>
    71. <footer>
    72. <slot name='footer'>slot>
    73. footer>
    74. div>
    75. `,
    76. });
    77. var vm = new Vue({
    78. el:'#app',
    79. data:{
    80. msg: "hello",
    81. },
    82. methods: {
    83. handle: function (event) {
    84. }
    85. }
    86. });
    87. script>
    88. html>

    4.6 作用域插槽

    作用域插槽
            应用场景:父组件对子组件的内容进行加工处理
            1.插槽定义
                Vue.component('fruit-list', {
                    props:['list'],
                    template: `
                        

                    
                            

  •                             
                                    {{item.name}}
                                

                            

  •                     

                    `,
                });        
            2.插槽内容
                

                    
                                        
                    

                

     

    1. html>
    2. <html>
    3. <head>
    4. <meta charset="utf-8">
    5. <title>title>
    6. <style type="text/css">
    7. .current {
    8. color: orange;
    9. }
    10. style>
    11. head>
    12. <body>
    13. <div id="app">
    14. <fruit-list :list='list'>
    15. <template slot-scope='slotProps'>
    16. <strong v-if="slotProps.info.id == 2" class="current">
    17. {{slotProps.info.name}}
    18. strong>
    19. <span v-else>
    20. {{slotProps.info.name}}
    21. span>
    22. template>
    23. fruit-list>
    24. div>
    25. body>
    26. <script type="text/javascript" src="../js/vue.js">script>
    27. <script type="text/javascript" >
    28. /*
    29. 作用域插槽
    30. 应用场景:父组件对子组件的内容进行加工处理
    31. 1.插槽定义
    32. Vue.component('fruit-list', {
    33. props:['list'],
    34. template: `
    35. <div>
    36. <li :key='item.id' v-for='(item, index) in list'>
    37. <slot :info='item'>
    38. {{item.name}}
    39. slot>
    40. li>
    41. div>
    42. `,
    43. });
    44. 2.插槽内容
    45. <div id="app">
    46. <fruit-list :list='list'>
    47. <template slot-scope='slotProps'>
    48. <strong v-if="slotProps.info.id == 2" class="current">
    49. {{slotProps.info.name}}
    50. strong>
    51. <span v-else>
    52. {{slotProps.info.name}}
    53. span>
    54. template>
    55. fruit-list>
    56. div>
    57. */
    58. Vue.component('fruit-list', {
    59. props:['list'],
    60. template: `
    61. <div>
    62. <li :key='item.id' v-for='(item, index) in list'>
    63. <slot :info='item'>
    64. {{item.name}}
    65. slot>
    66. li>
    67. div>
    68. `,
    69. });
    70. var vm = new Vue({
    71. el:'#app',
    72. data:{
    73. msg: "hello",
    74. list: [{
    75. id: 1,
    76. name: 'apple'
    77. },{
    78. id: 2,
    79. name: 'orange'
    80. },{
    81. id: 3,
    82. name: 'banana'
    83. }],
    84. id: 3,
    85. },
    86. methods: {
    87. handle: function (event) {
    88. }
    89. }
    90. });
    91. script>
    92. html>

  • 相关阅读:
    c单元语言测试--自定义代码、rspec 和Google test
    软考中级(软件设计师)——计算机组成和体系结构(占6分)
    标题优化技巧
    Tomcat 接收请求并传递给工作线程池流程
    redis缓存三大问题及内存满了该怎么办
    武汉凯迪正大—电容电感测量仪
    RocketMQ(14)——发送带Key的消息
    【5G核心网】手把手教你将Open5gs托管到k8s(KubeSphere)
    Error inflating class com.baidu.mapapi.map.MapView
    Arduino Esp8266 Web LED控制
  • 原文地址:https://blog.csdn.net/PengK_aha/article/details/128129603