组件化开发
- 一个页面(.vue文件)可能有一个或多个组件(.vue)组成完整的页面功能
封装的思想:把页面上
可重用的部分封装为组件,从而方便项目的 开发 和 维护vue组件-封装创建
哪部分标签复用, 就把哪部分封装到组件内
- 组件内template只能有一个根标签
- 组件内data必须是一个函数, 独立作用域
- 封装路径:components/Pannel.vue
```vue
芙蓉楼送辛渐
{{ isShow ? ‘收起’ : ‘展开’ }}寒雨连江夜入吴,
平明送客楚山孤。
洛阳亲友如相问,
一片冰心在玉壶。
<a name="gIjef"></a>### vue组件-复用全局注册语法:<br />全局入口在main.js, 在new Vue之上注册<br />`import 组件对象 from 'vue文件路径'`<br />`Vue.component("组件名", 组件对象)`- 组件名和组件对象使用大驼峰命名```javascriptimport PannelTest from './components/pannel.vue'Vue.component('Pannel', PannelTest)
在页面中使用:
- 单闭合:
<组件名 /> - 双闭合:
<组件名> <组件名 />```vue
局部导入语法:<br />`import 组件对象 from '文件路径'`<br />`components: { 组件名: 组件对象 }`(跟data同级)- components对象中,键值对一样可以只写一个- 组件名和组件对象使用大驼峰命名在页面中使用:- 单闭合:`<组件名 />`- 双闭合:`<组件名> <组件名 />````vue<template><div><Pannel /></div></template><script>import Pannel from '../components/pannel.vue'export default {components: {Pannel: Pannel}}</script><style lang="less" scoped></style>
vue组件-scoped作用
- 问题:组件化开发中,父子嵌套情况,样式会出现类名冲突时
- 说明:父组件的样式会覆盖子组件的样式
- 解决:在每个
style标签中加入scoped属性 -
vue组件-/deep/深度作用选择符
问题:父元素控制子元素的样式时,开启了样式模块化
scoped就控制不到- 解决:在要控制的子组件类名或元素名前面加一个
/deep/(深度作用选择符) - 默认子组件的根元素,会带上父组件的data-v-hash属性,所以可以直接控制
vue组件通信(重点)
vue单向数据流(限制)
- 保护数据的可维护性(只在一个位置可以修改数据)
- 父组件传递的数据
props,不能改,props只读 - 只有父组件可以改
- 简单类型的 不能直接改
- 引用类型的 不能改地址,但是可以修改里面的值(部分改)
- 总结:在哪儿定义就在那儿改
父传子-props
- 在父组件中的子组件标签
:传递的数据名="data变量名" - 不加:传递的是固定值,加:必须传递变量
- 子组件中接收:
props: ['父组件传递的数据名'] - 实际开发使用
props: {父组件转递的数据名: {type:设置(校验)接受数据的类型default: ( ) => { return }}}
default是默认属性如果父组件没有传递数据,使用这个默认值
如果是复杂类型(对象,数组)的,默认值需要通过函数返回默认值
export default {props: {tabList: {type: Array,default: () => [],require: true // 表示必须传递,不传递会报错},},}
子传父
在父组件中的子组件标签 @自定义事件="methods函数"
修改在父组件methods函数的内部修改
子组件的methods函数内部 this.$emit('自定义事件',参数1,参数2)
传递的参数会传递给自定义事件绑定的函数
组件生命周期
阶段
- 初始化 => 创建组件
- 挂载 => 渲染显示组件
- 更新 => 修改数据
-
钩子函数
初始化:(只执行一次,.vue文件实例化)
- 创建前:
beforeCreate ( ) { 实例化前 } - 创建后:
created ( ) { 发送ajax请求 }
- 创建前:
- 挂载:(只执行一次,页面渲染)
- 挂载前:
beforeMounte () { 页面渲染前,不能操作dom } - 挂在后:
mounted () { 可以操作dom和发送ajsx请求 }
- 挂载前:
- 更新:(可以执行多次,data变量更新)
- 更新前:
beforeUpdate () { 数据更新,页面没有更新 } - 更新后:
updated () { 数据更新,页面更新 }
- 更新前:
- 销毁:(只执行一次,切换页面或者组件从页面中被移除)
- 销毁前:
beforeDestroy () { 清除定时器,解绑js事件 } - 销毁后:
destroyed () { 清除定时器,解绑js事件 }
- 销毁前:
ref和$refs的使用
获取DOM对象
- 在获取DOM的元素身上写
ref属性并赋值 - 通过
this.$refs.ref属性值获取DOM对象 - 通过
this.$refs.ref属性值.style.css属性操作dom
获取组件实例
- 在获取组件的自定义标签身上写
ref属性并赋值 - 通过
this.$refs.ref的属性值获取组件实例 this.$refs.ref的属性值 === 获取当前的组件实例this$nextTick使用
语法:
this.$nextTick( () => {})vue修改data变量后,不能立马获取最新的dom (获取上一次的dom)
- vue做了优化,dom的更新是异步的
- 获取异步更新之后的dom使用
this.$nextTick(callback回调函数) - callback函数内部就可以获取到最新的dom
- 可以使用
async``await this.$nextTick()的写法
动态组件
语法:<component :is="data变量"><component>
- data变量值为动态切换组件的标签名
- 可以动态切换多个子组件
```vue
```vue<template><div><div class="box"><p>登录页面</p></div></div></template><script>export default {}</script><style scoped>.box {border: 2px solid pink;background-color: skyblue;}</style>
<template><div class="box"><p>注册页面</p></div></template><script>export default {}</script><style scoped>.box {border: 2px solid skyblue;background-color: pink;}</style>
组件缓存
现象:动态切换的组件,切换时会被销毁每次都会被重新创建(浪费性能)
语法:<keep-alive><keep-alive>
- 包裹后组件只会在第一次被创建一次,之后会被缓存
- 缓存的生命周期
- 激活:
activated() { } - 失去激活状态:
deactivated() { }
- 激活:
- include属性
include="被缓存组件的name值"- nama值是唯一的(不能使用html元素名,会报错)
```vue
```vue<template><div><div class="box"><p>登录页面</p></div></div></template><script>export default {name: 'lg',deactivated () {console.log('离开了缓存')},activated () {console.log('进入了缓存')},created () {console.log('创建了组件')},destroyed () {console.log('被销毁了')},}</script><style scoped>.box {border: 2px solid pink;background-color: skyblue;}</style>
<template><div class="box"><p>注册页面</p></div></template><script>export default {name: 'rg'}</script><style scoped>.box {border: 2px solid skyblue;background-color: pink;}</style>
组件插槽
通过组件标签传递内容给子组件,子组件通过slot元素接收展示渲染
默认插槽
语法:
传递<组件标签>插槽内容</组件标签>子组件接收<solt></solt>
- solt写一个,多次写回显示重复的内容
- solt不设置内容也可以单闭合
<solt /> - 如果没有传递插槽,solt内可以设置默认值
```vue
组件插槽的使用
我是组件插槽传递的
```vue<template><div><h2>我是子组件</h2><slot> <h4>插槽没传递,显示我</h4> </slot></div></template><script>export default {}</script><style scoped></style>
具名插槽
语法:
传递<组件标签><template v-slot:名字>插槽内容</template></组件标签>
子组件接收<solt name="名字"></solt>
v-solt:名字可以简写#名字- template标签外面都属于默认插槽
- v-slot和name的名字需要一样
- 可以传递多个,name不能重复
```vue
组件插槽的使用
来自西海的 三刀 刘索隆
绿藻头,嘎嘎帅
```vue<template><div><slot name="title"></slot><slot></slot><slot name="foot"> </slot></div></template><script>export default {}</script><style scoped></style>
作用域插槽
语法:
传递:子组件在slot元素上,通过动态绑定:属性名="data变量"
接收:通过<template #名字="变量">接收传递的数据
- 传递多个变量,写多个
:属性名="data变量" - 接收到的数据是一个对象类型,可以解构
```vue
组件插槽的使用
- {{ obj.name }}
- {{ obj.age }}
- {{ num }}
```vue<template><div><slot name="one" :obj="obj" :num="num"> </slot></div></template><script>export default {data () {return {obj: { name: '张三', age: 20 },num: 123}},}</script><style scoped></style>
