Vue组件应用
Vue的组件是可复用的 Vue 实例,且带有一个名字 。我们可以在一个通过 new Vue
创建的 Vue 根实例中,把这个组件作为自定义元素来使用。因为组件是可复用的 Vue 实例,所以它们与 new Vue
接收相同的选项,例如 data
、computed
、watch
、methods
以及生命周期钩子等。仅有的例外是像 el
这样根实例特有的选项。
一 创建组件
Vue提供了三种不同的方式来定义组件,分别是:全局组件,私有组件,单文件组件。接下来就让我一一道来。
1,全局组件
注册全局组件非常简单,也是很常用的一种方式。
- Vue.component('myCom',{
- template:'<div><p>我是一个全局<span>组件</span></p></div>'
- });
Vue.component()方法需要两个参数:
第一个,组件名称;
第二个,实例(初始化)对象,可以包含所有使用new方式创建Vue实例时提供的所有属性,除了el。
注意:组件的实例对象必须提供一个template属性,用作该组件的HTML代码模板,且在该模板中有且只能有一个根元素。全局组件的注册必须在创建Vue实例之前。
小技巧:由于在编写JS时,一般没有HTML代码提示,创建组件模板代码会很不方便,所有可以在HTML文件中使用<template>元素创建模板,然后在组件的template属性中使用id选择器引用该模板。
注意:<template>元素必须在new Vue实例接管的根元素外部。
- <template id="tem">
- <div>
- <p>我是组件内的p</p>
- <span>我是组件中的span</span>
- </div>
- </template>
- <!-- 在HTML中 -->
- Vue.component('myCom',{
- template:'#tem'
- });
//在组件中
2,私有组件
全局创建的组件在所有Vue实例中均可以使用,有时候这并不符合我们的需求。你可以通过以下方式定义Vue实例的私有组件,这些组件只能在该Vue实例根元素内部使用。
- var vm = new Vue({
- el:'#app',
- components:{
- mycom:{
- template:'#tem'
- }
- }
- });
通过Vue实例的components属性可以定义私有组件,该属性绑定一个对象,对象的属性名是组件名,属性值是组件实例对象。
3,单文件组件
Vue的单文件组件是一个以.vue为后缀名的文件。由于HTML和JavaScrip不能识别.vue文件,所以不能直接使用这种方式的组件,必须配合webpack或vue-cli工具才能正确解析.vue文件。这里的重点是Vue单文件组件,所以有兴趣的同学请移步webpack中文网。
- <tempalte>
- //HTML模板
- </template>
- <script>
- //JS代码
- </script>
- <style>
- //CSS代码
- </style>
.vue文件的名称就是组件的名称,其结构非常简单、清晰:
<template>标签是组件的HTML模板;
<script>标签是逻辑代码;
<style>标签中是样式代码。
二 组件的使用
不管以哪种方式创建Vue组件,我们最终的目的是在HTML页面中展示出来。本节将详细介绍Vue组件使用方式。
1,组件标签
要把我们创建的Vue组件添加到页面中去,只需要把组件名当做标签来使用即可。
- Vue.component('myCom',{
- template:"#tem"
- });
- var vm = new Vue({
- el:"#app"
- });
- //JS部分
- <div id="app">
- <my-com></my-com>
- </div>
- <!-- HTML部分 -->
小技巧:注册组件时,建议使用全小写形式命名,因为HTML标签要求使用小写字母。如果你一定要遵守小驼峰命名规则,那么你应该在使用组件时用“-”短横线把单词分隔开。
2,组件复用
Vue的组件可以重复使用。
- <div id="app">
- <my-com></my-com>
- <my-com></my-com>
- <my-com></my-com>
- </div>
当然,全局组件可以在任何地方使用,而私有组件只能在实例接管元素内部使用。
组件不仅可以简单的重复使用,还可以嵌套。
- var vm = new Vue({
- el:'#app',
- compontents:{
- mycom1:{
- template:'<div>组件一 <mycom2></mycom2></div>'
- },
- mycom2:{
- template:'<div>组件二</div>'
- }
- }
- });
3,另一种使用方式
- var mycom = {
- tempalte:'<div id="app2">hello</div>'
- };
- var vm = new Vue({
- el:'#app',
- render:function(createEl){
- return createEl(mycom);
- }
- });
使用render方式渲染组件:给Vue实例添加render属性,该属性值是一个接收一个方法作为参数的函数。参数用于创建Vue组件,return该组件将替代Vue实例接管的#app元素。最终的表现是:页面上将不再出现#app的div,取而代之的是#app2的div。
这种方式一般配合单文件组件使用,如果要渲染多个组件,只需要创建多个Vue实例即可。
三 数据传递(通信)
1,props传递数据(父组件 --> 子组件)
通过在子组件绑定props属性,实现父组件向子组件传递数据。props属性值是一个数组,数组元素被定义用来接收父组件传递来的数据,然后通过v-bind指令指定数组元素接收哪些数据。子组件通过访问props数组元素就可以访问到父组件传递过来的数据了,就如同访问data里面的值。
- <div id="app">
- <mycom :fromFatherMsg="toSonMsg"></mycom>
- </div>
- <!-- HTML部分 -->
- Vue.component({
- template:"<div>{{fromFatherMsg}}</div>",
- props:["fromFatherMsg"]
- });
- var vm = new Vue({
- el:'#app',
- data:{
- toSonMsg:'这是给子组件的数据'
- }
- });
- //JS部分
通过上面的例子,我们可以将这个过程简单的分为三步:
第一步,在子组件上添加一个数组属性props,在数组中定义用来接收数据的变量(以字符串形式存储);
第二步,使用子组件时通过v-bind指令,绑定预先定义的接收变量和父组件将要传递过来的值;
第三步,在子组件中,如同访问data中的数据一样,访问props数组元素接收到的数据。
2,$emit传递方法(父组件 --> 子组件)
父组件向子组件传递方法,是通过自定义事件来实现的。
监听(同时注册)自定义事件有两种方式:组件上使用v-on指令、实例的$on()方法。这里我们将使用第一种方式来做演示。
子组件通过实例的$emit()方法触发自定义事件,这里的事件名将成为$emit()方法的第一个参数。
- <div id="app">
- <mycom @fromFatherFun="toSonFun"></mycom>
- </div>
- <!-- HTML部分 -->
- Vue.component({
- template:"<div><button @click="myFun">点击执行来自父组件的方法</button></div>",
- methods:{
- myFun:function(){
- this.$emit('fromFatherFun');
- }
- }
- });
- var vm = new Vue({
- el:'#app',
- methods:{
- toSonFun(){
- console.log( "这是给子组件的方法");
- }
- });
- //JS部分
注意:和传递数据一样,子组件不能直接使用父组件的方法。子组件需要通过实例的$emit()方法间接执行来自父组件的方法。
这一过程也可以分为三步:
第一步,使用子组件时,通过v-on指令自定义一个事件;
第二步,绑定自定义事件和父组件需要传递的方法(指定回调函数);
第三步,通过子组件的$emit()方法(通过实参指定需要触发的自定义事件)触发父组件的方法执行;
3,子组件抛出值(子组件 --> 父组件)
子组件在通过$emit()触发自定义事件时,可以同时利用方法的第二个参数,向外抛出一个值。回调函数(上面父组件传递下来的方法)需要定义一个形参来接收这个子组件抛出的值。
- //接上面的例子
- Vue.component({
- template:"<div><button @click="myFun">点击执行来自父组件的方法</button></div>",
- data(){
- return {name:'ren'};
- },
- methods:{
- myFun:function(){
- this.$emit('fromFatherFun',this.name);
- }
- }
- });
- var vm = new Vue({
- el:'#app',
- data:{
- nameFromSon:null
- }
- methods:{
- toSonFun(data){
- this.nameFromSon = data;
- },
- });
子组件抛出一个值的原理和父组件给子组件传递方法原理是一样的,只不过是不同的用法而已。虽然有点绕,但有用哦。
4,获取子组件的引用
在使用子组件时,通过绑定ref属性,父组件可以通过Vue实例的$refs属性拿到子组件的引用,然后就可以直接访问子组件的属性或方法了。
- <div id="app">
- <mycom ref="sonCom"></mycom>
- <button @click="printMsgFromSon">点击打印子组件的信息</button>
- </div>
- <!-- HTML部分 -->
- Vue.component('mycom',{
- data:function(){return {name:'ren'}}
- });
- var vm = new Vue({
- el:'#app',
- methods:{
- printMsgFromSon:function(){
- console.log(this.$refs.sonCom.name);
- }
- }
- });
- //JS部分
小技巧:ref属性不仅可以用在组件上,也可以用在其他标准HTML标签上,这样Vue实例就可以获取到原生的DOM对象了。
注意:即使子组件是Vue实例的私有组件,实例也不能直接使用组件的相关数据,还是需要通过$refs等属性来间接访问。
5,兄弟组件间传值
兄弟组件间实现通信也是采用自定义事件的形式。不过,这一般需要一个空的Vue实例作为中介,配合使用$on()和$emit()实现兄弟组件间的传值。
- <div id="app">
- <com1></com1>
- <com2></com2>
- </div>
- <template id="com1">
- <div>
- <p>com1组件:{{name}}</p>
- <button @click="send">将数据发送给com2</button>
- </div>
- </template>
- <template id="com2">
- <div>
- <p>com2组件:{{name}}</p>
- </div>
- </template>
- <!-- HTML部分 -->
- var event = new Vue();
- var vm = new Vue({
- el:'#app',
- components:{
- com1:{
- template:'#com1',
- data(){
- return{name:'ren'};
- },
- methods:{
- send(){
- event.$emit('sendMsg',this.name);
- }
- }
- },
- com2:{
- template:'#com2',
- data(){
- return {name:null};
- },
- created(){//因为不知道什么时候会被触发,所以一般选择在生命周期钩子中监听
- event.$on('sendMsg',name => {this.name = name;})
- //这里需要使用箭头函数,使其内部的this指向com2
- }
- }
- }
- });
//JS部分
四 其他事项
1,单独的data
经过上面的学习,你可能已经发现了一个问题:组件中的data属性是一个函数返回的对象。
- Vue.component("mycom",{
- template:"",
- data(){
- return { //some code };
- }
- });
- //这是ES6的写法,等同于data:function(){return {some code};}
由于data属性绑定的是一个对象,而对象是一个引用类型,为了保证为每个组件维护一份独立的数据,组件的data属性必须是一个函数。
2,插槽<slot>
当你读到这里时,你可能会有一个疑问:既然我们可以用标签形式使用Vue组件,那么是否可以在开始标签和结束标签之间填些内容呢?如果可以的话,该如何做呢?Vue的答案是肯定的。
首先请看下面的例子:
- <div id="app">
- <com>我是插槽内容</com>
- </div>
- <!-- HTML部分 -->
- Vue.compenent('com',{
- template:'<div><p>我是组件</p><slot>我是默认值<slot></div>'
- });
- var vm = new Vue({
- el:'#app'
- });
- //JS部分
"我是插槽内容"将替换com组件中<slot>元素。
注意:如果在使用子组件时没有提供插槽值,那么<slot>元素中的默认值将会生效,前提是你已经定义了这些值。
上面的例子中,组件最终渲染的HTML结构如下:
- <div>
- <p>我是组件</p>
- 我是插槽内容
- </div>
注意:插槽的内容不仅可以是文本内容,还可以是HTML代码,甚至另一个组件。
如果你需要在一个组件中定义多个插槽,那么你应该需要用到<slot>元素的name属性,来指定每个插槽应该拥有怎么样的模板。
- <div>
- <com>
- <template v-slot:"header">
- <!-- 单独的HTML模板 -->
- </template>
- <div><p>我是默认的模板</p></div>
- <template v-slot:"footer">
- <!-- 单独的HTML模板 -->
- </template>
- </com>
- </div>
- <!-- HTML部分 -->
- Vue.component('com',{
- tempalte:'<div><slot name="header"></slot><slot></slot><slot name="footer"></slot></div>'
- });
- var vm = new Vue({
- el:'#app'
- });
具名的插槽需要在使用组件时,用<template>元素单独定义模板,并通过v-slot指令以参数的形式指定:“我是xxx插槽的模板”。
其他所有没有包裹在<template>元素内的模板,将自动归为匿名的<slot>元素下面。
3,特殊的嵌套元素
有些 HTML 元素,诸如 <ul>
、<ol>
、<table>
和 <select>
,对于哪些元素可以出现在其内部是有严格限制的。而有些元素,诸如 <li>
、<tr>
和 <option>
,只能出现在其它某些特定的元素内部。要怎样才能在这些元素中正确的渲染组件呢?幸好,Vue提供了is特性:
- <table>
- <tr is="mycom"></tr>
- </table>
注意:如果你使用字符串定义组件模板(例如:template: '...'
)、或者单文件组件(.vue)、或者<script>标签(<script type="text/x-template">),那么你完全可以忽略掉这个限制。
Vue组件应用的更多相关文章
- vue组件
分享出来让思路更成熟. 首先组件是 Vue.js 最强大的功能之一. 可以减少很多的工作量,提高工作效率. 编写一个可复用性的组件,虽然官网上也有.... 编写可复用性的vue组件 具备一下的几个要求 ...
- vue组件的配置属性
vue组件的声明语法: Vue.component('component-name',{ template:'<p>段落{{prop1}} {{prop2}}</p>', da ...
- vue组件,撸第一个
实现此例您可以学到: vue-cli的基本应用 父组件如何向子组件传递值 单文件组件如何引入scss v-on和v-for的基础应用 源码下载 一.搭建vue开发环境 更换镜像到cnpmnpm ins ...
- vue组件最佳实践
看了老外的一篇关于组件开发的建议(强烈建议阅读英文原版),感觉不错翻译一下加深理解. 这篇文章制定一个统一的规则来开发你的vue程序,以至于达到一下目的. 1.让开发者和开发团队更容易发现一些事情. ...
- JS组件系列——又一款MVVM组件:Vue(二:构建自己的Vue组件)
前言:转眼距离上篇 JS组件系列——又一款MVVM组件:Vue(一:30分钟搞定前端增删改查) 已有好几个月了,今天打算将它捡起来,发现好久不用,Vue相关技术点都生疏不少.经过这几个月的时间,Vue ...
- vue组件大集合 component
vue组件分为全局组件.局部组件和父子组件,其中局部组件只能在el定义的范围内使用, 全局组件可以在随意地方使用,父子组件之间的传值问题等. Vue.extend 创建一个组件构造器 template ...
- 【Vue】详解Vue组件系统
Vue渲染的两大基础方式 new 一个Vue的实例 这个我们一般会使用在挂载根节点这一初始化操作上: new Vue({ el: '#app' }) 注册组件并使用—— 全局注册 通过Vue.comp ...
- 关于vue组件的一个小结
用vue进行开发到目前为止也有将近一年的时间了,在项目技术选型的时候隔壁组选 react的时候我们坚持使用vue作为前端的开发框架.虽然两者思想上的差异不大,但是vue的语法在代码的可读性以及后期的维 ...
- Vue组件基础用法
前面的话 组件(Component)是Vue.js最强大的功能之一.组件可以扩展HTML元素,封装可重用的代码.根据项目需求,抽象出一些组件,每个组件里包含了展现.功能和样式.每个页面,根据自己所需, ...
- Vue组件模板形式实现对象数组数据循环为树形结构
数据结构为数组中包含对象--树形结构,用Vue组件的写法实现以下的效果: 树形列表,缩进显示层级,第5级数据加底色,数据样式显色,点击展开折叠数据.本文为用Vue实现方式,另有一篇为用knockout ...
随机推荐
- Birt报表
研究了两天终于发现开始学会了BIRT报表的开发流程. 第一步:到http://www.eclipse.org/downloads/下载 Eclipse IDE for Java and Report ...
- 吉利WA数
- python购物车练习题
# 购物车练习# 1.启动程序后,让用户输入工资,打印商品列表# 2.允许用户根据商品编号购买商品# 3.用户选择商品后,检测余额是否够,够就直接扣款,不够就提醒# 4.可随时退出,退出时,打印已购买 ...
- 大数据之路week01--自学之面向对象java(static,this指针(初稿))
函数的重载 返回值不一样会报错 java中,如果自己定义了构造函数的话,它就不会给你默认一个无参函数 如果一个属性,只进行定义,不初始化,自动补0,如果是一个布尔属性,默认是false但是如果一个局部 ...
- 最适合Java开发者的一本书和一软件
一书-<Java编程思想> 一软件-IntelliJ IDEA Java自学是否可以成功,答案显而易见,可以. 自学Java关键看自己是否有毅力.是否有恒心. 自学Java 自学Java不 ...
- Centos 6/7 常用命令总结 (基础)
Centos 6/7 常用命令总结 (基础): 参考链接:https://www.cnblogs.com/linhaifeng/p/6045600.html 目录介绍: a) bin目录:用来存放常用 ...
- 利用GitHub Pages + jekyll快速搭建个人博客
前言 想搭建自己博客很久了(虽然搭了也不见得能产出多频繁). 最初萌生想写自己博客的想法,想象中,是自己一行一行码出来的成品,对众多快速构建+模板式搭建不屑一顾,也是那段时间给闲的,从前后端选型.数据 ...
- Java基础:8种基本数据类型,取值范围和储存字节说明。
Java中,一共有8种基本数据类型: 4种整数型:int,short,long,byte. 2种浮点型:float,double. 1种字符类型:char. 1种表示真值的类型:boolean. [S ...
- 微信web协议,群成员唯一uin,获取群成员唯一标识
群成员唯一标识获取接口 全网最新,支持调试测试.觉得OK再付款! 800元出售源码 不讲价 联系QQ:2052404477
- Secure CRT注册码
secure CRT 把记忆的东西放在这就行了,:) SecureCRT 5.2.2的注册码 Name: Apollo InteractiveCompany: Apollo ...