vue组件入门
vue组件
什么是组件化开发
组件化开发指的是:根据封装的思想,把页面上可重用的UI 结构封装为组件,从而方便项目的开发和维护。
vue 中的组件化开发
vue 是一个支持组件化开发的前端框架。
vue 中规定:组件的后缀名是.vue。之前接触到的App.vue 文件本质上就是一个 vue 的组件。
vue 组件的三个组成部分
每个.vue 组件都由3 部分构成,分别是:
template
-> 组件的模板结构script
-> 组件的JavaScript 行为style
-> 组件的样式
其中每个组件中必须包含 template
模板结构,而 script
行为和 style
样式是可选的组成部分。
三个完整部分组成的组件如下
注意:
.vue
组件中的data
不能指向对象,组件中的data
必须是一个函数,在函数中return
一个对象用来定义数据在组件中
this
指向的是当前组件
1 | <template> |
注意: 组件必须要有唯一的根源素(即我们组件对外只能有一个div,其他的标签都应该被它包裹)
在组件中使用less
我们只需要在style
标签上添加 lang
属性,值为 less
1 | <style lang="less"> |
组件的关系
当我们封装好几个组件后(一般App.vue
放在src根目录中,其他组件放在components
文件夹下),组件之间并没有关系,我们只是默认把 App.vue
渲染到了index.html
中,其他组件都没有使用,想要将组件都利用起来,我们必须合理使用组件,让他们之间形成嵌套关系,比如:父子关系或兄弟关系
组件使用的三个步骤
在
App.vue
根组件中使用import语法导入其他组件1
2
3
4// 1. 导入需要使用的 .vue 组件
import Left from '@/components/Left.vue'
import Test from "@/components/Test.vue"
import Right from '@/components/Right.vue'在
components
节点中注册组件1
2
3
4
5
6
7
8
9
10
11
12
13
14export default {
data() {
return {
flag: true
}
},
// 2. 注册组件
// 当建和值相同的时候,可以简写
components: {
Left,
Right,
Test
}
}以标签形式使用组件
1
2<Left></Left>
<Right></Right>
components节点
使用components
节点注册的是私有组件,比如在 组件A
中注册了 组件F
,那么组件F
只能在组件A
中使用,而在组件B
中不能使用
注册全局组件
当某个节点需要频繁经常被使用的时候,如果我们每次都使用 components
来注册私有组件比较麻烦
我们通过 vue
项目的 main.js
入口文件中,使用 Vue.component()
方法,注册全局组件,注意不要在组件自己里面使用自己
1 | // 导入需要被全局注册的那个组件 |
组件的props
props
是组件的自定义属性,在封装通用组件的时候,合理地使用 props
可以极大的提高组件的复用性
在我们封装的组件中,添加 props
节点,该节点是一个数组/对象,可以自定义组件的属性
props 中的数据,可以直接在模板结构中被使用
注意:props 是只读的,不要直接修改 props
的值,否则终端会报错
使用的时候,我们需要在组件的标签中给自定义属性动态传入值<MyCount init="9"></MyCount>
,直接在标签里这样写传给组件的是一个字符串9,所以我们利用 v-bind
绑定属性时写入的是js表达式这一特性,让 9 变为数字9.所以我们这样写 <MyCount :init="9"></MyCount>
当我们需要给自定义属性一个初始值时,props
就需要定义为对象,并在其中定义自定义属性
,对于自定义属性
我们可以定义它的配置选项, 比如 default
,type
, required
等
数组形式的props | 对象形式的props | ||||
---|---|---|---|---|---|
|
|
1 | <MyCount :init="9"></MyCount> |
组件的样式冲突
使用 scoped 属性
默认情况下,写在 .vue
组件中的样式会全局生效,因此很容易造成多个组件之间的样式冲突问题。
导致组件之间样式冲突的根本原因是:
单页面应用程序中,所有组件的 DOM 结构,都是基于唯一的 index.html 页面进行呈现的
每个组件中的样式,都会影响整个 index.html 页面中的 DOM 元素
解决思路,使用属性选择器给当前组件里的标签都添加同一个自定义属性,每个不同的组件都使用不同的自定义属性,这样就会把样式限制在当前组件中了
事实上,如果让我们每次写标签的时候手动添加一个自定义属性会非常麻烦,只要我们在.vue
组件中的style
标签上添加一个 scoped
属性,在编译生成时,vue就会自动实现上面的功能,为我们的标签添加一个 data-v-xxxx
这样的自定义属性来避免组件之间的样式冲突
1 | <style lang="less" scoped> |
使用 /deep/ 样式穿透
当我们在父组件中想要修改子组件的样式时,如果我们的父组件添加了 scoped
属性,那么修改的样式并不能在子组件中生效,但如果我们不加 scoped
属性 那么样式又会在全局生效,影响布局,因此我们需要使用 /deep/
来达到 在父组件中修改子组件样式的目的
1 | <style lang="less" scoped> |
/deep/
的原理是:在选择器前面添加一个属性选择器,代表该属性选择器包裹下的对应选择器使用该样式。当然添加的这个属性选择器,就是我们每个组件的自定义属性 data-v-xxx