Vue组件定义
简介
组件是可复用的 Vue 实例。
本质上是一个对象,该对象包含data、computed、watch、methods、filters以及生命周期钩子等成员属性。
组件结构:
{
data(){
return {
//
}
},
computed:{
displayName(){
return '';
}
},
methods:{
onClickHandler(params){
// do something
}
}
}
基础知识
data属性
data属性维护一个组件内部状态,其余组件正常情况下不可见。
- 可以通过
props传递给子组件; - 可以通过
$emit的方式传递给父组件; 可以通过
this.$refs.ref.$data在mounted生命周期内获取子组件的内部状态;- 目前不知道如何监听其变化;
- 因为计算属性
computed和侦听属性watch只能监听 响应式依赖 的变化,而$refs非响应式。
- 可以通过
一个组件的 data 选项必须是一个函数。
data选项有两种定义方式: 一、对象形式:data:{
//引用该组件的地方,共用一个状态的引用,以至于,只要有一处修改了$data中的某一属性值,其它引用该组件的地方也跟随着改变该属性值(其实,不是跟随,本来就是同一个指向)。
}
二、函数形式:data(){
return {
//引用该组件的地方,每一个组件都会获得独立的引用,互不干扰。
}
}
computed属性 VS methods属性 VS filter
| 区别 | method | computed | filter |
|---|---|---|---|
| 类型 | 函数 | 数据变量 | 函数 |
| 用途 | 作事件处理函数 | 作数据 | 作管道符 |
| 作用范围 | 组建内 | 组建内 | 组建内(局部注册)、全局(全局注册) |
| 参数 | 可以带参 | 不带参(非函) | 带参 |
| 返回值 | 不要求 | 必须有 | 必须有 |
| 触发 | 交互时触发 | 在它的相关依赖发生改变时才会重新求值 | 传入的数据变化时执行 |
注意:
Vue中并不是所有的属性都是响应式的,如$refs无法监听它的变动;
组件构建的主要区别在于模板的生成方式。
模板定义方式
template选项
字符串模板
- 以HTML标签结构组成的字符串;
- 示例:
{
template: '<h1 v-if="level === 1">简单示例</h1>',
props: {
level: {
type: Number,
required: true
}
}
}
id选择器指定的模板
- 以
id标识的一段script标签包裹的HTML片段; - 示例:
<script type="text/x-template" id="anchored-heading-template">
<h1 v-if="level === 1">
简单示例
</h1>
</script>
{
template: '#anchored-heading-template',
props: {
level: {
type: Number,
required: true
}
}
}
render
- 发挥JavaScript最大的编程能力,该函数接收一个
createElement方法作为第一个参数用来创建VNode; createElement接收三个参数:组件根节点类型、组件配置对象、子节点(官方关于组件配置对象的说明);- 示例:
{
render: function (createElement) {
return createElement(
'h' + this.level, // tag name 标签名称
this.$slots.default // 子组件中的阵列
)
},
props: {
level: {
type: Number,
required: true
}
}
}
单文件组件
单文件组件将模板、逻辑、样式在结构上分离,保存在同一个文件中。
<template>
<div>
...
</div>
</template>
<script>
...
export default{
...
}
...
</script>
<style>
...
</style>
方案选择
| template | 单文件 | render |
|---|---|---|
| 一行的简单结构 | 常规的选择 | 前边两种方案解决不了时候的选择(灵活性高) |
注意:
- 不论选择哪一种方案,定义模板时,一定要有一个非
template标签元素作根DOM,有且仅有一个。
组件注册方式
局部注册
以上几种方案定义的组件本质上都是一个对象,获取该对象(假设变量名为TabBar),要求只在另一个组件(假设变量名为App)内使用:
App组件的配置对象:
{
components:{
'tab-bar': TabBar,
}
}
这样就是局部注册,该组件TabBar只能在App模板中使用<tab-bar></tab-bar>,其它组件对TabBar不可见。
全局注册
以上几种方案定义的组件本质上都是一个对象,获取该对象(假设变量名为TabBar),要求项目内任何组件可使用:
一般在项目的入口文件(如:脚手架搭建项目的main.js)中:
Vue.component('tab-bar',TabBar);
这样就是全局注册,该组件TabBar能在整个项目内使用<tab-bar></tab-bar>,所有组件对TabBar可见。
生命周期钩子
以下用自己的语言将生命周期钩子表述一下,如果有不对的地方,请校正:

