zoukankan      html  css  js  c++  java
  • Vue 框架学习(七) 组件化开发

    一、组件通信

    (一)传值(两结合使用详见案例)

      1、父传子:props(注意4个名字两两成对)

    父组件:使用绑定把值传给子组件

    子组件:通过props获取父组件传入的值(可以进行类型限制或默认值)

    <body>
      <div id="app">
        <!-- 只能有一个root对象,所以数据的使用必须在一个div里面 -->
        <cpn :cmovies="moviese" :cmessage="message"></cpn>
      </div>
    
      <template id="cpn">
        <div>
          <ul>
            <li v-for="movie in cmovies">
              {{movie}}
            </li>
          </ul>
          <h2>{{cmessage}}</h2>
        </div>
      </template>
    
      <script>
        // 父传子: props
        const cpn = {
          template: '#cpn',
          // props: ['cmovies', 'cmessage'],
          props: {
            // 类型限制
            // cmovies: Array,
            // cmessage: String
    
            // 提供默认值,以及毕传值,数组不能传空数组
            cmovies: {
              type: Array,
              default: ['Default', 'Default'],
            },
            cmessage: {
              type: String,
              default: 'Default',
              request: true,
            }
          },
          data() {
            return {}
          },
        }
    
        //创建Vue实例,得到 ViewModel
        const app = new Vue({
          el: '#app',
          data: {
            message: 'Smallstars',
            moviese: ['海王', '火影']
          },
          methods: {},
          computed: {},
          components: {
            cpn
          },
        });
      </script>
    </body>
    View Code

      2、子传父

    子组件:通过监听点击事件,然后使用$emit发射事件

    父组件:监听子组件的发射事件

    <body>
      <!-- 父组件模板 -->
      <div id="app">
        <!-- 监听子组件发射的事件,传给父组件操作 -->
        <cpn @itemclick="cpnclick"></cpn>
      </div>
    
      <!-- 子组件模板 -->
      <template id="cpn">
        <div>
          <button v-for="item in categories" @click="btnClick(item)">{{item.name}}</button>
        </div>
      </template>
    
      <script>
        // 子组件
        const cpn = {
          template: '#cpn',
          data() {
            return {
              categories: [{
                  id: 1,
                  name: '热门推荐'
                },
                {
                  id: 2,
                  name: '手机数码'
                },
                {
                  id: 3,
                  name: '家用家电'
                },
                {
                  id: 4,
                  name: '电脑办公'
                },
              ]
            }
          },
    
          methods: {
            btnClick(item) {
              // 发射事件
              this.$emit('itemclick', item)
            }
          },
        }
    
        //创建Vue实例,得到 ViewModel
        const vm = new Vue({
          el: '#app',
          data: {},
          methods: {
            // 父组件对子组件传来的事件进行操作
            cpnclick(item) {
              console.log('cpnclick', item);
            }
          },
          computed: {},
          components: {
            cpn
          },
        });
      </script>
    
    </body>
    View Code

    (二)访问

      1、父访子

     $children数组、$refs

    <body>
      <div id="app">
        <cpn></cpn>
        <cpn></cpn>
        <cpn ref="aaa"></cpn>
        <button @click="btnClick">按钮</button>
      </div>
    
      <template id="cpn">
        <div>子组件</div>
      </template>
    
      <script>
        //创建Vue实例,得到 ViewModel
        const vm = new Vue({
          el: '#app',
          data: {
            message: '你好啊',
          },
          methods: {
            btnClick() {
              // 调用子组件的方法
              // 1.$children
              // console.log(this.$children);
              // this.$children[0].showMessage();
    
              // 2.$refs
              console.log(this.$refs.aaa);
    
            }
          },
          computed: {},
          components: {
            cpn: {
              template: '#cpn',
              methods: {
                showMessage() {
                  console.log('showMessage');
                }
              },
            }
          },
        });
      </script>
    
    </body>
    View Code

      2、子访父

    $parent、$root(访问根组件)

    <body>
      <div id="app">
        <cpn></cpn>
      </div>
    
      <template id="cpn">
        <div>
          <h2>cpn子组件</h2>
          <ccpn></ccpn>
        </div>
    
      </template>
    
      <template id="ccpn">
        <div>
          <h2>ccpn子组件</h2>
          <button @click="btnClick">按钮</button>
        </div>
      </template>
    
      <script>
        //创建Vue实例,得到 ViewModel
        const vm = new Vue({
          el: '#app',
          data: {
            message: '你好啊我是Vue',
    
          },
          methods: {
    
          },
          computed: {},
          components: {
            cpn: {
              template: '#cpn',
              data() {
                return {
                  name: 'cpnName'
                }
              },
              components: {
                ccpn: {
                  template: '#ccpn',
                  methods: {
                    btnClick() {
                      // 1.访问父组件
                      console.log(this.$parent);
                      console.log(this.$parent.name);
    
                      // 2. 访问根组件
                      console.log(this.$root.message);
                    }
                  },
                }
              }
            }
          },
        });
      </script>
    
    </body>
    View Code

    (三)事件总线

    (四)Vuex

      详见Vuex专题

    二、插槽

    (一)普通插槽

    <body>
      <div id="app">
        <cpn></cpn>
        <cpn>
          <p>cpn2</p>
        </cpn>
        <cpn><span>cpn3</span></cpn>
        <cpn><input type="text">
          <p>cpn4</p>
        </cpn>
      </div>
    
      <template id="cpn">
        <div>
          <p>我是cpn</p>
          <slot><button>默认按钮</button></slot>
        </div>
      </template>
    
      <script>
        //创建Vue实例,得到 ViewModel
        const vm = new Vue({
          el: '#app',
          data: {},
          methods: {},
          computed: {},
          components: {
            cpn: {
              template: '#cpn'
            }
          },
        });
      </script>
    
    </body>
    View Code

    (二)具名插槽

    <body>
      <div id="app">
        <cpn><span>没有name属性会把所有没有名字的插槽都替换</span></cpn>
        <cpn><button slot="left">返回</button></cpn>
        <cpn><span slot="center">使用slot使用相应的插槽</span></cpn>
    
      </div>
    
      <template id="cpn">
        <div>
          <slot>没有name</slot>
    
          <slot name="left"></slot>
          <slot name="center"></slot>
          <slot name="right"></slot>
          <slot>没有name</slot>
    
        </div>
      </template>
      <script>
        //创建Vue实例,得到 ViewModel
        const vm = new Vue({
          el: '#app',
          data: {},
          methods: {},
          computed: {},
          components: {
            cpn: {
              template: '#cpn'
            }
          },
        });
      </script>
    
    </body>
    View Code

    (三)编译作用域(父组件和子组件的属性相同)

    <body>
      <div id="app">
        <!-- 先看在那个模板里面,直接去app找 -->
        <cpn v-show="isShow"></cpn>
      </div>
    
      <template id="cpn">
        <div>
          <h2>我是子组件</h2>
          <!-- 模板中去自己模板中找 -->
          <button v-show="!isShow">按钮</button>
        </div>
      </template>
      <script>
        //创建Vue实例,得到 ViewModel
        const vm = new Vue({
          el: '#app',
          data: {
            message: 'Smallstars',
            isShow: true,
          },
          methods: {},
          computed: {},
          components: {
            cpn: {
              template: '#cpn',
              data() {
                return {
                  isShow: false,
                }
              },
            }
          },
        });
      </script>
    
    </body>
    View Code

    (四)作用域插槽(父组件替换插槽的内容,但内容是子组件决定。由于编译作用域的原因,父组件本不能直接访问子组件的值)

    <body>
      <div id="app">
        <cpn></cpn>
        <!-- 父组件想对子组件的数据进行操作,但是不能直接拿(前一章作用域问题) -->
        <!-- 获取子组件数据用不同方式展示 -->
        <cpn>
          <template slot-scope="slot">
            <!-- <span v-for="item in slot.data">{{item}} - </span> -->
            <span>{{slot.data1.join('-')}}</span>
    
          </template>
    
        </cpn>
    
        <cpn>
          <template slot-scope="slot">
            <span v-for="item in slot.data1">{{item}} * </span>
          </template>
    
        </cpn>
    
      </div>
    
      <template id="cpn">
        <div>
          <!-- 作用域插槽,在这里绑定数据好在父组件使用 -->
          <slot :data1="pLanguages">
            <ul>
              <li v-for="item in pLanguages">{{item}}</li>
            </ul>
          </slot>
        </div>
      </template>
      <script>
        //创建Vue实例,得到 ViewModel
        const vm = new Vue({
          el: '#app',
          data: {
            message: 'Smallstars',
          },
          methods: {},
          computed: {},
          components: {
            cpn: {
              template: '#cpn',
              data() {
                return {
                  pLanguages: ['Python', 'JavaScript', 'C++', 'C#']
                }
              },
            }
          },
        });
      </script>
    
    </body>
    View Code
    每天进步一点点
  • 相关阅读:
    HashTable、HashSet和Dictionary的区别
    CCF_ 201312-3_最大的矩形
    CCF_ 201312-2_ISBN号码
    CCF_201312-1_出现次数最多的数
    CCF_ 201509-2_日期计算
    CCF_ 201512-3_画图
    CCF_ 201512-2_消除类游戏
    CCF_ 201409-2_画图
    CCF_201409-1_相邻数对
    CCF_ 201412-1_门禁系统
  • 原文地址:https://www.cnblogs.com/smallstars/p/13509174.html
Copyright © 2011-2022 走看看