作者 | Jeskson

来源 | 达达前端小酒馆

Vue组件的概述

组件是什么呢,了解组件对象的分析,Vue组件中的data属性,props传递数据的原理到底是什么。

事件通信的那些事

如何了解父子组件事件通信,和遇到非父子组件事件通信如何处理。

组件类型又是什么鬼

自定义组件双向绑定v-model,动态组件,又是如何称为动态的,为啥是动态呢,递归组件,如何理解递归。

Vue组件的了解

Vue的理解,可以找我上一篇vue.js-详解三大流行框架VUE_快速进阶前端大咖-Vue基础,组件是什么,组件就是自己写好的一部分封装好的功能,自己写的叫组件,别人写的叫插件,组件的运用,是vue.js强大的功能之一,组件的出现是为了提高代码的可重用性,组件是一部分完整好的,如果要使用,你可以放到你自己任何的项目上去,减少代码的重复书写。

直接在你要用的地方引入即可,是不是减少了重复性开发,可以把组件的代码按照template,style,script的拆分形式,放到对应的文件中。

template是什么?它是模板(template),模板是声明了数据和最终展现给用户的dom之间的映射关系,初始化数据data是什么?一个组件的初始数据状态,对于可以重复使用的组件来说,通常是私有的状态,方法methods是对数据进行操作的方法,接收外部参数,组件之间通过参数来进行数据的传递和共享props,参数默认是单向绑定,也可以双向绑定。

回调函数,一个组件可以触发多个回调函数,created(),attached(),destroyed()。

Vue组件,全局注册与局部注册

全局注册文件,Vue.component('组件名', {组件参数})方式创建

<body>
<div id="app">
<my-component></my-component>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
// 创建全局组件
Vue.component('my-component",{
// template: 组件的HTML代码结构
template: '<div>this is dada</div>'
});
// Vue实例对象
var vm = new Vue({
el: '#app'
});
</script>
</body>

局部注册组件,不是每个组件都是需要进行全局注册的,也可以直接在vue实例对象的构造函数中,使用compontent关键字进行注册自定义的组件。

<div id="app">
<local-component></local-component>
</div> <script src="https://unpkg.com/vue"></script>
<script>
// Vue实例UI小
var vm = new Vue({
el: '#app',
// 创建局部组件
components: {
'my-components': {
template: '<div>this is my</div>'
}
}
}
});

首先先创建局部组件对象,然后注册Vue构造器中注册局部组件对象,最后使用局部组件。

<div id="app">
// 在默认情况,使用camel标记法将ui自动转换为短横线形式
<local-component></local-component>
</div> <script src="https://unpkg.com/vue"></script> <script>
// 创建局部组件
const localComponent = {
template: '<div>this is da</div>'
} // vue实例对象
var vm = new Vue({
el: '#app',
// 创建只对当前vue实例对象有效的局部组件
components: {
// 注册组件
localcomponent
}
});
</script>
var vm = new Vue({
el: '#app',
// 创建局部组件
components: {
// 注册组件
'my-component': localComponent
}
});

组件对象的分析

vue组件就是一个vue实例:

// 自定义组件
var dada = Vue.component('my-component', {
template: '<h1>dada</h1>'
});

组件只允许有唯一一个根元素,这样也行:

// 自定义
const dada = Vue.component('my-component', {
template: `
<div>
<span>达达前端</span>
<p> this is da</p>
</div>
`
});

在组件中使用template标签:

<div id='app'>
<h1>my-component</h1>
<my-component></my-component>
</div> <template id="my">
<div>this is dada</div>
<p>this is dadadada</p>
</template> <script..></script> <script>
// 自定义组件
const my = Vue.component('my-component", {
template: '#my'
});
// vue实例对象
var vm = new Vue({
el: '#app'
});
</script> // 会出现程序错误
因为vue组件只允许有一个根元素。 组件template属性中包含div与P两个元素
<template id="my">
// 组件只允许有一个根元素
<div>
<div>da</div>
<p>da</p>
</div>
</template> // 成功

vue组件中的data属性

在组件中,可以使用任何有效的Vue实例对象属性。data属性是Vue组件可用的响应式数据,它是Vue实例的数据对象。在创建实例后,用户可以通过vm.$data访问原始数据对象,Vue实例也代理了data的所有属性。

即vm.a 等价于 vm.$data.a,以"_"或者是"$"开头的属性不会被Vue实例代理,因为它们可能和Vue内置的属性以及api方法产生冲突。

// 创建一个实例
var vm = new Vue({
data: data
})
vm.a // => 1
vm.$data === data // => true // Vue.extend()中的data
var Component = Vue.extend({
data: function() {
return { a: 1 }
}
})

data属性必须声明为返回一个初始数据对象的函数。


