第04章 vue组件

Vue的组件component就是一个代码的封装而已,它的目的就是独立的实现某个功能。在之前的前端工程中,都是一个个的html文件组成,而vue工程则是一个个的组件文件组成。这些组件文件各自其职,共同完成整个前端系统。如何将一个大的前端系统按照组件为单位进行拆分,可能更多的是依据UI界面,这里不过多的叙述。

首先,我们创建一个“04_vue_component.html”文件,代码如下

<div id="app">
    <my-component />
</div>

<script>

// 定义全局组件
Vue.component('my-component', {
    template: '<p>hello, my-component</p>'
})

new Vue({ el: '#app' })

</script>

上述代码中,我们定义了一个全局组件“my-component”,然后使用“template”指定这个组件里面的内容是“<p>hello, my-component</p>”。因为前端工程主要就是完成UI界面,因此定义组件的主要内容也是UI界面。接下来,我们就想使用普通的html标签那样,使用“<my-component />”就能使用我们刚刚定义的组件了。我们这个“my-component”组件只是一个简单UI界面的封装,因此“<my-component />”标签的最终效果就是输出<p>标签。

接下来,我们在创建“04_vue_component2.html”来创建一个vue的“局部组件”。

<div id="app">
    <my-component />
</div>

<script>
new Vue({
    el: '#app',
    components: {
        'my-component': {
            template: '<p>hello, my-component<p>'
        }
    }
})
</script>

我们发现,全局组件和局部组件的区别在于定义的位置是不一样的。

其实全局组件和局部组件在使用上也有很大区别。从名称来看,全局组件使用范围更广,它可以被其他组件使用,而局部组件只能在本页面内使用。由于我们的代码案例是单html页面结构,并不是多文件的vue工程架构,因此我们暂时不会将vue组件定义成单独文件。

接下来,我们继续创建“04_vue_component3.html”文件,代码如下

<div id="app">
    <my-component />
</div>

<template id="my-component-html">
    <p>hello, my-component</p>
</template>

<script>
new Vue({
    el: '#app',
    components: {
        'my-component': {
            template: '#my-component-html'
        }
    }
})
</script>

在上述代码中,我们仍然定义了一个局部组件,但是它的template属性并不是html代码片段了,而是一个ID选择器。我们在文件中使用<template>标签定义了这个局部组件的内容。这样的好处在于,我们就可以按照正常的书写html的方式来构建组件的内容,而不是以字符串的形式来构建了。其实vue组件中除了template来定义组件内容之外,还可以使用data和methods等来定义数据和方法,其实就如同使用vue一样来使用vue组件。

接下来,我们创建“04_vue_component4.html”,代码如下所示:

<div id="app">
    <my-component />
</div>

<template id="my-component-html">
	<div>
        <p>{{message}}</p>
        <button @click="updateMessage">updateMessage</button>
    </div>
</template>

<script>
new Vue({
    el: '#app',
    components: {
        'my-component': {
            template: '#my-component-html',
			data: function(){
				return {
					message: 'hello, my-component'	
				}
			},
			methods: {
				updateMessage:function(){
					this.message = 'hello, vue';	
				}
			}
        }
    }
})
</script>

我们重新定义了“my-component”组件。在组件的内部,我们定义了数据message和方法updateMessage,他们使用基本和之前vue的使用是一样的。这里有两点需要注意,第一,在<template>标签中定义的组件内容的时候,必须有一个根标签(本案例的<div>);第二,组件内的data数据定义并不是json对象,而是function方法。

接下来,我们点击按钮

这样一个简单的小功能,我们将其定义在一个组件内,而不是之前的vue实例中。我们前面提到,vue组件就是一个独立的小功能,但是这种独立性只是“功能”层面上,并不是“数据”层面上。也就是说,当我们使用某个vue组件的时候,我们可能需要向其传递数据,甚至还要让它返回处理好的数据。接下来,我们演示如何向组件传递数据,我们创建“04_vue_component_props.html”文件

<div id="app">
    <my-component message="hello, my-component" />
</div>

<template id="my-component-html">
	<p>{{message}}</p>
</template>

