vue 第三天 组件化开发

------------------ 组件化开发思想 -------------------

1.0 组件化规范: Web Components

  1. 我们希望尽可能多的重用代码
  2. 自定义组件的方式不太容易(html、css和js)
  3. 多次使用组件可能导致冲突
    官网:https://developer.mozilla.org/zh-CN/docs/Web/Web_Components

而 Vue部分实现了上述规范

------------------ 组件注册 -------------------

2.1 全局组件注册语法

	Vue.component(组件名称, {
     
		data: 组件数据,
		template: 组件模板内容
	})
	
	// 注册一个名为 button-counter 的新组件
	Vue.component('button-counter', {
     
		data: function () {
     
			return {
     
				count: 0
			}
		},
		template: ''
	})

2.2 组件用法

<div id="app">
	<button-counter></button-counter>     组件名
</div>
<div id="app">
	<button-counter></button-counter>   可以多次调用
	<button-counter></button-counter>
	<button-counter></button-counter>
</div>

2.3 组件注册注意事项

  1. data必须是一个函数

  2. 组件模板内容必须是单个跟元素( 平级根元素只能有一个 )

	只能这样  
    template: `
        
`
, 不能 这就不是单个根元素 template: ` `,
  1. 组件模板内容可以是模板字符串
    模板字符串需要浏览器提供支持(ES6语法)
  2. 组件命名方式
    如果使用驼峰式命名组件,那么在使用组件的时候,只能在字符串模板中用驼峰的方式使用组件,但是在普通的标签模板中,必须使用短横线的方式使用组件
例如:
 Vue.component('HelloWorld', {
     
	template:`
	  字符串模板中可以使用
`
})
普通标签模板中 需要修改:
<hello-world></hello-world>

	短横线方式
	Vue.component('my-component', {
      /* ... */ })
    驼峰方式
	Vue.component('MyComponent', {
      /* ... */ })

2.4 局部组件注册(写在实例里面)

	局部组件只能在注册他的父组件中使用

	1. 先定义一个 var 
     var ComponentA = {
     
   	   data: function(){
     
   	     return {
     
     	     msg: 'HelloJerry'
          }
       },
       template: '
{ {msg}}
'
}; 2. 在实例里面调用(第一个是组件名称,第二个预先设置好的参数) new Vue({ el: '#app' components: { 'component-a': ComponentA, 'component-b': ComponentB, 'component-c': ComponentC, } })

------------------ Vue调试工具用法 -------------------

可以自己百度

------------------ 组件间数据交互 -------------------

4.1 父组件向子组件传值

1. 组件内部通过props接收传递过来的值 ( props传递数据原则:单向数据流)

     Vue.component(‘menu-item', {
     
		props: ['title'],
		template: '
{ { title }}
'
})

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

	<menu-item title="来自父组件的数据"></menu-item>
	<menu-item :title="title"></menu-item>

3. props属性名规则 (跟组件名 差不多 都需要在 html 中 转换短横线形式)

  1. 在props中使用驼峰形式,普通的标签模板中 需要转换为短横线
  2. 字符串形式的模板中没有这个限制
	Vue.component(‘menu-item', {
     
	// 在 JavaScript 中是驼峰式的
		props: [‘menuTitle'],
		template: '
{ { menuTitle }}
'
}) <!– 在html中是短横线方式的 --> <menu-item menu-title=“nihao"></menu-item>

4. props属性值类型
: 就是原始的数组 不加冒号会转变为字符串 比如 :pnum=‘12’ 是数字型 pnum=‘12’ 是字符串

  1. 字符串 String
  2. 数值 Number
  3. 布尔值 Boolean
  4. 数组 Array
  5. 对象 Object

4.2 子组件向父组件传值

1. 子组件通过自定义事件向父组件传递信息 (不携带参数)

	<button v-on:click='$emit("enlarge-text") '>扩大字体</button>

2. 父组件监听子组件的事件

	<menu-item v-on:enlarge-text='handle'></menu-item>

3. 子组件通过自定义事件向父组件传递信息 (携带参数)

<button v-on:click='$emit("enlarge-text", 0.1) '>扩大字体</button>

4. 父组件监听子组件的事件 (这个 $event 等于 0.1)

<menu-item v-on:enlarge-text='handle($event)'></menu-item>

4.3 非父子组件间传值

1. 单独的事件中心管理组件间的通信

	var eventHub = new Vue() // 名字任意

2. 监听事件与销毁事件(监听事件 写在 mounted:function(){} 里面)

	eventHub.$on('add-todo', (val)=>{
     } ) 
	eventHub.$off('add-todo')

3. 触发事件

	eventHub.$emit(‘add-todo', val)

------------------ 组件插槽的作用 -------------------

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

5.2 组件插槽基本用法(父组件向子组件传递内容)

1. 插槽位置 (slot)

	Vue.component('alert-box', {
     
	!!!如果父组件没有内容, 则显示slot里面的内容,
	!!! 如果父组件有内容,则slot的内容则会被覆盖消失
		template: `
			
Error! 默认内容
`
})

2. 插槽内容( slot 里显示 Something bad happened)

	<alert-box>Something bad happened.</alert-box>

5.3 具名插槽用法(主要是 设置 slot 的 name 属性)

1. 插槽定义

        Vue.component('base-layout', {
     
            template: `
        
`
}); var vm = new Vue({ el: '#app', data: { } });

2. 插槽内容

    <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'>  
           //需要填充多个标签, 就用 template 这个固定标签
        <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>

5.4 作用域插槽

应用场景:父组件对子组件的内容进行加工处理


<body>
  <div id="app">
    <fruit-list v-bind:list='list'>
   		  2. 给 templat 设置 slot-scope='slotProps'
      <template slot-scope='slotProps'>  
      3. 里面的 属性设置  slotProps.info.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>


    Vue.component('fruit-list', {
     
      props: ['list'],
      1. 给 slot 设置 v-bind:info(任意名字) = ''
      template:   
      `    
        
  • { {item.name}}
  • `
    }); var vm = new Vue({ el: '#app', data: { list: [{ id: 1, name: 'apple' },{ id: 2, name: 'orange' },{ id: 3, name: 'banana' }] } });

    你可能感兴趣的:(vue,vue)