beforeCreate
在这个时候,生命周期函数已经准备好。
- 组件实例已经构建,但本组件实例的数据、方法还没有注入;
- 可以在各个生命周期内通过组件实例
this调用根实例上注入的$router、$store等对象。 - 可以在本生命周期内进行数据初始化;
created
在这个时候,当前组件实例this上的属性($data、props、$methods...)已经注入绑定,可以调用本实例上的成员属性;
beforeMount
在进入本生命周期之前,会进行以下判断:
是否有
el选项(指定挂载目标):- 有
el选项的是根实例; - 没有
el选项的是非根实例(默认挂载元素为组件调用的位置);
- 有
是否有
template选项:- 有
template选项的是内联模板; - 没有
template选项的是单文件组件; - 个人觉得,还有
render选项的判断;
- 有
最终这些模板都会转换为render函数进行渲染!!!
这个生命周期在解析模板,不知道有什么实际用途。
mounted
在本生命周期之前,已经将模板渲染为真实DOM,其中vm.$el为组件实例的根DOM元素;
- 本生命周期是初始化第三方插件的场所;
- 必要时候,可以在本生命周期内对DOM进行操作;
- 本生命周期是获取
this.$refs.ref的场所;
来源:https://segmentfault.com/a/1190000015882730
Vue组件定义的更多相关文章
- vue组件定义方式,vue父子组件间的传值
vue组件定义方式,vue父子组件间的传值 <!DOCTYPE html> <html lang="zh-cn"> <head> <met ...
- vue组件定义全局方法
1.在vue实例的data中定义一个对象 2.可以在其他组件定义方法 3.触发方法
- vue组件定义方式
一.全局组件 <div id="box"> {{msg}} <my-aaa></my-aaa> </div> var Home = ...
- [js高手之路] vue系列教程 - 组件定义与使用上部(7)
组件是vue框架比较核心的内容,那么什么是组件呢? 通俗点讲:组件是由一堆html, css, javascript组成的代码片段, 作用是为了实现模块的重用 组件的基本用法: <div id= ...
- vue 组件的定义
1.什么是组件? 组件的出现,就是为了拆分vue实例的代码量的,能够让我们以不同的组件来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可. 2.组件化和模块化的不同? 模块化: ...
- vue教程3-03 vue组件,定义全局、局部组件,配合模板,动态组件
vue教程3-03 vue组件,定义全局.局部组件,配合模板,动态组件 一.定义一个组件 定义一个组件: 1. 全局组件 var Aaa=Vue.extend({ template:'<h3&g ...
- Vue学习笔记【23】——Vue组件(组件的定义)
定义Vue组件 什么是组件: 组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可: 组件化和模块化的不同: ...
- 怎么定义一个自己的vue组件
1.在src文件夹中创建一个hello文件夹,然后创建hello.js和hello.vue 2.hello.vue代码如下 <template> <button>这是hello ...
- vue组件最佳实践
看了老外的一篇关于组件开发的建议(强烈建议阅读英文原版),感觉不错翻译一下加深理解. 这篇文章制定一个统一的规则来开发你的vue程序,以至于达到一下目的. 1.让开发者和开发团队更容易发现一些事情. ...
随机推荐
- 前端之JavaScript:JS简单介绍
JavaScript(JS)之简单介绍 一.JavaScript的历史 1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中).后将其改名Scr ...
- redis面试题集錦
1为什么Redis需要把所有数据放到内存中? Redis为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘.所以Redis具有快速和数据持久化的特性.如果不将数据放到内存中,磁盘 ...
- A1065
判断两数相加是否大于第三数,大于输出true,否则输出false(相等也是false) 1 需要注意数字溢出的问题: 2 先判断溢出,因为在a,b都是负数最小值的情况下,相加直接是正数,在c较小的时候 ...
- linux运维、架构之路-全网备份项目方案
一.项目需求说明 某公司有多台服务器,里面的数据很重要,如果磁盘坏了,数据就会丢失,所以公司要求把重要服务器数据备份以便出现问题时可以进行恢复,要求:每天晚上00点整在所有服务器上打包备份系统配置文件 ...
- div拖拽到iframe上方 导致 缩放和拖拽的不平滑和鼠标事件未放开 解决方法
思路一:用在开始进行缩放(触发了resizable的start事件)为iframe添加z-index属性,将iframe放置在最下层. $("#draggable").resiza ...
- 一次傻乎乎的错误QAQ
东北联赛上有一道题,数据范围是2^60,当时不记得long long的范围,于是写了一个程序试了一下,把队友带入了一个大数的大坑QAQ(蠢哭). 当时写的代码是这样的: #include<ios ...
- 【bzoj4136】[FJOI2015]带子串包含约束LCS问题
题目描述: 带有子串包含约束的最长公共子序列问题可以具体表述如下. 给定2个长度分别为n和m的序列X和Y,以及一个子串包含约束集S. S中共有k个字符串S={S1,S2,…,Sk},其中字符串Si的长 ...
- 改变input的placeholder字体颜色
改变input的placeholder字体颜色,注意哦,只是placeholder的字,用户输入的字不可以 input::-webkit-input-placeholder{ coloc:#000; ...
- Spring、Hibernate、Struts官方下载地址
hibernate 官网: http://hibernate.org/ hibernate3 官方下载:http://sourceforge.net/projects/hibernate/files/ ...
- 用 MuGo 搭建 Go Engine 在 KGS 对战
MuGo 是一个开源的 Go Engine,下棋能力大概在 10k - 2k 左右. 用 MuGo 搭建 Go Engine 并在 KGS 对战的步骤如下: 1. 安装 TensorFlow 因为 M ...