概述
vue
组件是vue
常用的功能,vue
也因为强大的组件功能得到很多开发者的青睐。一个好的组件,可以提供给开发者很多方便,特别是复用代码,代码一致性等。
本文通过实现一个列表my-list
组件,来讲解组件的用法和特性。
下面先看一下工程目录:
组件引入
组件引入分全局引入和局部引入,顾名思义,全局引入可以在任何一个路由页面使用该组件,而局部引入是在引入页面才能使用。
import myList from '../components/my-list'
//全局引入
Vue.component('my-list',myList)
export default {
name: "componentStudy",
data: function () {
return {}
},
//局部引入,写法很灵活
components:{myList},
methods: {},
mounted: function () {
},
computed: {},
created: function () {
}
}
上面的代码的2中写法分别是全局引入和局部引入,整体来说,像分页组件,下拉框组件,表格组件等大多数页面都用得上的可以全局引入,像tab页面,特殊按钮等用的比较的少的页面可以采用局部引用。
组件传值
我们的列表组件,各个页面的数据不一样,这些数据往往是通过引入改组件的页面决定的,那么意味着,这些数据应该是从父组件传到子组件的,下面我们给我们的列表组件传一个dataList
(数据)和一个clickFunction
(点击每一项的触发函数)。vue
通过prop
子组件传值,这里传值可以是js
所有类型。
//文件componentSutdy.vue
<my-list :data-list="dataList" :click-fun="clickFunction"></my-list>
data: function () {
return {
dataList:[
{title:'标题1',content:'内容一'},
{title:'标题2',content:'内容二'},
{title:'标题3',content:'内容三'},
]
}
},
methods: {
clickFunction(item){
console.log(item)
}
},
//文件my-list.vue
<template>
<div class="my-list">
<ul>
<li class="list-group-item" v-for="(item,index) in dataList" @click="clickFun(1)">
<div class="main-title" v-text="item.title"></div>
<div class="content" v-text="item.content"></div>
</li>
</ul>
</div>
</template>
//子组件接收父组件传过来的值
props:{
dataList:{
type:[Array,Object], // 类型校验,多个可能的类型
require:true, //是否必传
default:function () { //默认值, 对象或数组默认值必须从一个工厂函数获取
return []
},
// //自定义校验
// validator: function (value) {
// // 这个值必须匹配下列字符串中的一个
// return ['success', 'warning', 'danger'].indexOf(value) !== -1
// }
},
clickFun:{
type: Function,
require: false
}
},
子组件调用父组件方法
和其他框架一下,vue在子组件无法直接通过this.的方式调到父组件的方法,这里vue提供的是$emit的方式来调用父组件的方法。我们修改上面的例子,让子组件点击按钮来删除一个列表,这里值得注意的是,vue组件直接传递参数是单向的,意思是,父组件传递过去的变量,只能在父组件被改变子组件是不能改变父组件传过来的这个变量的。不过可以通过赋值、计算属性等方式来重新定义一个变量。
修改部分的代码:
//文件componentSutdy.vue
//添加了@deleteItem的绑定
<my-list :data-list="dataList" :click-fun="clickFunction" @deleteItem="removeItem"></my-list>
//方法里面添加执行函数
removeItem(index){
this.dataList.splice(index,1)
}
//文件my-list.vue
//添加了$emit('deleteItem',index)"执行函数
<li class="list-group-item" v-for="(item,index) in dataList" @click="clickFun(1)">
<div class="main-title" v-text="item.title"></div>
<div class="content" v-text="item.content"></div>
<i class="el-icon-delete" @click="$emit('deleteItem',index)"></i>
</li>
设置点击删除按钮,顺利删除了一行,可以看到,我们在父组件通过
deleteItem
传递了removeItem
函数给子组件,子组件通过$emit('deleteItem',index)
顺利调到了父组件的函数,并且传递了一个参数,父组件通过这个参数删除了用户点击的数据,这个过程完成了字段就调用父组件的方法,也说明了,子组件不要直接改变父组件传递过来的参数,因为这里是单向绑定的。
值得注意的是,字段就调用父组件的函数,有2种方式,稳重第一种是通过prop传递,第二种是通过@绑定来传递的,实际使用过程中,建议使用第二种方式。
父组件调用子组件方法
很多时候,我们需要字段就来执行某种操作,来达到页面效果,比如说,我们需要在用户点击之后,改变列表颜色,来切换主题。
//文件componentSutdy.vue,关键代码
<my-list :data-list="dataList" ref="myList" :click-fun="clickFunction" @deleteItem="removeItem"</my-list>
<el-button @click="changeTheme" style="margin-top: 20px;">切换主题</el-button>
changeTheme(){
this.$refs.myList.changeColor()
},
//文件my-list.vue,关键代码
<li class="list-group-item" :class="{'has-bg':isChange}" v-for="(item,index) in dataList" @click="clickFun(1)">
<div class="main-title" v-text="item.title"></div>
<div class="content" v-text="item.content"></div>
<i class="el-icon-delete" @click="$emit('deleteItem',index)"></i>
</li>
changeColor(){
this.isChange = true
}
总结:关于vue组件就将到这里,相信上面的类容能涵盖到大多数用法,还有部分动态组件和异步组件不作讲解,实际使用中,用到很少,整个代码的源码可以在git:https://github.com/jackzhujie/vue-study.git上下载到。
最后想查看更多文章,可以关注我的个人公众号: