• 03 Vue组件化开发


    1. 组件化开发思想

    1.1 组件化思想

    • 标准
    • 分治
    • 重用
    • 组合

    1.2 组件化规范: Web Components##

    并不是所有浏览器都支持这个规范

    • 我们希望尽可能多的重用代码
    • 自定义组件的方式不太容易(html、css和js)
    • 多次使用组件可能导致冲突

    Web Components 通过创建封装好功能的定制元素解决上述问题

    官网:https://developer.mozilla.org/zh-CN/docs/Web/Web_Components

    Vue部分实现了上述规范

    2. 组件注册

    2.1 全局组件注册语法

    Vue.component(组件名称, {
    	data: 组件数据,
    	template: 组件模板内容
    })
    

    演示

    // 注册一个名为 button-counter 的新组件 Vue.component('button-counter', {
    data: function () {
    	return {
    		count: 0
    	}
    }, 
    template: '<button v-on:click="count++">点击了{{ count }}次.</button>'
     })
    

    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.组件模板内容必须是单个跟元素

    3.组件模板内容可以是模板字符串 ⚫

    • 模板字符串需要浏览器提供支持(ES6语法)

    4.组件命名方式

    • 短横线方式

        Vue.component('my-component', { /* ... */ })
      
    • 驼峰方式

        Vue.component('MyComponent', { /* ... */ })
      

    2.4 局部组件注册

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

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

    3. 组件间数据交互

    3.1 父组件向子组件传值

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

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

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

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

    3.props属性名规则

    • 在props中使用驼峰形式,模板中需要使用短横线的形式

    • 字符串形式的模板中没有这个限制

      Vue.component(‘menu-item', {
      // 在 JavaScript 中是驼峰式的
      props: [‘menuTitle'],
      template: '

      {{ menuTitle }}
      '
      })
      <!– 在html中是短横线方式的 -->
      <menu-item menu-title=“nihao">

    4.props属性值类型

    • 字符串 String
    • 数值 Number 不绑定是字符类型
    • 布尔值 Boolean 不绑定是字符类型
    • 数组 Array
    • 对象 Object

    演示

    <body>
        <div id="app">
            <div>{{pmsg}}</div>
            <menu-item :pstr="pstr" :pnum="12" :pboo=true :parr="parr" :pobj="pobj"></menu-item>
        </div>
        <script type="text/javascript" src="js/vue.js"></script>
        <script type="text/javascript">
            // 父组件向子组件传值
            Vue.component('menu-item', {
                props: ["pstr", "pnum", "pboo", "parr", "pobj"],
                template: `
                    <div>
                        <div>{{typeof pstr}}</div>
                        <div>{{12 + pnum}}</div>
                        <div>{{typeof pboo}}</div>
                        <ul>
                           <li :key='index' v-for='(item,index) in parr'> {{item}}</li>
                        </ul>
                        <div><span>{{pobj.name}}</span></div>
                        <div><span>{{pobj.age}}</span></div>
    
                    </div>
                `
            })
    
            var vm = new Vue({
                el: '#app',
                data: {
                    pmsg: '父组件中内容',
                    pstr: 'hello',
                    parr: ['apple', 'orange'],
                    pobj: {
                        age: 18,
                        name: "水井"
                    }
                }
            })
        </script>
    
    </body>
    

    4.2 子组件向父组件传值

    props传递数据原则:单向数据流

    1.子组件通过自定义事件向父组件传递信息

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

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

    <menu-item v-on:enlarge-text='fontSize += 0.1'></menu-item>
    

    3.子组件通过自定义事件向父组件传递信息

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

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

    <menu-item v-on:enlarge-text='fontSize += $event'></menu-item>
    // $event是固定的 
    

    4.3 兄弟组件间传值

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

    var eventHub = new Vue()
    

    2.监听事件与销毁事件

    eventHub.$on('add-todo', addTodo)
    eventHub.$off('add-todo')
    

    3.触发事件

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

    5. 组件插槽

    5.1 组件插槽的作用

    父组件向子组件传递内容(模板内容)

    组件插槽固定名称 slot

    5.2 组件插槽基本用法

    1.插槽位置

    Vue.component('alert-box', {
    	template: `
    		<div class="demo-alert-box">
    			<strong>Error!</strong>
    			<slot></slot>
    		</div>
    	`
    })
    

    2.插槽内容

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

    5.3 具名插槽用法

    1.插槽定义

    <div class="container">
    	<header>
    		<slot name="header"></slot>
    	</header>
    	<main>
    		<slot></slot>
    	</main>
    	<footer>
    		<slot name="footer"></slot>
    	</footer>
    </div>
    

    2.插槽内容

    <base-layout> 
    	<h1 slot="header">标题内容</h1>
    	<p>主要内容1</p> 
    	<p>主要内容2</p>
    	<p slot="footer">底部内容</p> 
    </base-layout>
    

    演示

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    
    <body>
        <div id="app">
            <!-- 第一种写法 -->
            <alert-box>
                <p slot="header">标题信息</p>
                <p>主要内容1</p>
                <p>主要内容2</p>
                <p slot="footer">底部信息</p>
            </alert-box>
    
            <!-- 第二种写法 -->
            <alert-box>
                <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>
            </alert-box>
        </div>
        <script type="text/javascript" src="js/vue.js"></script>
        <script type="text/javascript">
            //   组件插槽:父组件向子组件传递内容
            Vue.component('alert-box', {
                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>
    </body>
    
    </html>
    

    5.4 作用域插槽

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

    1.插槽定义

    <ul>
    	<li v-for= "item in list" v-bind:key= "item.id" >
    		<slot v-bind:item="item">
    			{{item.name}}
    		</slot>
    	</li>
    </ul>
    

    2.插槽内容

    <fruit-list v-bind:list= "list">
    	<template slot-scope="slotProps">
    		<strong v-if="slotProps.item.current">
    			{{ slotProps.item.text }}
    		</strong>
    	</template>
    </fruit-list>
  • 相关阅读:
    双向绑定v-bind
    梁山好汉为何成不了大气候?(转)
    八大排序算法(转)
    在c或c+程序里打印调用栈。转
    cocos2dx 做test遇到一个问题,记录下来
    我所理解的cocos2dx自适配屏幕大小方案
    eclipse pydev 跳转
    mac 系统通用快捷键(mac 下的应用多数会往这些标准看齐)(转:http://yang3wei.github.io/blog/2013/02/08/chen-ni-yu-mac-chen-ni-yu-xcode/)
    使用cgitb来简化异常调试(记录下来,感觉很有用)
    python trackback的使用心得
  • 原文地址:https://www.cnblogs.com/xujinglog/p/13304204.html
Copyright © 2020-2023  润新知