vue组件
什么是组件: 组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可;
组件化和模块化的不同:
- 模块化: 是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一;
- 组件化: 是从UI界面的角度进行划分的;前端的组件化,方便UI组件的重用;
全局组件定义的三种方式
注意:无论是那一种方式创建出来的组件,template属性指向的模板内容只能有一个根元素
1.使用 Vue.extend 配合 Vue.component 方法:
//这是通过Vue.extend创建的全局组件
var com1 = Vue.extend({
template: '<h3>这是通过Vue.extend创建的组件</h3>'
});
//使用组件 Vue.component('组件名称',创建出来的组件模板对象)
//组件名称可以是大写,如myCom1 但是在调用的时候要以my-com1来调,或者直接使用小写来命名组件
Vue.component('myCom1',com1)
//也可以合并成为一句来写
Vue.component('myCom1', Vue.extend({
template: '<h3>这是通过Vue.extend创建的组件</h3>'
}))
在html里面调用模板
<div id="app">
<my-com1></my-com1><!--正确方式-->
<!-- <myCom1></myCom1> 错误方式-->
</div>
2.直接使用 Vue.component 方法:
Vue.component('mycom2',{
template:'<h3>这是Vue.extend创建的模板</h3>'
})
3.将模板字符串,定义到script标签种:
<body>
<div id="app">
<mycom3></mycom3>
</div>
<!-- 在控制的元素app外面使用template元素定义组件的html模板结构 -->
<template id="temp1">
<h3>这是通过template在在外部定义组件结构这种方式有代码提示</h3>
</template>
<script type="text/javascript">
Vue.component('mycom3',{
template:'#temp1'
})
var vm = new Vue({
el:'#app',
data:{
}
});
</script>
</body>
自定义私有组件
<body>
<div id="app">
<com4></com4>
<com5></com5>
<com6></com6>
</div>
<template id="temp1">
<h3>这是通过template在在外部定义组件结构这种方式有代码提示 私有组件</h3>
</template>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
},
//定义示例内部私有组件
components: {
com4: Vue.extend({
template: '<h3>这是一个私有组件Vue.extend</h3>'
}),
com5: {
template: '<h3>这是一个私有组件,简写方式</h3>'
},
com6: {
template: '#temp1'
}
}
});
</script>
</body>
组件中的data数据
<script type="text/javascript">
//1组件可以有自己的data数据
//2组件的data和实例的不一样 实例中的对象可以为一个对象 但是组件中的data必须是一个方法
//3组件中的data除了必须为一个方法之外,这个方法的内部必须返回一个对象
//4 组件中的data数据和实例中的data数据使用一样
Vue.component('com1', Vue.extend({
template: '<h3>这是h3标签----{{msg}}</h3>',
data: function() {
return {
msg: '这是组件中data定义的数据'
}
}
}))
var vm = new Vue({
el: '#app',
data: {
},
methods: {
}
});
</script>
组件中的方法和组件的独立性
<body>
<div id="app">
<com1></com1>
<com1></com1>
<com1></com1>
</div>
<template id="temp">
<div>
<input type="button" value="+1" @click="addNum" />
<h3>{{msg}}</h3>
</div>
</template>
<script type="text/javascript">
//1组件可以有自己的data数据
//2组件的data和实例的不一样 实例中的对象可以为一个对象 但是组件中的data必须是一个方法
//3组件中的data除了必须为一个方法之外,这个方法的内部必须返回一个对象
//4 组件中的data数据和实例中的data数据使用一样
//5.为了保证组件的独立性 所以data中return的对象不能是外面的,必须要写在return后面
//,如果return的是组件外面的对象,不管实例化多少对象,指向的都是同一个地址,也就是多个组件
//共用一个data,一个实例数据发生变化,其余的组件数据也会发生变化
// 6.要使用组件中的方法 事件必须绑定在模板上面
Vue.component('com1', Vue.extend({
template: '#temp',
data: function() {
return {
msg: 0
}
},
methods: {
addNum() {
this.msg++;
}
}
}))
var vm = new Vue({
el: '#app'
});
</script>
</body>
使用flag
标识符结合v-if
和v-else
切换组件
<body>
<div id="app">
<a href="#" @click.prevent="flag=true">登录</a>
<a href="#" @click.prevent="flag=flase">注册</a>
<com1 v-if="flag"></com1>
<com2 v-else="flag"></com2>
</div>
<script type="text/javascript">
Vue.component('com1', Vue.extend({
template: '<h3>登录</h3>',
}))
Vue.component('com2', Vue.extend({
template: '<h3>注册</h3>',
}))
var vm = new Vue({
el: '#app',
data: {
flag: true
}
});
</script>
</body>
使用:is
属性来切换不同的子组件,并添加切换动画
<body>
<div id="app">
<a href="#" @click.prevent="com='com1'">登录</a>
<a href="#" @click.prevent="com='com2'">注册</a>
<!-- vue提供了component 来展示对应的组件 -->
<!-- component是一个占位符 :is属性可以指定要展示组建的名称(名称是一个字符串) -->
<component :is="com"></component>
</div>
<script type="text/javascript">
Vue.component('com1', Vue.extend({
template: '<h3>登录</h3>',
}))
Vue.component('com2', Vue.extend({
template: '<h3>注册</h3>',
}))
var vm = new Vue({
el: '#app',
data: {
flag: true,
com: 'com1'
}
});
</script>
</body>
添加动画
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css">
.v-enter,
.v-leave-to {
opacity: 0;
transform: translateX(150px);
}
.v-enter-active,
.v-leave-active {
transition: all 0.5s ease;
}
</style>
</head>
<body>
<div id="app">
<a href="#" @click.prevent="com='com1'">登录</a>
<a href="#" @click.prevent="com='com2'">注册</a>
<!-- mode切换动画时的模式,是先出后进,还是先进后出 -->
<!-- 给组件设置动画 只需要将组件写到transition标签里面 -->
<transition mode="out-in">
<component :is="com"></component>
</transition>
</div>
<script type="text/javascript">
Vue.component('com1', Vue.extend({
template: '<h3>登录</h3>',
}))
Vue.component('com2', Vue.extend({
template: '<h3>注册</h3>',
}))
var vm = new Vue({
el: '#app',
data: {
flag: true,
com: 'com1'
}
});
</script>
</body>
</html>
父组件向子组件传值
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<!--
父组件向子组件传值
1.定义一个组件
2.在组件身上绑定一个自定义属性指向父组件的data中的数据 如(datas)
<com1 v-bind:datas="msg1"></com1>
3.将自定义的属性在子组件内部props定义一下,以数组字符串的形式定义 如props:['datas']
4.在子组件模板中就可以通过自定义属性访问数据
template:'<h3>子组件{{datas}}</h3>',
5.data身上的数据可读可写,props身上定义的数据只可以读
-->
<div id="app">
<com1 v-bind:datas="msg1"></com1>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
msg1: '父组件的数据'
},
components: {
'com1': Vue.extend({
template: '<span>子组件<br/> {{datas}} </span>',
data: function() {
return {
msg: '子组件数据'
}
},
props: ['datas']
})
}
});
</script>
</body>
</html>
子组件调用父组件的方法
<body>
<!--
子组件调用父组件的方法:
1,创建一个模板组件,给自己的组件写一个指向自己的方法;
2.在控制区域的组件身上自定义一个事件,指向父组件的方法:<com1 @fun="show"></com1>
3.在子组件里面使用this.$emit('自定义事件名'),触发父组件身上的方法;
-->
<div id="app">
<com1 @fun="show"></com1>
</div>
<template id="temp1">
<div>
<button @click="sonbtn">子组件按钮</button>
</div>
</template>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {},
methods: {
show() {
console.log("这是父组件的方法")
}
},
components: {
com1: {
template: '#temp1',
methods: {
sonbtn() {
this.$emit('fun')
}
}
}
}
});
</script>
</body>
子组件向父组件传值
<body>
<!--
子组件调用父组件的方法:
1,创建一个模板组件,给自己的组件写一个指向自己的方法;
2.在控制区域的组件身上自定义一个事件,指向父组件的方法:<com1 @fun="show"></com1>
3.在子组件里面使用this.$emit('自定义事件名'),触发父组件身上的方法;
4.this.$emit('自定义事件名',对应父组件的形参个数),通过形参传值给父组件;
-->
<div id="app">
<com1 @fun="show"></com1>
</div>
<template id="temp1">
<div>
<button @click="sonbtn">子组件按钮</button>
</div>
</template>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {},
methods: {
show(data1, data2) {
console.log("这是父组件的方法")
console.log(data1)
console.log(data2)
}
},
components: {
com1: {
template: '#temp1',
methods: {
sonbtn() {
this.$emit('fun', '第一个形参对应的数据', "第二个形参对应的数据")
}
}
}
}
});
</script>
</body>
vue使用ref获取Dom元素和组件引用
<body>
<!--
ref 获取dom元素;
1.给需要获取的dom元素添加一个属性ref="自定义名称";如<span ref="myspan">这是一个span标签</span>
2.现在就可以在vm实例中使用this.$refs.自定义名称;获取到dom元素;console.log(this.$refs.myspan)
ref获取组件的data和methods
1.给控制区域的组件添加一个属性ref="自定义名称";如<com ref="mycom"></com>
2.现在就可以在vm实例中使用this.$refs.自定义名称;访问到组件
3.通过 this.$refs.自定义名称.data里面的属性; 获取到组件的属性
3.通过 this.$refs.自定义名称.methods里面的方法名; 就可以调用组建的方法
-->
<div id="app">
<button @click="btns">点击输出到控制台</button>
<span ref="myspan">这是一个span标签</span>
<com ref="mycom"></com>
</div>
<template id="temp1">
<div>组件</div>
</template>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
},
methods: {
btns() {
console.log(this.$refs.myspan)
console.log(this.$refs.mycom)
console.log(this.$refs.mycom.id)
this.$refs.mycom.show()
}
},
components: {
'com': {
template: '#temp1',
data: function() {
return {
id: 3
}
},
methods: {
show() {
console.log("这是组件的方法")
}
}
}
}
});
</script>
</body>