Vue组件化开发相应知识点

Vue组件化开发相应知识点

1.组件注册

1.1 全局注册

通过 Vue.component('组件名‘,{}) 方法进行注册;全局注册的组件任何实例都能使用。
基本实例代码如下:

  <div id="app">
    <button-counter></button-counter>
  </div>
  
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    Vue.component('button-counter', {
    
    
      // data 是一个函数 返回后一个对象,数据存储于对象中
      data: function(){
    
    
        return {
    
    
          count: 0
        }
      },
      // 组件的模板必须是只有一个根元素,内容也可以是模板字符(``)串形式
      template: '<button @click="handle">点击了{
    
    {count}}次</button>',
      methods: {
    
    
        handle: function(){
    
    
          this.count += 2;
        }
      }
    })
    var vm = new Vue({
    
    
      el: '#app',
      data: {
    
    
        
      }
    });
  </script>

1.2 局部注册

局部注册的组件只能在当前实例中使用。
基本实例代码如下:

  <div id="app">
    <test-com></test-com>
  </div>
  
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    Vue.component('test-com',{
    
    
      // 不会显示helloworld,因为hello-world组件是在vm中注册的
      template: '<div>Test<hello-world></hello-world></div>'
    });
    var HelloWorld = {
    
    
      data: function(){
    
    
        return {
    
    
          msg: 'HelloWorld'
        }
      },
      template: '<div>{
    
    {msg}}</div>'
    };
   
    var vm = new Vue({
    
    
      el: '#app',
      data: {
    
    
        
      },
      // 注册局部组件
      components: {
    
    
        'hello-world': HelloWorld,
      }
    });

2. Vue组件之间传值

2.1 父组件向子组件传值

父组件通过在模板中绑定相应的数据到子组件上,在子组件中使用props接收父组件传递来的值;直接嵌入html的组件,props中若使用驼峰的形式,在绑定数据的时候则需要使用短横线形式绑定,而使用字符串则无需考虑此类型的限制。

  <div id="app">
    <div>{
    
    {
    
    pmsg}}</div>
    <menu-item :menu-title='ptitle'></menu-item>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    /*
      父组件向子组件传值-props属性名规则
    */
    Vue.component('third-com', {
    
    
      props: ['testTile'],
      template: '<div>{
    
    {testTile}}</div>'
    });
    Vue.component('menu-item', {
    
    
      props: ['menuTitle'],
      template: '<div>{
    
    {menuTitle}}<third-com testTile="hello"></third-com></div>'
    });
    var vm = new Vue({
    
    
      el: '#app',
      data: {
    
    
        pmsg: '父组件中内容',
        ptitle: '动态绑定属性'
      }
    });
  </script>

2.2 子组件向父组件传值

在子组件用$emit()触发事件,$emit() 第一个参数为 自定义的事件名称 第二个参数为需要传递的数据,父组件中需要使用v-on监听子组件的事件,事件名称与子组件中自定义的事件名称一致。

  <div id="app">
    <div :style='{fontSize: fontSize + "px"}'>{
    
    {
    
    pmsg}}</div>
    <menu-item @enlarge-text='handle($event)'></menu-item>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    /*
      子组件向父组件传值-携带参数
    */
    
    Vue.component('menu-item', {
    
    
      props: ['parr'],
      template: `
        <div>
          <button @click='$emit("enlarge-text", 10)'>扩大父组件中字体大小</button>
        </div>
      `
    });
    var vm = new Vue({
    
    
      el: '#app',
      data: {
    
    
        pmsg: '父组件中内容',
        fontSize: 10
      },
      methods: {
    
    
        // val为$emit()中传递过来的参数(可以是对象、数组)
        handle: function(val){
    
    
          // 扩大字体大小
          this.fontSize += val;
        }
      }
    });
  </script>

2.3 兄弟组件之间传值

