1.组件化

在大型应用开发的时候,页面可以划分成很多部分。往往不同的页面,也会有相同的部分。例如可能会有相同的头部导航、尾部信息模块。

但是如果每个页面都独自开发,这无疑增加了我们开发的成本。所以我们会把页面的不同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发。

1.1.定义全局组件

我们可以使用 Vue.component 来定义一个组件:

Vue.component(组件名称, Vue对象)

在 Vue 对象中我们需要使用 template 来定义组件的 HTML 部分。

(提示:在 ES6 中我们可以使用 模板字符串` 符号来定义多行字符串)

示例:

Vue.component('hello', {
    template: `<p>Hello World !</p>`
})

注意:template 中的 HTML 代码必须要写在一个根元素中。

什么是根元素呢?看下图:

根元素:最外层要有一个标签。

在这里插入图片描述

  • 案例:

在这里插入图片描述

  • 案例实现
<script src="../vue-2.5.17.js"></script>
<div id="app">
    <counter></counter>
</div>
<script>
// 定义全局组件,两个参数,组件名称和组件参数
Vue.component("counter",{
    template:`<button v-on:click="count++" >{{count}}</button>`,
    data(){
        return {
            count:0
        }
    }

})

var vm = new Vue({
   el:"#app",
});
</script>
  • 组件其实也是一个Vue实例,因此它在定义时也会接收:data、methods、生命周期函数等
  • 不同的是组件不会与页面的元素绑定,否则就无法复用了,因此没有el属性。
  • 但是组件渲染需要html模板,所以增加了template属性,值就是HTML模板
  • 全局组件定义完毕,任何vue实例都可以直接在HTML中通过组件名称来使用组件了。
  • data的定义方式比较特殊,必须是一个函数。

总结一下:

  • 全局组件只能有一个根元素
  • 组件中有data、methods、created、computed
  • data一定要定义成方法,而且必须要有返回值

1.2.组件的复用

定义好的组件,可以任意复用多次:

<div id="app">
    <!--使用定义好的全局组件-->
    <counter></counter>
    <counter></counter>
    <counter></counter>
</div>

效果:

在这里插入图片描述

你会发现每个组件互不干扰,都有自己的count值。怎么实现的?

组件的data属性必须是函数

当我们定义这个 <counter> 组件时,它的data 并不是像这样直接提供一个对象:

data: {
  count: 0
}

取而代之的是,一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:

data: function () {
  return {
    count: 0
  }
}

如果 Vue 没有这条规则,点击一个按钮就会影响到其它所有实例!

案例:

<script src="../vue-2.5.17.js"></script>
<div id="app">
    <!-- 组件肯定使用在页面中
         组件的使用方式:以组件名为标签访问
     -->
    <counter></counter><br>
    <counter></counter><br>
    <list></list><br>
    <list></list><br>
</div>
<script>
// 全局组件挂在到Vue对象中
// 第一个参数:组件名字
// 第二个参数:组件内容,需要是一个对象
Vue.component("counter",{
    // 在组件中也必须要有模板,模板要写在一个根元素中,在vue中,只能有一个最大的父元素绑定el
    // 模板内容需要使用 模板字符串
    template:`<button @click="num++">加{{num}}</button>`,
    // 模板中,data只能定义成方法格式,不能定义属性
    // data方法必须要有返回值
    data(){
        return {
            num:0
        }
    },
    methods:{

    }
});

// 继续写
Vue.component("list",{
    template:`<ul>
                <li v-for="user in users">{{user.name}} - {{user.age}}</li>
            </ul>`,
    data(){
        return {
            users:[{name:"lucy",age:12},
                {name:"tom",age:12},
                {name:"lily",age:12}
            ]
        }
    }
})



var vm = new Vue({
  el:"#app"
})
</script>

1.2.局部注册

一旦全局注册,就意味着即便以后你不再使用这个组件,它依然会随着Vue的加载而加载。

因此,对于一些并不频繁使用的组件,我们会采用局部注册。

我们先在外部定义一个对象,结构与创建组件时传递的第二个参数一致:

const counter = {
    template:'<button v-on:click="count++">点击 {{ count }} </button>',
    data(){
        return {
            count:0
        }
    }
};

然后在Vue中使用它:

var app = new Vue({
    el:"#app",
    components:{
        counter:counter // 将定义的对象注册为组件
    }
})
  • components就是当前vue对象子组件集合。
    • 其key就是子组件名称
    • 其值就是组件对象的属性
  • 效果与刚才的全局注册是类似的,不同的是,这个counter组件只能在当前的Vue实例中使用

1.3.组件通信

通常一个页面会以一棵嵌套的组件树的形式来组织:

在这里插入图片描述

  • 页面首先分成了顶部导航、左侧内容区、右侧边栏三部分
  • 左侧内容区又分为上下两个组件
  • 右侧边栏中又包含了3个子组件

各个组件之间以嵌套的关系组合在一起,那么这个时候不可避免的会有组件间通信的需求。

1.3.1.父向子传递props

父组件是通过props属性给子组件通信的来看下代码:

父组件:

<parent>
    <child :child-com="content"></child> //注意这里用驼峰写法哦
</parent>

data(){
    return {
        content:'lixin'
    };
}

子组件通过props来接受数据

第一种方法

props: ['childCom']

第二种方法

props: {
    childCom: String //这里指定了字符串类型,如果类型不一致会警告的哦
}

第三种方法

props: {
    childCom: {
        type: String,
        default: 'lixin' 
    }
}

1.3.2.子向父传递$emit

vue2.0只允许单向数据传递,我们通过出发事件来改变组件的数据,废话少说,上干货

子组件代码

<template>
    <div @click="open"></div>
</template>

methods: {
   open() {
        this.$emit('showbox','the msg'); //触发showbox方法,'the msg'为向父组件传递的数据
    }
}

父组件

<child @showbox="toshow" :msg="msg"></child> //监听子组件触发的showbox事件,然后调用toshow方法

methods: {
    toshow(msg) {
        this.msg = msg;
    }
}

1.3.3.兄弟传递$emit $on

我们可以实例化一个vue实例,相当于一个第三方

let vm = new Vue(); //创建一个新实例

组件他哥

<div @click="ge"></div>
methods: {
    ge() {
        vm.$emit('blur','lixin'); //触发事件
    }
}

组件小弟接受大哥命令

<div></div>
created() {
  vm.$on('blur', (arg) => { 
        this.test= arg; // 接收
    });
}
Logo

前往低代码交流专区

更多推荐