<div id="app">
<h1>my-component</h1>
<my-component></my-component>
<h2>my</h2>
<my-component></my-component>
</div> <template id="my">
<div>
<div>this is my</div>
<p>this is da</p>
<p>{{message}}</p>
<button @click="message = 'update message'">
修改
</button>
</div>
</template> <script src="https://unpkg.com/vue"></script> <script>
var data={
message: 'global'
}
// 全局组件
const my = Vue.component('my-component', {
template: '#my',
// data属性表示当前组件使用的数据信息
// data属性必须是回调函数形式,在回调函数中要返回对象
data: function() {
return data;
}
});
// Vue实例对象
var vm = new Vue({
el: '#app'
});
</script>
// 全局组件
const my = Vue.component('my-component',{
template: '#my',
// data属性表示当前组件使用额数据信息
// data属性必须是回调函数形式,在回调函数中要返回对象
// data属性应该返回一个都有的对象
data: function() {
return {
message: 'component-message'
};
}
});

props传递数据

父组件和子组件之间的通信使用props,是组件数据中的一个字段,子组件使用props来获取父组件的数据,props可以是字面量语法,动态语法,绑定修饰符等。

props字面量,子组件通过props声明待接收的父组件数据,父组件中使用子组件,通过HTML属性为子组件传递数据。

子组件:

const my = {
// props:声明接收父组件数据
props: ['message'],
// data一样
template: '<span>{{message}}</span>'
}

父组件:

<my-component message="message from parent by props">
<my-component>
const my = {
props: ['myMessage'];
template: '<span>{{message}}</span>'
}
<my-component my-message="hello"></my-component>
子组件props指明数据
Vue.component("my-component",{
props: ['message'],
template: '<span>{{message}}</span>'
});
<my-component alt="this is add"></my-component>

动态语法:

<div id="app">
<my-component v-bind:message="message">
</my-component>
<my-component :message="message">
</my-component>
</div>

v-bind指令将HTML属性绑定到一个表达式上,使用v-bind指令将动态props绑定到父组件的数据。

var vm = new Vue({
el: '#app',
data: {
user: {
name: 'test',
age: '12'
}
}
}); <div id="app">
<my-component :user="user"></my-component>
<my-component user="user"></my-comoponent>
</div>

绑定修饰符

父组件的属性发生变化时,会传递给子组件

