文章目录
VUE组件
基本概念
组件化开发: 根据封装的思想,把页面上可重用的UI结构封装为组件,从而方便项目的开发和维护
VUE中的组件开发: VUE是一个支持组件化开发的前端框架,组件的后缀名**.vue**(如:App.vue文件本质上是一个vue组件)
组件的三个组成部分
- template:组件的模板结构
- script:组件的js行为
- style:组件的样式
- 组件中的data不能指向对象,必须是一个函数
<template>
<div class="test-box">
<h3>自定义的VUE组件------{{username}}</h3>
<button>修改用户名</button>
</div>
</template>
<script>
//默认导出,固定写法
export default{
//不能指向对象,要指向一个函数
data(){
return {
username:"vue"
}
}
}
</script>
<style>
.test-box{
background-color: rgba(54, 145, 148, 0.418);
height: 100px;
width: 250px;
}
</style>
在组件中定义methods方法
为了实现按钮的功能,我们可以在script中添加定义methods方法(注意:methods与data是平级的)
<script>
//默认导出,固定写法
export default{
//不能指向对象,要指向一个函数
data(){
return {
username:"vue"
}
},
methods:{
changeName(){
this.username='test'
}
}
}
</script>
注意
- 在组件中定义当前组件中侦听器(watch)、过滤器()或者计算属性(computed)跟之前的方式一样
- 组件中的模板结构只能包含唯一的根节点,否则将会如下报错
- 在组件中使用less语法,需要在style 中添加lang=“less”,具体操作如下:
<style lang="less">
.test-box{
background-color: pink;
height: 100px;
width: 250px;
h3{
color: red;
}
}
</style>
组件之间的父子关系
组件在被封装好之后,彼此之间是相互独立的,不存在父子关系 | 使用组件的时候,根据彼此的嵌套关系,形成了父子关系,兄弟关系 |
使用组件的三个步骤
- 使用Import 语法导入需要的组件
import Left from './components/Left.vue'
- 使用components节点注册组件(components和methods、data是同级的)
<script>
export default {
components:{
//当键和值一样的时候可以简写为:Left
'Left':Left
}
}
</script>
- 以标签形式使用刚才注册的组件
<div class="box">
<!-- 直接以标签形式使用刚才注册的组件 -->
<left></left>
</div>
实现的效果如下:
小贴士
- 通过components注册的是私有组件,即在组件A的components节点下,注册了组件F,则组件F只能用在组件A中
- 配置@路径提示的插件
在setting.json中添加
//导入文件时是否携带文件的扩展名 "path-autocomplete.extensionOnImport": true, //配置@的路径提示 "path-autocomplete.pathMappings": { "@":"${folder}/src" },
注册全局组件
在main.js中,通过**Vue.component()**方法,可以注册全局组件
import Count from "@/components/Count.vue"
Vue.component('Mycount',Count)
- 参数1:字符串格式,表示组件的注册名称
- 参数2:需要被全局注册的那个组件
如在left.vue中使用count.vue组件
组件的props
props是组件的自定义属性,在封装通用组件的时候,合理地使用props可以极大的提高组件的复用性
-
props是自定义属性,允许使用者通过自定义属性,为当前组件指定初始值
-
props:['init']
是自定义属性的名字,是组件的封装者自定义的,只要合法即可 -
vue规定,组件中封装的自定义属性是只读的,不能修改props值,否则会直接报错,想要修改props的值,可以把props的值转存到data中,因为data中的数据都是可读可写的
<script>
export default {
//props是自定义属性,允许使用者通过自定义属性,为当前组件指定初始值
props:['init'],
data(){
return{
count:this.init
}
}
}
</script>
- props的default默认值:在声明自定义属性时,可以通过default来定义默认值
export default {
//props是自定义属性,允许使用者通过自定义属性,为当前组件指定初始值
props:{
//自定义属性A:{配置选项}
init:{
//如果外界使用该组件的时候没有传递init值,则使用default默认值
default:0
}
}
}
- props的type类型:可以通过type类型来指定数据的类型
export default {
//props是自定义属性,允许使用者通过自定义属性,为当前组件指定初始值
props:{
//自定义属性A:{配置选项}
init:{
//如果外界使用该组件的时候没有传递init值,则使用default默认值
default:0,
type:Number
}
}
}
- props的required来设置必填项:校验是否有传该参数,与是否有默认值无关
组件之间的样式冲突问题
默认情况下,写在**.vue组件中的样式会全局生效,因此很容易造成多个组件之间的样式冲突问题,其根本原因在于:
- 单页面应用程序中,所有组件的DOM结构,都是基于唯一的index.html页面进行呈现的
- 每个组件中的样式,都会影响整个index.html页面中的DOM元素
解决方法:
- 为每个组件分配唯一的自定义属性(data-v-x形式),在编写组件样式的时候,通过属性选择器来控制样式的作用域
- 在style标签处添加scoped:scoped会自动在元素上添加唯一属性(data-v-x形式)
缺点:
- 若子组件带有scoped而父组件没有,则父组件无法操作子组件
- 若父组件带有scoped而子组件没有,则父组件仍然无法操作子组件,这是由于父组件有唯一的标志而子组件不会带有这个唯一标志
/deep/样式穿透
如果给当前组件的style节点添加了scoped属性,则当前组件的样式对子组件不生效。若想要生效,可以使用**/deep/深度选择器**。常用于:当使用第三方组件库的时候,如果有修改第三方组件默认样式的需求,需要用到/deep/