前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue 组件(四):组件插槽

Vue 组件(四):组件插槽

作者头像
Chor
发布2019-11-08 15:22:45
1K0
发布2019-11-08 15:22:45
举报
文章被收录于专栏:前端之旅前端之旅

1.组件化

组件实际上是可以复用的 Vue 实例,它们与 new Vue 接收相同的选项,例如 datacomputedmethods 以及生命周期钩子等。 何谓复用?如果把页面看作是组件的容器,那么导航栏、搜索框其实都是可以复用的组件。作为对可重用代码的封装,它们自身具有独立的数据和逻辑。

前端组件化的核心思路就是将一个巨大复杂的东西拆分成若干个小东西(组件),这些组件可以自由组合、替换和删除,同时不影响整个应用的运行,这就是组件化开发。

组件化的好处是:

  • 提高开发效率
  • 方便重复使用,简化调试步骤,方便单元测试
  • 提升整个项目的可维护性,方便团队成员的协同开发
  • 高内聚(功能必须是完整的)、低耦合(解耦业务逻辑和数据)

2.创建组件

2.1 全局组件

全局组件在 new Vue 之前创建,创建之后可用于所有根实例的模板中。 2.x 之前全局组件的创建过程如下:

代码语言:javascript
复制
let obj = Vue.extend({/*option*/})   // 创建组件构造器对象
Vue.component(TagName,obj)           // 注册组件

2.x 之后语法糖的写法如下:

代码语言:javascript
复制
Vue.component("TagName",{/*option*/})   // 同时创建并注册组件

2.2 局部组件

更多的是创建局部组件,让其只能在当前所处的 Vue 实例的模板中使用。

代码语言:javascript
复制
var obj = {/*option*/}
const app = new Vue({
  el:'#app',
  components:{
    "aaa":obj
  }
})

如果需要创建父子组件,那么可以这样写:

代码语言:javascript
复制
var son = {/*option*/}

var parent = {
  template:`<div><h2>something</h2><bbb></bbb></div>`,
  components:{
    "bbb":son
  }
}

const app = new Vue({
  el:'#app',
  components:{
    "aaa":parent
  }
})

之后在 dom 中书写 <aaa></aaa> ,会发现父子组件都可以渲染,但是单独书写 <bbb></bbb> 则无法渲染子组件,这是因为子组件是在父组件中注册的,因此它只能在父组件的模板中使用。

2.3 模板抽离

上面的 <div><h2>something</h2><bbb></bbb></div> 可以单独抽离出来放在一个有 id 的 <template></template> 中,之后直接 #id 引用该模板即可。

代码语言:javascript
复制
<template id="temp">
  <div>
    <h2>something</h2>
    <bbb></bbb>
  </div>
</template>

// 改写如下:
var parent = {
  template:`<div><h2>something</h2><bbb></bbb></div>`,
  components:{
    bbb:"#temp"
  }
}

注意:每个组件都必须有且仅能有一个根元素,这意味着组件所有的内容必须包裹在一个最外层元素中。

3. 组件的命名

组件创建后,直接在 dom 中书写组件名即可使用组件。但是组件的命名有一定的规则。 定义组件名的方式有两种:

(1) 使用 kebab-case(字母全小写+连字符),例如:

代码语言:javascript
复制
Vue.component('my-component', { /*option*/ })

使用时也必须是 kebab-case。即 <my-component></my-component>,否则会报错。

(2) 使用 PascalCase(帕斯卡),例如:

代码语言:javascript
复制
Vue.component('MyComponent',{/* option*/})

如果是在父组件模板(模板没有抽离到 HTML 中的)中使用,则允许 kebab-case 和 PascalCase 两种方式,即 <MyComponent></MyComponent> 或者 <my-component></my-component> 都是允许的;但是如果直接在 DOM (非字符串的模板)中,则只能使用相应的 kebab-case,否则会报错。

我们来看一个例子:

上图中我们创建了父子组件,其中子组件采用 PascalCase 命名,之后在父组件模板中引用子组件时,发现不管是 kebab-case 命名还是 PascalCase 命名都是可以成功渲染的。

再来看第二张图:

我们创建了 HisCpn 组件,之后直接在 DOM 中引用(没有转换为 kebab-case 命名),结果报错了;同样的,我们创建了 cpn1MyCpn 父子组件,之后直接在 DOM 中引用,发现转换为 kebab-case 命名 的子组件可以正常渲染,而仍然采用 PascalCase 命名的子组件则报错了,因为前面我们说过:如果直接在 DOM (非字符串的模板)中,则只能使用相应的 kebab-case,否则会报错。

注意: PascalCase 每个单词首字母都大写,而 camelCase 即驼峰式命名第一个单词首字母不大写。

4. 为什么组件的 data 必须是函数?

另外还有一个需要注意的地方是,根实例的 data 是对象,但是组件的 data 却是函数。 这是因为组件是可复用的,每次使用一次 <my-component></my-component> 就会创建一个组件实例,如果定义组件时 data 依然返回的是对象,那么一个组件数据的更改将会同步影响到其它组件,因为它们共享一个 data 对象。如下图所示,我们只操作了一个组件,但三个组件数据都同步改变:

相反,如果 data 是函数,那么每次函数执行时都会开辟新的内存空间,创建并返回一个新的对象副本,这使得每个实例都有自己的 data 对象,实例互相之间不影响。如下图所示:

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-10-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.组件化
  • 2.创建组件
    • 2.1 全局组件
      • 2.2 局部组件
        • 2.3 模板抽离
        • 3. 组件的命名
        • 4. 为什么组件的 data 必须是函数?
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档