// 默认单向绑定
<child :message="parentMessage"></child>
// 双向绑定
<child :message.sync="parentMessage"></child>
// 单向绑定
<child :message.once="parentMessage"></child>
// 在子组件中修改props都会影响父组件的状态
<div id="example">
<input type="text" v-model="info.name"/>
<child v-bind:msg.once = "info"></child>
</div>
<script src="vue.js"></script> <script>
// 创建根实例
var vm = new Vue({
el: '#example',
data: function() {
return {
info: {
name: 'hello'
}
}
},
components: {
'child': {
//声明props
props: ['msg'],
template: '<div>{{msg.name}}</div>'
}
}
});
</script>
Vue.component('example', {
props: {
propsA: 'null',
// 多种类型
propM: [String, Number],
// 必须是字符串
propB: {
type: String,
required: true
},
propc: {
type:Number,
default: 100
},
propD: {
type: Object,
default: function() {
return {msg: 'hello'}
}
},
// 指定props为双向绑定
propE: {
twoWay: true
},
propF: {
validator: function() {
return value > 10
}
}
});

type类型:string,number,boolean,object,function,array.

type可以是一个自定义的构造器。

为props定义一个coerce()函数

Vue.component('example', {
props: {
// 转换函数
propG: {
coerce: function(val) {
return val+''
}
},
propH: {
coerce: function(val){
return JSON.parse(val)
}
}
}
})

事件通信

父子组件事件通信,会在HTML中使用元素会有的一些属性,父组件通过props向子组件传递数据,子组件通过events向父组件发送消息。

子组件需要某个数据,可以在内部定义一个props,父组件将data属性传递给子组件的data属性。

// 父组件向子组件传递数据
<my-component :item="users"></my-component Vue.component('example',{
template: `<div><button @click="myclick"></button></div>`,
methods: {
myclick: function() {
}
}
});

父组件向子组件传递数据

子组件向父组件发送消息可以使用vue自定义事件机制。

子组件主要通过使用$emit向父组件触发事件。

父组件使用$on或v-on指令监听子组件触发的事件,并接收子组件发送的消息。

<div id="app">
<my-component @childevent="handleEvent"></my-component>
</div>
Vue.component('my-component',{
template: '#my-component',
props: ['value'],
methods: {
emitEvent: function() {
console.log('child component click event');
this.$emit('childevent');
}
}
});
Vue.component('my-component',{
template: '#my-component',
props: ['value'],
methods: {
emitEvent: function() {
console.log('child component click event');
this.$emit('childevent');
}
}
});
emitEvent: function() {
this.$emit('childevent','附加数据')
}
handleEvent:function(){
console.log(arguments[0]);
}

子组件向父组件发送消息。父组件$on或v-on监听子组件触发的事件,接收子组件发送的消息。

<div id="app">
// 使用组件
<my-component :message="message" @my-component-event="handleMyComponentEvent">
</my-component>
<p>message==={{message}}</p>
</div> <template id="my">
<div>
<p>{{message}}</p>
<p>
<button @click="handleClick"></button>
</p>
</div>
</template> <script>
const myComponent={
template: '#my',
props:['message'],
methods:{
handleClick: function(){
this.$emit('my-component-event','updata');
}
}
};
// Vue实例对象
var vm = new Vue({
el: '#app',
data: {
message: 'from parent'
},
// 注册组件
components: {
myComponent
},
// 方法
methods: {
// 接收子组件定义事件处理
handleMyComponentEvent: function(param){
this.message=arguments[0];
}
}
});

非父子组件进行事件通信

父组件通过props向子组件传递数据,子组件通过自定义事件向父组件触发动态修改事件。

非父子组件之间的通讯方式

子组件中,通过使用$parent或者$root访问当前组件的父组件或根组件实例对象。

this.$parent父组件

this.$root根组件


var vm = new Vue({
el: '#app',
data: {
message: 'message'
},
components: {
childComponent
}
}); const childComponent={
template:'',
methods:{
updateRootMessage: function(){
this.$root.message='message from child';
}
}
};

父组件访问子组件,使用ref属性,通过this.$refs进行访问子组件

<div id="app">
<child-component ref="childComponent">
</child-component>
</div>

var vm = new Vue({
el: '#app',
components: {
childComponent
},
methods: {
updateChild: function(){
this.$refs.childComponent.message="from parent";
}
}
});

事件总线机制

监听订阅on,触发emit。用on方法去监听某个事件,用emit方法去触发这个事件,同时调用这个on方法回调函数,这样就完成了一次事件触发。

var dada = new Vue()
// 触发组件a中的事件
dada.$emit('id-selected',1)
// 触发b创建的函数中监听事件
dada.$on('id-selected', function(id){
})

创建事件总线对象

var dada = new Vue()

监听事件总线所触发的事件

dada.$on

触发自定义事件

dada.$emit

<div id="app">
<child1-component></child1-component>
<child2-component :message="message" ref="child2">
</child2-component>
</div> <template id="child1">
<div>
<button @click="updateChild2">da</button>
</div>
</template> <template id="child2">
<div>
message={{message}}
<p>{{name}}</p>
</div>
</template> <script src="https://unpkg.com/vue">更新2的内容</script> <script>
const dada = new Vue();
// 创建组件
const child1Component={
template: '#child1',
methods: {
updaeChild2: function(){
// 使用事件总线触发自定义事件
dada.$emit('child1-event','update name from child1');
}
}
}; const child2Component = {
template: '#child2',
props: ['message'],
data: function() {
return {
name: 'child2'
};
},
created: function() {
// 保留当前vue组件对象
const app = this;
// 监听事件总线触发的事件
bus.$on('child1-event', function(param){
console.log('捕获');
app.name = param;
});
}
};
</script>

❤️ 不要忘记留下你学习的脚印 [点赞 + 收藏 + 评论]

作者Info:

【作者】:Jeskson

【原创公众号】:达达前端小酒馆。

【福利】:公众号回复 “资料” 送自学资料大礼包(进群分享,想要啥就说哈,看我有没有)!

【转载说明】:转载请说明出处,谢谢合作!~

大前端开发,定位前端开发技术栈博客,PHP后台知识点,web全栈技术领域,数据结构与算法、网络原理等通俗易懂的呈现给小伙伴。谢谢支持,承蒙厚爱!!!


若本号内容有做得不到位的地方(比如:涉及版权或其他问题),请及时联系我们进行整改即可,会在第一时间进行处理。


请点赞!因为你们的赞同/鼓励是我写作的最大动力!

欢迎关注达达的CSDN!

这是一个有质量,有态度的博客

来吧!一文彻底搞定Vue组件!的更多相关文章

  1. 一文搞定Vue2组件通信

    vue 组件通信方式 父组件将自己的状态分享给子组件使用: 方法:父组件通过子标签传递数据,子组件通过 props 接收 子组件改变父组件的状态; 方法:父组件在子标签上通过@abc 提供一个改变自身 ...

  2. 小白6步搞定vue脚手架创建项目

    1.安装node及npm node -v (测试node是否安装成功)npm -v(测试npm是否安装成功) 2.安装cnpm npm install -g cnpm --registry=http: ...

  3. 3.十分钟搞定Vue搭建

    Vue推荐开发环境 Node.js 6.2.0.npm 3.8.9.webpack 1.13.vue-cli 2.5.1.webstrom2016 现在开始安装环境 安装nodejs 可以在终端里下载 ...

  4. 一篇搞定vue请求和跨域

    vue本身不支持发送AJAX请求,需要使用vue-resource.axios等插件实现 axios是一个基本Promise的HTTP请求客户端,用来发送请求,也是vue2.0官方推荐的,同时不再对v ...

  5. 轻松搞定Vue 使用SignalR与Asp.net Core通讯

    前言 针对于Web与其他应用的的通讯,在.Net中,SignalR是一个不错的选择,在前后端没有分离的时候,直接引用对应的signalr.js文件即可: 这里主要记录Vue与Asp.netcore 前 ...

  6. 一文彻底搞定Hystrix!

    前言 Netflix Hystrix断路器是什么? Netflix Hystrix是SOA/微服务架构中提供服务隔离.熔断.降级机制的工具/框架.Netflix Hystrix是断路器的一种实现,用于 ...

  7. 深入理解Vue组件3大核心概念

    摘要: 搞懂Vue组件! 作者:浪里行舟 原文:详解vue组件三大核心概念 Fundebug经授权转载,版权归原作者所有. 前言 本文主要介绍属性.事件和插槽这三个vue基础概念.使用方法及其容易被忽 ...

  8. 一文搞定Spring Boot + Vue 项目在Linux Mysql环境的部署(强烈建议收藏)

    本文介绍Spring Boot.Vue .Vue Element编写的项目,在Linux下的部署,系统采用Mysql数据库.按照本文进行项目部署,不迷路. 1. 前言 典型的软件开发,经过" ...

  9. 1小时搞定vuepress快速制作vue文档/博客+免费部署预览

    先来一下演示效果.和vue的官方文档几乎是一致的,页面内容都可自定义. 此教程部署后的效果预览. 在你跟着教程搭建好项目之后,你会收获: 快速搭建一个文档/博客,后期只需要修改markdown内容和导 ...

随机推荐

  1. eclipse激活jrebel

    1.原本jrebel已经激活了,某天突然失效了.报错如下: JRebel: ERROR Failed to obtain seat. Unable to connect to license serv ...

  2. HDU-1760 A New Tetris Game DFS

    曾经,Lele和他姐姐最喜欢,玩得最久的游戏就是俄罗斯方块(Tetris)了. 渐渐得,Lele发觉,玩这个游戏只需要手快而已,几乎不用经过大脑思考. 所以,Lele想出一个新的玩法. Lele和姐姐 ...

  3. redis 阻塞原因

    1.内因: A.api或数据结构使用不合理: 如:对一个包含上万元素的hash结构执行hgetall操作,数据量大且命令复杂度O(n),必然阻塞 B.慢查询:前面有介绍 C.大对象: 执行./redi ...

  4. 修改Hexo自动生成的HTML文件名

    导读 我们在使用Hexo框架生成静态博客时,其实是将你写好的.md文件输出成HTML文件进行渲染,其中HTML的文件名称就是.md的文件名称. 而我们为了编辑文章方便,为了通过文件名就知道这是哪篇文章 ...

  5. NET 已知excel表格前面26个是a到z,27是aa28是ab,以此类推,N是多少

    问题: 已知excel表格前面26个是a到z,27是aa28是ab,以此类推,N是多少 代码: /// <summary> /// 已知excel表格前面26个是a到z,27是aa28是a ...

  6. 如何通过调优攻破 MySQL 数据库性能瓶颈?

    一.前言 MySQL调优对于很多程序员而言,都是一个非常棘手的问题,多数情况都是因为对数据库出现问题的情况和处理思路不清晰.在进行MySQL的优化之前必须要了解的就是MySQL的查询过程,很多的查询优 ...

  7. linux 如何指定nologin用户执行命令

    在linux中建立网站时,我们一般分配一个www之类的用户给网站应用程序. 如果我们使用root或者具有管理员权限的账号在网站目录下去创建文件时,会遇到各种权限问题. 这时我们可以切换到www用户,这 ...

  8. Java中级知识归纳(三)

    十一.Java垃圾回收机制 Java的垃圾回收机制是Java虚拟机提供的能力,用于在空闲时间以不定时的方式动态回收无任何引用的对象占据的内存空间.可以使用显式调用,System.gc();Runtim ...

  9. Python 电子邮件

    从一台计算机编写邮件到对方收到邮件.假设我们自己的电子邮件地址是me@163.com,对方的电子邮件地址是friend@sina.com 我们在本地的软件上写好邮件,点击发送,邮件就发送出去了,这些电 ...

  10. 如何down掉IB交换机口

    服务器上找到需down的网络:ip a 通过ib命令iblinkinfo找到对应交换机以及在ib交换机上对应端口号 登录IB交换机,并通过命令:config进入配置模式 通过命令:port进入端口配置 ...