vue入门04
Vue快速入门04
组件组成三个部分
组件的三大组成部分:
结构
<template>
- 只能有一个根元素
<div>
- 只能有一个根元素
样式
<style>
- 全局样式(默认):影响所有组件
- 局部样式:
scoped
下样式,只用于当前组件
- 逻辑
<script>
el
根实例独有,data
是一个函数,其他配置项与引入核心库开发一样的
样式—scoped
默认情况:写在组件中的样式会全局生效,因此很容易造成多个组件之间的样式冲突问题
全局样式:默认组件中的样式会作用到全局
局部样式:可以给组件加上
scoped
属性,可以让样式只作用于当前组件1
2<style scoped>
</style>
为避免不同组件样式冲突,建议给每个组件加上scoped
scoped原理
- 给当前组件内所有的标签都会添加
data-v-hash值
的属性 css
选择器都被添加[data-v-hash值]
的属性选择器
最终导致必须是当前组件的元素,最会有这个自定义属性,才会被这个样式作用到
逻辑—data是一个函数
一个组件的data
选项必须是一个函数,这样的好处是:保证每个组件实例,维护独立的一份数据对象
每次创建新的组件实例,都会重新执行一次data
函数,得到一个新对象
1 | <script> |
实例
1 | <template> |
组件通信
概述
组件通信,指的是 组件与组件 之间的数据传递
- 组件的数据是独立的,无法直接访问其他组件的数据
- 如果想要使用其他组件的数据,组需要利用组件通信机制
组件关系及其对应通信方案
不同组件关系,其组件通信方案也不一样
组件关系分类:
- 父子关系
- 组件间通信方案:
props
和$emit
- 组件间通信方案:
- 非父子关系
- 组件间通信方案:
provide & inject
和eventbus
- 组件间通信方案:
通用的解决方案Vuex
,适用于复杂的业务场景
父子通信
父组件通过props
将数据传递给子组件
- 在父组件中给子组件以添加属性的方式传递值
- 在子组件中通过
props
接收数据
子组件利用$emit
通知父组件修改更新
- 子组件
$emit
发送消息· - 父组件中给子组件添加消息监听
- 父组件中实现相应的处理函数
实例
父组件代码
1 | <template> |
子组件代码
1 | <template> |
Prop
Prop
定义:组件上注册的一些自定义属性
Prop
作用:向子组件传递数据
特点:
- 可以传递任意数量的prop
- 可以传递任意类型的prop
Prop校验
为保证组件的Prop
不乱传,可以为组件的Prop
指定验证要求,不符合要求,控制台就会有错误提示
常见的校验:
- 类型校验
1 | props:{ |
- 非空校验
- 默认值
- 自定义校验
如果需要满足多个校验的要求,完整的写法如下:
1 | props:{ |
Prop vs data
共同点:都可以给组件提供数据
区别:
- data数据是自己的,可以随便改
- prop数据是外部父组件提供的,不能直接更改,遵循单向数据流
非父子组件通信
方式一:event bus事件总线
作用:非父子组件之间,进行简易消息传递,复杂场景简易使用Vuex
使用语法:
创建一个都能访问到的事件总线(空Vue实例)
1
2
3import Vue from 'vue'
const Bus = new Vue()
export default BusA组件(接收方),监听Bus实例的事件
1
2
3
4
5created(){ //监听事件,出触发对应动作
Bus.$on('sendMsg',(msg)=>{
this.msg = msg
})
}B组件(发送方),触发Bus实例的事件
1
Bus.$emit("sendMsg","传递的消息内容")
方式二:provide & inject
provide & inject
作用:跨层级(爷爷辈组件提供的数据,子孙辈均可直接使用)共享数据
- 父组件provide提供数据
1 | export default{ |
- 子/孙组件inject取值使用
1 | export default{ |
进阶语法
v-model原理
原理:v-model
本质是一个语法糖,例如应用在input
输入框,其就相当于value
属性和input
事件的合写
作用:提供数据的双向绑定
- 数据变,视图会跟着变:
value
- 视图变,数据会跟着变:
@input
1 | <input v-model="msg" type="text"> |
表单组件封装 & v-model简化代码
表单组件封装
- 父传子:数据应该是父组件
Props
传递过来的,v-model
拆解绑定数据 - 子传父:监听输入,子传父,传值给父组件修改
子组件BaseSelect封装的代码示例
1 | <select :value="cityId" @change="handleChange"> |
父组件代码示例
1 | <BaseSelect :cityId="selectId" @事件名="selectId= $event"></BaseSelect> |
父组件v-model简化代码,实现父子组件数据的双向绑定
在子组件中将数据更改的事件命名为input
,传递的数据名改为value
,这样父组件代码就可以简写
子组件封装代码示例
1 | <select :value="value" @change="handleChange"> |
父组件代码
1 | <BaseSelect :value="selectId" @input="selectId=$event"></BaseSelect> |
.sync修饰符(了解)
作用:可以实现父子组件数据的双向绑定,简化代码
背景:v-model简化的前提是数据传递时props
接收用value
命名,但是并非所有组件用value
都合适,而用.sync
可以自定义props
属性名
ref和$refs
作用:利用ref
和$refs
可以用于获取dom
元素或组件实例
背景:
- 利用
document.queryselector()
查找时是整个页面查找 - 利用
ref
和$refs
是在当前组件内查找,会更加精准准确
语法:
获取dom
元素
- 目标标签添加
ref
属性,并将属性值设置为xxx
- 在恰当时机(挂载之后,才可访问
dom
元素),通过this.$refs.xxx
获取目标标签
示例代码
1 | <div ref="chartRef">渲染图标容器</div> |
1 | mounted(){ |
获取组件实例
- 给目标组件添加
ref
属性,设置属性值为xxx
- 在恰当时机,通过
$refs.xxx
获取目标组件,然后可以调用组件对象里面的方法
示例代码
1 | <BaseCom ref="baseCom"></BaseCom> |
1 | this.$refs.baseCom.组件方法() |
Vue异步更新与$nextTick
异步更新:Vue
是异步更新DOM
,以提升性能
$nextTick
:等DOM
更新后,才会触发执行此方法里的函数体
语法:this.$nextTick(函数体)
示例
比如点击一个按钮,然后会显示一个输入框,然后让这个输入框自动获取焦点
1 | <template> |
上面这种写法是会报错的,因为vue
是dom
异步更新,不能立刻获取对应元素
应当借助$nextTick
来实现该功能,等dom
更新完,再执行对应的功能
1 | <template> |