<script>
// 定义一个组件类型对象
var myComponent = Vue.extend({
    props: ['message'],
    template: '#my-component-html'
});

// 直接使用组件类型对象
new Vue({
    el: '#app',
    components: {
        'my-component': myComponent
    }
})
</script>

在上述代码中,我们将组件定义在vue实例的外面,但他不是全局组件,仍然是局部组件。因为vue本质就是js对象,它的组件也是js对象。因此,我们只需要按照vue组件的格式定义一个js对象,那么它就是vue组件了。我们只需要在局部组件的位置使用这个js对象即可。当我们使用这个组件的时候,我们是“<my-component message="hello, my-component" />”这样用的。也就是说,我们给组件传递数据的方式,就是通过组件标签属性。当然,这个属性名称message是我们自定义的,属性值“hello, my-component”就是传递给数据的数据。那么,我们如何在组件内部显示传递过来的数据呢?首先要使用props声明传递过来的数据,也就是我们定义的属性名称message,然后就可以在<template>中直接使用了。正常情况下,我们都是在data中定义数据message,而传递过来的数据涉及到交互,所以就在props声明一下就行了。另外需要注意的是,使用data定义的时候,数据是json对象形式,而props声明的时候,数据是数组形式。

在上述代码中,我们传递给组件的数据是硬代码写的,实际上,它应该是一个数据变量。接下来,我们创建“04_vue_component_props2.html”文件,代码如下

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

<template id="my-component-html">
	<p>{{message}}</p>
</template>

<script>
// 定义一个组件类型对象
var myComponent = Vue.extend({
    props: ['message'],
    template: '#my-component-html'
});

// 直接使用组件类型对象
new Vue({
    el: '#app',
	data:{ msg:'hello, my-component' },
    components: {
        'my-component': myComponent
    }
})
</script>

其实,我们的改动就两点。第一,就是在vue实例中增加了data数据定义,增加了一个名称为msg的字符串数据,它的值就是“hello, my-component”。第二,我们如何将这个msg传递给组件的message呢?非常简单,就是使用“v-bind”绑定指令::message="msg"

我们可以将vue实例理解为父组件,子组件的message来源于父组件的msg。那么,这个message和msg的关系是如何呢?这个问题类似于java方法的参数传递问题。这里,我们先给出结论。修改父组件msg会同步子组件message,但修改子组件message不会同步父组件msg。

我们创建“04_vue_component_sync.html”文件,代码如下

<div id="app">
    <div>
    	<p><span>父组件:</span>{{msg}}</p>
        <p><button @click="changMsg()">修改父组件msg</button></p>
    </div>
    <my-component :message="msg" />
</div>

<template id="my-component-html">
    <div>
        <p><span>子组件:</span>{{message}}</p>
        <p><button @click="changMessage()">修改子组件message</button></p>
    </div>
</template>

<script>
// 定义一个组件类型对象
var myComponent = Vue.extend({
    props: ['message'],
    template: '#my-component-html',
    methods: {
        changMessage: function(){
            this.message = 'hello, child'
        }
    }
});

// 直接使用组件类型对象
new Vue({
    el: '#app',
	data:{ msg:'hello, my-component' },
    components: {
        'my-component': myComponent
    },
    methods: {
        changMsg: function(){
            this.msg = 'hello, parent!';
        }
    }
})
</script>

其实,我们就是在父组件和子组件增加了各自修改数据的方法。我们只需要点击各自的修改数据方法来查看是否对对方有影响。

我们首先点击“修改父组件msg”按钮

我们发现,修改父组件的msg数据,子组件的message也跟随改变。接下来,我们刷新浏览器恢复之前的初始页面,然后点击“修改子组件message”按钮

我们发现,子组件改变了,但是父组件没有改变。这样的结论比较尴尬,要么两者相互影响(类似于java方法的引用类型参数传递),要么就不要影响(类似于java方法的基本类型参数传递)。如何解决这个问题,我们下一个章节介绍。

本章节先介绍到这里。

本课程的内容可以通过CSDN免费下载:https://download.csdn.net/download/richieandndsc/89025243
 

  • 20
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值