Vue基础day03总结

1 组件

  • 组件可以扩展 HTML 元素,封装可重用的代码
  • 组件参数的data值必须是函数,要求返回一个对象.。所以各个组件的数据私有,值相互独立,即每个实例可以维护一份被返回对象的独立的拷贝。
  • 组件模板必须是单个根元素(html标签有一个顶级根元素,不能是兄弟节点)
  • 组件模板的内容可以是模板字符串``((ES6语法))
  • 命名:短横线(my-component)和驼峰式(MyComponent)—建议使用短横线
  • 全局组件是component,没有s的;而局部组件是components,是有s的

全局组件

全局组件注册后,任何vue实例都可以用
定义:

Vue.component(组件名称, {
	data: 组件数据(data的值必须是函数),
	template: 组件模板内容
})

使用方式:
(1)注册

<script type="text/javascript">
  //全局组件	    
  // 注册一个名为 button-counter 的新组件
  Vue.component('button-counter', {
    data: function(){
      return {
        count: 0
      }
    },
    template: '<button @click="handle">点击了{{count}}次</button>',
    //组件里也可以定义自己的方法
    methods: {
      handle: function(){
        this.count += 2;
      }
    }
  });
  //vm是一个vue实例
  var vm = new Vue({
    el: '#app',
    data: {
      
    }
  });
</script>

(2)使用

<div id="app">
  <!-- 无论组件在注册时采用短横线还是驼峰命名,在html中使用组件必须使用短横线的命名方式 -->
  <button-counter></button-counter>
  <button-counter></button-counter>
  <button-counter></button-counter>
</div>

效果:
在这里插入图片描述

局部组件

只能在当前注册它的vue实例(它的父组件)中使用
定义:

	var ComponentA = { /* data...template... */ }
	var ComponentB = { /* data...template... */ }
	var ComponentC = { /* data...template... */ }
	new Vue({
	el: '#app'
	components: {
	'component-a': ComponentA,
	'component-b': ComponentB,
	'component-c': ComponentC,
	}
	})

使用方式:
(1)注册

<script type="text/javascript">
 //1 定义组件
  var HelloWorld = {
    data: function(){
      return {
        msg: 'HelloWorld111'
      }
    },
    template: '<div>{{msg}}</div>'
  };
  var HelloTom = {
    data: function(){
      return {
        msg: 'HelloTom222'
      }
    },
    template: '<div>{{msg}}</div>'
  };
  var HelloJerry = {
    data: function(){
      return {
        msg: 'HelloJerry333'
      }
    },
    template: '<div>{{msg}}</div>'
  };

  var vm = new Vue({
    el: '#app',
    data: {
      
    },
    //2 局部注册
    components: {
      'hello-world': HelloWorld,
      'hello-tom': HelloTom,
      'hello-jerry': HelloJerry
    }
  });
</script>

(2)使用

<div id="app">
  <hello-world></hello-world>
  <hello-tom></hello-tom>
  <hello-jerry></hello-jerry>
</div>

效果:
在这里插入图片描述

2 组件之间的数据传值

父组件向子组件传值

  • 父组件通过属性将值传递给子组件
  • 子组件用属性props接收(props传递数据原则:单向数据流 父->子)
<div id="app">
<div>{{pmsg}}</div>
  <!--2 为子组件绑定父组件的属性值 -->
  <!-- 父组件(vm实例)通过属性title将值传递给子组件(menu-item) -->
  <menu-item title='来自父组件的值'></menu-item>
  <!-- 父组件通过属性title和content将值传递给子组件 ,title的值ptitle来自父组件data 中的数据,
  传的值可以是数字、布尔、字符串、对象、数组 -->
  <menu-item :title='ptitle' content='hello'></menu-item>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
  
  Vue.component('menu-item', {
     //3 子组件用props接收数据
    //子组件用属性props接收title和content
    props: ['title', 'content'],
    data: function() {
      return {
        msg: '子组件本身的数据'
      }
    },
    template: '<div>{{msg + "----" + title + "-----" + content}}</div>'
  });
  var vm = new Vue({
    el: '#app',
    data: {
      //1 要传递给子组件的数据
      pmsg: '父组件中内容',
      ptitle: '动态绑定属性'
    }
  });
</script>

效果:
在这里插入图片描述

