Vue 组件化
Vue - cli 脚手架工具
1.什么是单页面应用程序:
单页面应用程序(Single Page Application),简称 SPA
指的是
一个Web网站中只有唯一的一个HTML页面
,所有的功能与交互都在这唯一的一个页面内完成
2.什么是 vue-cli :
vue-cli
的作用是可以帮助我们一键生成工程化的 Vue 项目。中文官网: https://cli.vuejs.org/zh/
3.安装和使用:
① 全局安装 vue-cli
npm install -g @vue/cli
使用 vue-V 命令检查是否安装成功
② 基于 vue-cli 快速生成工程化的 Vue 项目
vue create 项目的名称 (如:vue create demo-1)
4.vue项目介绍:
①:index.html 单页面应用的唯一的一个html页面
- 预留了一个 el 区域
- 引入了一个打包后的脚本文件
②:main.js webpack 打包的入口文件
- 把 App.vue 渲染到了 index.html 所预留的 el 区域
③ :App.vue
- 它包含了所有将来要在页面中渲染的 UI 结构
Vue 组件
一、什么是组件化开发 ?
组件化开发
指的是:根据封装
的思想,把页面上可重用的 UI 结构封装为组件
,提高页面 UI 结构的复用性,从而方便项目的开发维护
二、Vue中的组件化开发?
Vue是一个
支持组件化开发
的前端框架Vue中规定:
组件的后缀名是.vue
三、Vue组件的三个组成部分?
每个 Vue 组件都由 3 部分组成:
template
=> 组件的模板结构
script
=> 组件的JavaScript行为
style
=> 组件的样式
注意:
每个组件中必须包含 template 模板结构
,template
是必须存在的,而script 行为
和style 样式
是可选
的组成部分
Vue组件 - template 标签的基本使用
Vue规定:每个组件对应的
模板结构
,需要定义到<template>
节点中
<template>
<!-- 当前组件的 DOM 结构,需要定义在 template 标签内部 -->\
<div>
<h1>这是 App.vue 组件</h1>
</div>
</template>
注意:
- template是一个虚拟元素,不会被渲染为任何实际的 DOM 元素,只起到
包裹的作用
- template中
只能包含唯一的根元素
Vue组件 - style 标签的基本使用
style:
Vue规定:开发者可以在 style 节点中
编写样式美化当前组件的UI结构
,组件内的 style 节点是可选
的。
style 节点的基本结构如下:
<style>
h1{
color:red;
}
</style>
让 style 中支持 less 语法
在 style 标签上添加
lang='less'
属性,即可使用 less 语法编写组件的方式:前提:需要安装less:
npm install less less-loader@7.3.0 -D
① -D 是
--save-dev
的简写② -S 是
--save
的简写安装 less 完成后,重新启动项目
npm run serve
less语法的
<style lang="less">
h1{
color:red;
span:{
color:blue;
}
}
</style>
Vue组件 - script 标签的基本使用
script:
Vue 规定:开发者可以在 script 节点中
封装组件的 JavaScript 业务逻辑
script 节点的基本结构如下:
<script>
// 今后,组件相关的 data数据、methods方法等
// 都需要定义到 export default 所导出的对象中
export default{}
</script>
Vue组件中的 data 必须是函数
Vue 规定:vue 组件中的 data
必须是一个函数
,不能
直接指向一个数据对象
<script>
export default{
// 组件中,data 必须是一个函数,不能直接指向一个数据对象
data(){
return{
username:'zhangsan'
}
}
}
</script>
Vue 组件 - 使用组件
如何使用组件
Vue 程序默认会渲染 App.vue 组件的内容,它是整个项目最顶层的组件】
要想在页面中
渲染其他组件的内容
,需要将其嵌套
在 App.vue中
使用组件的 三个步骤
:
- 步骤1:导入,使用 import 语法
导入需要的组件
<!-- import 接受名称 from '路径' -->
<!-- @:可以找到src目录 @ === src -->
import Left from '@/components/Left.vue'
- 步骤2:使用
components
节点注册组件
<script>
export default{
components:{
// 组件的注册名称 : 导入的组件名称
Left:Left // 可简写为 Left
}
}
</script>
- 步骤3:
以标签形式
使用刚才注册的组件
<div class="box">
<!-- 标签形式,使用组件 -->
<Left></Left>
</div>
Vue 组件 - 组件的全局注册
组件的私有注册:
通过 components 注册的是
私有组件
,它只能在注册它的组件中使用,不能在其他组件使用
组件的全局注册:
在项目的入口文件
main.js
中,注册全局组件
<script>
// 1,在main.js的头部,使用 import 导入需要全局注册的组件
import Count from '@/components/Count.vue'
// 2.全局注册
// 在main.js中,new Vue()构造函数之前,进行全局组件注册
// 使用 Vue.component('组件注册名称','导入的全局组件的名称')
Vue.component('Count',Count)
</script>
prop - prop 的基本使用
prop是什么?
prop 是组件的
自定义属性
。在封装通用组件
的时候,合理地使用 prop 可以极大的提高组件的复用性
!可以理解为 prop 是在使用组件的时候,
从外面传递给组件的一个参数
<!-- 需求:在Count组件中,实现 +1 功能 -->
<p>count的值是:{{count}}</p>
<button @click="count += 1">+1</button>
<script>
data(){
return{
count:0
}
}
</script>
prop的使用(需求:使用prop来提高组件的复用性)
Count.vue:
<!-- 定义 props 选项,用来接收外界传进来的参数 -->
<!-- 使用对象的格式为prop设置配置选项 -->
props:['n']
Left.vue:
<!-- 通过自定义属性给组件传参 -->
<Count :n="1"></Count>
Right.vue:
<!-- 通过自定义属性给组件传参 -->
<Count :n="2"></Count>
prop - prop 的配置选项
给 prop 设置数据类型
在声明 prop 时,可以通过
type
来规定prop 的数据类型
如果传递过来的数据不符合type设置的数据类型,vue会在控制台中给出
报错信息
、
示例代码如下:
<script>
// 使用对象格式,给 prop 设置配置选项
props:{
n:{
// type 可以规定传递过来的 prop 的数据类型
// 常见的数据类型:String、Number、Boolean、Object、Array
type:Number
}
}
</script>
给 prop 设置默认值
在声明 prop 时,可以通过
default
来设置prop 的默认值
当外界在使用组件的时候,
没有传递自定义属性
,prop就使用这个默认值
示例代码如下:
<script>
// 使用对象格式,给 prop 设置配置选项
props:{
n:{
// default 用来给 prop 设置默认值
// 当外界在使用组件的时候,没有传递自定义属性,prop就使用这个默认值
default:1
}
}
</script>
给 prop 设置是否必填
在声明 prop 时,可以通过
required
选项,将该 prop 设置为必填项
,强制外界使用组件的时候必须传递自定义属性
示例代码如下:
<script>
// 使用对象格式,给 prop 设置配置选项
props:{
n:{
// required:true 规定该 prop 是必填项
// 强制使用组件的时候必须传递自定义属性,否则会报错
required:true
}
}
</script>
required 和 default 是互斥的选项,不会同时设置。如果同时设置,
required 的优先级比 default 高
prop - prop 是只读的
prop 是只读的
vue 规定:组件中封装的自定义属性是
只读的
,我们不能直接修改
prop 的值。否则会直接报错
代码示例如下:(设置 init 初始值)
<!-- prop 是只读的,不能直接修改 -->
<p>count的值是:{{init}}</p>
<button @click="init += n">+{{n}}</button>
<script>
props:{
init:{
type:Number,
default:0
}
}
</script>
要想修改 prop 传进来的
初始值
,可以把 prop 的值转存到 data 中
,然后修改 data,因为 data 中的数据都 是可读可写的!
代码示例如下:
<!-- prop 是只读的,不能直接修改 -->
<p>count的值是:{{init}}</p>
<button @click="init += n">+{{n}}</button>
<script>
data(){
return{
// 如果想修改 prop 传进来的初始值,可以将 prop 的值转存到 data 中,然后修改 data
count: this.init
}
}
</script>
解决组件之间的样式冲突
组件之间的样式冲突问题
默认情况下,
写在 vue 组件中的样式会全局生效
,因此很容易造成多个组件之间的样式冲突问题
导致组件之间样式冲突的原因是:
- 单页面面应用程序中,所有组件的 DOM 结构,都是
基于唯一的 index.html 页面
进行呈现的 - 每个组件中的样式,都会
影响整个 index.html 页面
中的 DOM 元素
style 节点的 scoped 属性
vue 为
style 节点
提供了scoped
属性,从而防止组件之间的样式冲突问题:代码示例:Left.vue
<style scoped> <!-- 给组件的 style 标签设置 scoped 属性后, 那么样式只会作用于当前组件,并不会影响其他组件的样式 --> h3{ color:orange } </style>
实现原理:
- style 标签中添加 scoped 属性后,vue就会为当前组件中的DOM 元素添加唯一的一个自定义属性
v-data-xxx
- 然后 css 选择器会通过这个自定义属性去选中元素,从而解决样式冲突的问题
注意:实际开发中,建议在每个组件的 style 身上都加上 scoped 属性
样式穿透
在给当前组件的 style 添加了 scoped 属性后,如果想
在父组件中修改子组件的样式
,就需要使用深度选择器
在 css 中使用
>>>
,代码示例如下:<style scoped> <!-- 在 css 中使用 >>> 实现样式穿透 --> div >>> h5{ color:pink; } </style>
在 less 中使用
/deep/
,代码示例如下:<style scoped lang="less"> <!-- 在 less 中使用 /deep/ 实现样式穿透 --> div /deep/ h5{ color:pink; } </style>
应用场景:需要
修改第三方组件库中组件的原有样式
的时候