Vue组件化开发

一、组件基础

【官网定义】

1、组件是可复用的 Vue 实例 ;
2、它们与 new Vue 接收相同的选项,例如 【data】、【computed】、【watch】、【methods】以及【生命周期钩子】等;
3、仅有的例外是没有像 el 这样根实例特有的选项
4、一个组件的 data 选项【必须是一个函数】,因此每个实例可以维护一份被返回对象的独立的拷贝

【命名方式】

1、【连接符形式】 <my-component-name> 
    适用于【DOM】与【template】
2、【驼峰式】 <my-component-name> 
    仅适用于【template】

【总结】

1、当使用 【驼峰式】 定义一个组件时,你在引用这个自定义元素时两种命名法都可以使用。
2、也就是说 和 都是可接受的。
3、注意,尽管如此,直接在【DOM】(即非字符串的模板) 中使用时只有【连接符形式】是有效的。

【注册类型】

1、全局注册

Vue.component("header-app", {
            // 组件中的data都是一个函数 , 返回对象
            data() {
                return {
                    msg: "全局的组件header-app"
                }
            },
            // 必须有一个根标签 
            template: `
                <header>
                    {{msg}}
                    <button @click='test'>按钮</button>
                    <DemoC />
                </header>
            `,
            methods: {
                test() {
                    alert("测试组件中的方法")
                }
            },
            components: {
                DemoC: cc
            }
        })

2、局部注册 —类似于按需引入

let vm = new Vue({
    el: "#app",
    data: {
        msg: "vm中的msg"
    },
    // 2、注册局部组件 FooterApp 
    // 3、外部引入组件 DemoC
    components: {
        FooterApp: {
            data() {
                return {
                    msg: "FooterApp的msg"
                }
            },
            template: `
                <footer>
                    {{msg}}
                    <button @click='test'>按钮</button>
                </footer>
            `,
            methods: {
                test() {
                    alert("测试组件中的方法--footerApp")
                }
            }
        },
        DemoC: cc
    },
    methods: {
        test() {
            alert("vm中的")
        }
    }
})

【总结】

1、被全局注册的组件,可以在全局任何一个组件内使用
2、被局部注册的组件,只能在当前在这里插入代码片注册的范围内使用

二、组件化开发实战回顾

1. 分析页面结构

【组件分区】

在这里插入图片描述

【页面结构】

在这里插入图片描述

2.组件抽离 【以homeRight为例】

2.1 思路分析:

a、【页面右侧】分为【右边上半区域】和【右边下半区域】
b、【右边下半区域】中可抽离出【表单组件】

2.2 具体源码:

1. homeRight 【页面右侧】
(function () {
    window.homeRight = {
        template: `
        <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
        <!--右边上半区域-->
        <homeTop @delete_hobby="deleteHobby" :hobbies='hobbies'></homeTop>
        <!--右边下半区域-->
        <homeDown :deltetEmp='deltetEmp' :empList="empList">
           
        </homeDown>
      </div>
        `,
        components: {
            homeTop,
            homeDown
        },
        data() {
            return {
                hobbies: ["吃", "喝", "玩", "乐"],
                empList: [
                    { id: 1, name: "小红", num: 20240311 },
                    { id: 2, name: "小王", num: 20240311 },
                    { id: 3, name: "小刚", num: 20240311 }
                ]
            }
        }
    }
}())
2.homeTop 【右边上半区域】
(function () {
    window.homeTop = {
        template: `
        <div>
            <h1 class="page-header">{{i}}</h1>
            <div class="row placeholders">
                <div v-for="(item,index) in hobbies" class="col-xs-6 col-sm-3 placeholder">
                    <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200"
                    height="200" class="img-responsive" alt="Generic placeholder thumbnail">
                    <h4>{{item}}</h4>
                    <span class="text-muted" @click="deleteHobby(index)">删除</span>
                </div>
            </div>
        </div>
        `,
        props:['hobbies'],
        methods: {
            deleteHobby(index){
                this.$emit("delete_hobby",index)
            }
        },
        created () {
            PubSub.subscribe('test', (e, num) => {
                this.i = num
            })
        },
        data () {
            return {
                i:0
            }
        }
    }
}())
3.homeDown 【右边下半区域】
(function () {
    window.homeDown = {
        template: `
            <div>
                <h2 class="sub-header">Section title</h2>
                <slot name='111'>111</slot>
                <slot name='222'>222</slot>
                <div class="table-responsive">
                <table class="table table-striped">
                    <thead>
                    <tr>
                        <th>#</th>
                        <th>Header</th>
                        <th>Header</th>
                        <th>Header</th>
                    </tr>
                    </thead>
                    <tbody>
                        <Item :key='item.id' v-for="(item,index) in empList"
                        :emp='item' :deltetEmp="deltetEmp" :index='index'></Item>
                    </tbody>
                </table>
                </div>
            </div>
        `,
        components: {
            Item
        },
        props: {
            "empList": Array,
            "deltetEmp":Function
        }
    }
}())
4.Item 【表单组件】
(function () {
    // 可以在tr这里写v-for吗??
    window.Item = {
        template: `
        <tr>
            <td>{{emp.id}}</td>
            <td>{{emp.name}}</td>
            <td>{{emp.num}}</td>
            <td><a href="www.baidu.com" @click.prevent='deltetEmpIndex'>删除</a></td>
        </tr>
        `,
        props: {
            "emp": {
                require: true,
                type: Object
            },
            'index': {
                require: true,
                type: Number
            },
            "deltetEmp": {
                require: true,
                type: Function
            }
        },
        methods: {
            deltetEmpIndex() {
                if (window.confirm("你确定要删除")) {
                    this.deltetEmp(this.index)
                }
            }
        }
    }
}())

3. 极致组件化

在这里插入图片描述

3.1 根组件提取app.js

1. 具体操作
a、将index.html中<div id="#app">标签体中的代码提取,变成根组件存入app.js中
b、app.js的template中引用了AppNavbar、AppLeaf和AppHome组件,所以我们要将index.html中的components选项中的组件对象剪切到App组件对象中。
2. 源码
// 组件入口 app.js
(function () {
    template = `
        <div>
            <!--头部导航区域-->
            <app-nav-bar></app-nav-bar>
            <!--核心区域:分左右两边-->
            <app-home></app-home>
        </div>
    `
    window.App = {
        template,
        components: {
            AppNavBar,
            "AppHome":AppHome
        }
    }
}())

3.2 提取index.html中的js文件

1. 具体操作
前index.html文件中还有JS代码,可以将这些JS代码提取出来放到main.js
2. 源码
// 程序入口
new Vue({
    el: '#app',
    template: '<App></App>',
    components: {
        App
    }
})

3.3 引入

1. 具体操作
引入app.js 和 main.js文件
2. 源码
  <!-- 组件入口 相当于 App.vue -->
  <script src="./components/app.js"></script>
  <!-- 程序入口 相当于app.js -->
  <script src="./main.js"></script>
  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值