子组件向父组件传值

  • 子组件通过自定义事件 $emit(arg1,arg2) 向父组件传递信息
  • arg1是自定义的事件名称 ,arg2是需要传递的数据
  • 父组件用 v-on:arg1或者@arg1 监听子组件的事件
<div id="app">
  <div :style='{fontSize: fontSize + "px"}'>{{pmsg}}</div>
  <menu-item :parr='parr' @enlarge-text='handle($event)'></menu-item>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
  //子组件
  //子组件用$emit(自定义的事件名称,传递的数据)触发事件
  Vue.component('menu-item', {
    props: ['parr'],
    template: `
      <div>
        <ul>
          <li :key='index' v-for='(item,index) in parr'>{{item}}</li>
        </ul>
        <button @click='$emit("enlarge-text",5)'>子组件1,扩大5px</button>
        <button @click='$emit("enlarge-text",10)'>子组件2,扩大10px</button>
      </div>
    `
  });
  //父组件
  var vm = new Vue({
    el: '#app',
    data: {
      pmsg: '父组件中内容',
      parr: ['apple','orange','banana'],
      fontSize: 10
    },
    methods: {
      handle: function(val){
        // 扩大字体大小
        this.fontSize += val;
      }
    }
  });
</script>

效果:
在这里插入图片描述

兄弟组件之间的传值

  • 单独的事件中心管理组件间的通信:var eventHub = new Vue()
  • 监听事件:eventHub.$on(‘add-todo’, addTodo)
    mounted时监听
  • 触发事件:eventHub.$emit(‘add-todo’, id)
  • 销毁事件:eventHub.$off(‘add-todo’)
<script type="text/javascript">
  // 1 事件中心
  var hub = new Vue();

  //子组件1
  Vue.component('test-one', {
    data: function(){
      return {
        num: 0
      }
    },
    template: `
      <div>
        <div>子组件1:{{num}}</div>
        <div>
          <button @click='handle'>点击</button>
        </div>
      </div>
    `,
    methods: {
      handle: function(){
        //3 触发事件(这里触发兄弟组件2的事件)
        hub.$emit('second-event', 2);
      }
    },
    mounted: function() {
      //2 监听事件
      hub.$on('first-event', (val) => {
        this.num += val;
      });
    }
  });

  //子组件2
  Vue.component('test-two', {
    data: function(){
      return {
        num: 0
      }
    },
    template: `
      <div>
        <div>子组件2:{{num}}</div>
        <div>
          <button @click='handle'>点击</button>
        </div>
      </div>
    `,
    methods: {
      handle: function(){
        // 触发事件(这里触发兄弟组件1的事件)
        hub.$emit('first-event', 1);
      }
    },
    mounted: function() {
      hub.$on('second-event', (val) => {
        this.num += val;
      });
    }
  });
  var vm = new Vue({
    el: '#app',
    data: {
      
    },
    methods: {
      handle: function(){
        // 4 销毁事件
        hub.$off('first-event');
        hub.$off('second-event');
      }
    }
  });
</script>
<div id="app">
  <div>父组件</div>
  <div>
    <button @click='handle'>销毁事件</button>
  </div>
  <test-one></test-one>
  <test-two></test-two>
</div>

在这里插入图片描述

3 组件插槽

作用:父组件向子组件传递内容

<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">
  //子组件
  //插槽的位置在子组件的template里
  Vue.component('alert-box', {
    template: `
      <div>
        <strong>ERROR:</strong>
        <slot>默认内容</slot>
      </div>
    `
  });
  var vm = new Vue({
    el: '#app',
    data: {
      
    }
  });
</script>

在这里插入图片描述

具名插槽

在组件base-layout的template中定义如下:

<div>
  <header>
    <slot name='header'></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name='footer'></slot>
  </footer>
</div>

html中使用:

<!-- 使用方式一 -->
<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 id="app">
  <!--2 子组件中绑定属性,值为fruitlist -->
  <fruit-list :list='fruitlist'>
     <!-- 通过slotProps可以拿到子组件中插槽传过来的数据slotProps.info -->
    <template slot-scope='slotProps'>
      <!-- 如果id为3,加样式 -->
      <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', {
    // 3 子组件使用props属性接收传的值
    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: {
      // 1 父组件中的数据fruitlist
      fruitlist: [{
        id: 1,
        name: 'apple'
      },{
        id: 2,
        name: 'orange'
      },{
        id: 3,
        name: 'banana'
      }]
    }
  });
</script>
.current {
   color: orange;
}

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值