兄弟之间传递数据需要借助于事件中心,通过事件中心(提供事件中心 var hub = new Vue())传递数据;传递数据方,通过一个事件触发hub. e m i t ( 方 法 名 , 传 递 的 数 据 ) , 接 收 数 据 方 , 通 过 在 m o u n t e d ( ) 钩 子 函 数 中 触 发 h u b . emit(方法名,传递的数据),接收数据方,通过在mounted(){} 钩子函数中触发hub. emit()mounted()hub.on()方法名;在数据传递结束后可以销毁事件 通过hub.$off()方法名销毁之后无法进行传递数据。

  <div id="app">
    <div>父组件</div>
    <div>
      <button @click='handle'>销毁事件</button>
    </div>
    <test-tom></test-tom>
    <test-jerry></test-jerry>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    /*
      兄弟组件之间数据传递
    */
    // 提供事件中心
    var hub = new Vue();

    Vue.component('test-tom', {
    
    
      data: function(){
    
    
        return {
    
    
          num: 0
        }
      },
      template: `
        <div>
          <div>TOM:{
     
     {num}}</div>
          <div>
            <button @click='handle'>点击</button>
          </div>
        </div>
      `,
      methods: {
    
    
        handle: function(){
    
    
          hub.$emit('jerry-event', 2);
        }
      },
      mounted: function() {
    
    
        // 监听事件
        hub.$on('tom-event', (val) => {
    
    
          this.num += val;
        });
      }
    });
    Vue.component('test-jerry', {
    
    
      data: function(){
    
    
        return {
    
    
          num: 0
        }
      },
      template: `
        <div>
          <div>JERRY:{
     
     {num}}</div>
          <div>
            <button @click='handle'>点击</button>
          </div>
        </div>
      `,
      methods: {
    
    
        handle: function(){
    
    
          // 触发兄弟组件的事件
          hub.$emit('tom-event', 1);
        }
      },
      mounted: function() {
    
    
        // 监听事件
        hub.$on('jerry-event', (val) => {
    
    
          this.num += val;
        });
      }
    });
    var vm = new Vue({
    
    
      el: '#app',
      data: {
    
    
        
      },
      methods: {
    
    
        handle: function(){
    
    
          hub.$off('tom-event');
          hub.$off('jerry-event');
        }
      }
    });
  </script>

3.组件插槽

组件的最大特性就是复用性,而用好插槽能大大提高组件的可复用能力。在子组件中设置默认内容,当父组件不向子组件传递内容时,显示默认内容。

3.1匿名插槽

在子组件中设置默认内容,当父组件不向子组件传递内容时,显示默认内容。

  <div id="app">
    <alert-box>有bug发生</alert-box>
    <alert-box>有一个警告</alert-box>
    <alert-box></alert-box>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    /*
      组件插槽:父组件向子组件传递内容
    */
    Vue.component('alert-box', {
    
    
      template: `
        <div>
          <strong>ERROR:</strong>
          <slot>默认内容</slot>
        </div>
      `
    });
    var vm = new Vue({
    
    
      el: '#app',
      data: {
    
    
        
      }
    });
  </script>

3.2 具名插槽

在slot 标签中使用name绑定相应的元素;而使用template标签能够将多个信息合并传递到某一插槽。

  <div id="app">
    <base-layout>
      <p slot='header'>标题信息</p>
      <p>主要内容1</p>
      <p>主要内容2</p>
      <p slot='footer'>底部信息信息</p>
    </base-layout>

    <base-layout>
      <template slot='header'>
        <p>标题信息1</p>
        <p>标题信息2</p>
      </template>
      <p>主要内容1</p>
      <p>主要内容2</p>
      <template slot='footer'>
        <p>底部信息信息1</p>
        <p>底部信息信息2</p>
      </template>
    </base-layout>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    /*
      具名插槽
    */
    Vue.component('base-layout', {
    
    
      template: `
        <div>
          <header>
            <slot name='header'></slot>
          </header>
          <main>
            <slot></slot>
          </main>
          <footer>
            <slot name='footer'></slot>
          </footer>
        </div>
      `
    });
    var vm = new Vue({
    
    
      el: '#app',
      data: {
    
    
        
      }
    });
  </script>

3.3 作用域插槽

作用域插槽可以在父组件对子组件加工处理,既可以复用子组件的slot,又可以使slot内容不一致。
具体使用:在子组件中定义插槽,通过属性绑定的形式将数据传递到父组件中,而在父组件中需要使用template标签以及它的slot-scope属性获取子组件的数据。如子组件中通过绑定:info 属性,父组件中时使用slot-scope=’father‘接收;当父组件需要对数据进行处理则通过father.info获取数据后进行相应的操作。

  <div id="app">
    <fruit-list :list='list'>
      <template slot-scope='slotProps'>
        <strong v-if='slotProps.info.id==3' class="current">{
    
    {
    
    slotProps.info.name}}</strong>
        <span v-else>{
    
    {
    
    slotProps.info.name}}</span>
      </template>
    </fruit-list>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    /*
      作用域插槽
    */
    Vue.component('fruit-list', {
    
    
      props: ['list'],
      template: `
        <div>
          <li :key='item.id' v-for='item in list'>
            <slot :info='item'>{
     
     {item.name}}</slot>
          </li>
        </div>
      `
    });
    var vm = new Vue({
    
    
      el: '#app',
      data: {
    
    
        list: [{
    
    
          id: 1,
          name: 'apple'
        },{
    
    
          id: 2,
          name: 'orange'
        },{
    
    
          id: 3,
          name: 'banana'
        }]
      }
    });
  </script>

猜你喜欢

转载自blog.csdn.net/weixin_42371354/article/details/104932657