【Vue】组件

Vue的两大核心

  1. 数据驱动 - 数据驱动界面显示
  2. 模块化 - 复用公共模块,组件实现模块化提供基础

组件基础


组件渲染过程

template ---> ast(抽象语法树) ---> render ---> VDom(虚拟DOM) ---> 真实的Dom ---> 页面

Vue组件需要编译,编译过程可能发生在

  • 打包过程 (使用vue文件编写)
  • 运行时(将字符串赋值template字段,挂载到一个元素上并以其 DOM 内部的 HTML 作为模板)

对应的两种方式 runtime-only vs runtime-compiler

runtime-only(默认)

  • 打包时只包含运行时,因此体积更少
  • 将template在打包的时候,就已经编译为render函数,因此性能更好

runtime-compiler

  • 打包时需要包含(运行时 + 编译器),因此体积更大,大概多10Kb
  • 在运行的时候才把template编译为render函数,因此性能更差

启用runtime-compiler两种方式

  1. main.js启用
Vue.config.runtimeCompiler = true
  1. vue.config.js(若没有手动创建一个)
module.exports = {
    runtimeCompiler: true      //默认false
}

组件定义


1. 字符串形式定义(不推荐)

例子

const CustomButton = {
  template: "<button>自定义按钮</button>"
};

这种形式需要启用运行时编译(runtime-compiler)

2. 单文件组件(推荐)

创建.vue后缀的文件,定义如下

<template>
  <div>
    <button>自定义按钮</button>
  </div>
</template>

<template> 里只能有一个根节点,即第一层只能有一个节点,不能多个节点平级

这种形式在打包的时就编译成render函数,因此跟推荐这种方式定义组件

组件注册


  1. 全局注册
    全局注册是通过Vue.component()注册
import CustomButton from './components/ComponentDemo.vue'
Vue.component('CustomButton', CustomButton)

优点

  • 其他地方可以直接使用
  • 不再需要components指定组件

缺点

  • 全局注册的组件会全部一起打包,增加app.js体积

适合

  • 基础组件全局注册
  1. 局部注册
    在需要的地方导入
<template>
  <div id="app">
    <customButton></customButton>
  </div>
</template>
<script>
import CustomButton from "./components/ComponentDemo.vue";

export default {
  name: "App",
  components: { CustomButton }
};
</script>

优点

  • 按需加载

缺点

  • 每次使用必须导入,然后components指定

适合

  • 非基础组件

组件使用


组件复用
<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png" />
    <customButton></customButton>
    <customButton></customButton>
    <customButton></customButton>
  </div>
</template>

customButton 组件

<template>
  <div id="app">
    <button @click="increment">click me {{times}} times</button>
  </div>
</template>
<script>
export default {
  data() {
    return { times: 0 };
  },
  methods: {
    increment() {
      return this.times++;
    }
  }
};
</script>

每个组件都会创建一个新实例,组件的data必须是function,因此每个实例维护自己的data数据

组件传参
  1. 通过props属性
<template>
  <button> {{buttonText}} </button>
</template>
<script>
export default {
  props: {
    buttonText: String
  }
};
</script>
<customButton buttonText="Button 1"></customButton>
<customButton buttonText="Button 2"></customButton>
<customButton buttonText="Button 3"></customButton>
运行效果
  1. 通过插槽<slot></slot>
<template>
  <button style="margin:10px"><slot>Defalt Button</slot></button>
</template>
<script>
export default {
  props: {
    buttonText: String
  }
};
</script>
<customButton></customButton>
<customButton><span style="color:blue">Button 2</span></customButton>
<customButton>Button 3</customButton>
运行效果

看到是用自定义组件的innerHtml替换插槽,若插槽只有一个,可以不写name attribute,若多个插槽需指定插槽name attribute

自定义事件
  1. 在组件内部调用this.$emit触发自定义事件
<template>
  <div style="margin:10px">
    <button @click="increment">
      <slot>Defalt Button</slot>
    </button>
    <span>Click me {{times}} times</span>
  </div>
</template>
<script>
export default {
  props: {
    buttonText: String
  },
  data() {
    return { times: 0 };
  },
  methods: {
    increment() {
      this.times++;
        ("increment");
    }
  }
};
</script>
  1. 调用者监听自定义事件
<template>
  <div id="app">
    <customButton @increment="handleIncrement"></customButton>
    <customButton @increment="handleIncrement">
      <span style="color:blue">Button 2</span>
    </customButton>
    <customButton @increment="handleIncrement">Button 3</customButton>
    <p>Total click {{totalClicks}} times</p>
  </div>
</template>
<script>
import CustomButton from "./components/ComponentDemo.vue";

export default {
  name: "App",
  components: { CustomButton },
  data() {
    return { totalClicks: 0 };
  },
  methods: {
    handleIncrement() {
      this.totalClicks++;
    }
  }
};
</script>
运行效果
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容

  • 此文基于官方文档,里面部分例子有改动,加上了一些自己的理解 什么是组件? 组件(Component)是 Vue.j...
    陆志均阅读 3,825评论 5 14
  • 三、组件 组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML元素,封装可重用...
    小山居阅读 608评论 0 1
  • 从接触angularjs1.x开始,使用并开发过很多组件和指令,它能极大的扩展web的业务处理能力,而且代码很简洁...
    老鼠AI大米_Java全栈阅读 3,124评论 0 4
  • PS:转载请注明出处作者: TigerChain地址: https://www.jianshu.com/p/8de...
    TigerChain阅读 4,675评论 1 53
  • Vue组件 vue组件:封装前端vue特效代码,便于引用 全局组件全局组件通过Vue.component在scri...
    3e0693dcfb2f阅读 317评论 0 0