上海 网站备案系统,东莞企业网站建设公司,新产品开发8个步骤,百度广告价格文章目录 一、scoped 样式冲突二、data 是一个函数三、组件通信1. 父子通信1.1 props 校验1.2 props 比较 data 2. 非父子通信2.1 event bus2.2 provide-inject 四、进阶语法1. v-model 详解2. sync 修饰符3. ref 和 $refs4. $nextTick 一、scoped 样式冲突 注意点#xff1a;… 文章目录 一、scoped 样式冲突二、data 是一个函数三、组件通信1. 父子通信1.1 props 校验1.2 props 比较 data 2. 非父子通信2.1 event bus2.2 provide-inject 四、进阶语法1. v-model 详解2. sync 修饰符3. ref 和 $refs4. $nextTick 一、scoped 样式冲突 注意点 ① 结构只能有一个根元素 ② 样式组件中定义的样式默认是全局生效的会影响到所有组件而 scoped 属性下的样式可以作用于当前组件 ③ 逻辑el 是根实例所独有的data 是一个函数。 默认情况下写在组件中的样式会全局生效因此很容易造成多个组件之间的样式冲突问题而组件应该有着自己独立的样式我们可以给组件加上 scoped 属性让样式只作用于当前组件。
style scoped
/stylescoped 原理给当前组件中的所有元素都添加一个自定义属性data-v-hash不同的哈希值用于区分不同的组件
二、data 是一个函数
在一个组件里面data 选项必须是一个函数保证每个组件实例维护独立的一份数据对象。 每次创建新的组件实例都会执行一次 data 函数得到一个新对象各个对象之间互不影响。 三个实例对象各自独立互不影响
三、组件通信
组件通信就是指组件与组件之间的数据传递。 组件之间的数据是独立的无法直接访问其他组件的数据想要用其他组件的数据就必须要组件通信。
组件关系分为父子关系和非父子关系 1. 父子通信
父组件通过 props 将数据传递给子组件子组件不能直接修改父组件中的数据而是利用 $emit 通知父组件进行修改更新。 !--App.vue--
templatediv classAppSon :titlemyTitle changeTitlehandleChange/Son/div
/templatescript
import Son from ./components/Son.vue;
export default {data() {return {myTitle: 栈老师不回家}},components: {Son},methods: {handleChange(newTitle) {this.myTitle newTitle}}
}
/scriptstyle scoped
.App {width: 600px;height: 600px;background-color: rgb(193, 230, 248);margin: 0 auto;padding: 20px;
}
/style
!--Son.vue--
templatediv classson{{ title }}button clickchangeFn修改/button/div
/templatescript
export default {props: [title],methods: {changeFn() {this.$emit(changeTitle, 新数据)}}
}
/scriptstyle
.son {width: 200px;height: 200px;background-color: #f8dd30;margin: 0, auto;
}
/style通过自定义属性和自定义事件来实现父子之间的通信。子组件通过 $emit 向父组件发送消息通知第一个参数是父组件中自定义的监听事件第二个参数是修改的新数据父组件通过 change Title 监听消息并做出回应即修改数据。
1.1 props 校验
props 用于向子组件传递数据并且可以传递任意类型、任意数量的数据。
为了保证组件的正常运行组件的 props 不可以乱传。我们可以给组件的 props 指定验证要求不符合要求控制台就会有错误提示可以帮助开发者快速发现错误。
① 类型校验
props: {校验的属性名: 类型 //Number、String、Boolean、Array、Object...
}② 更详细的校验
props: {校验的属性名: {type: 类型, //Number、String、Boolean、Array、Object...required: true, //是否必填default: 默认值, //默认值validator(value) { //value就是传过来的属性名//自定义校验逻辑return true //true通过校验false不通过校验}}
} 1.2 props 比较 data
共同点都可以给组件提供数据。
区别data 的数据是自己的可以随便改props 的数据是外部的不能直接改要遵循单向数据流原则通知其父组件进行修改。
单向数据流父组件的 props 更新会单向向下流动从而影响到子组件。
count 是 count 加 1 并重新赋值会直接修改 count 的值而 count 1 并不会重新赋值count 的值也不会被改变所以对于 props 里的数据不要使用 直接让它 1 通知父组件即可
谁的数据谁负责数据一般提供在公共的父组件中
2. 非父子通信
2.1 event bus
event bus 用于非父子组件之间进行简易的消息传递。
① 创建一个双方都能访问到的事件总线空 Vue 实例→ utils/EventBus.js
import Vue from vue
const Bus new Vue()
export default Bus② A 组件接收方监听 Bus 实例的事件
created() {Bus.$on(sendMsg, (msg) {this.msg msg})
}③ B 组件发送方触发 Bus 实例的事件
Bus.$emit(sendMsg, 这是一个消息)发送方发送消息从而触发 Bus而接收方时刻监听着 BusBus 一旦被触发接收方立马就可以接收到消息
完整代码如下
//EventBus.js
//创建一个都能访问到的事件总线空的Vue实例
import Vue from vue;
const Bus new Vue()
export default Bus//BaseA.vue
templatediv classbaseA我是A组件(接收方)div{{ msg }}/div/div/templatescriptimport Bus from /utils/EventBus;export default {data() {return {msg: }},created() {//订阅消息Bus.$on(sendMsg, (msg) {this.msg 收到消息了 msg})}}/scriptstyle scoped.baseA {width: 200px;height: 150px;padding: 10px;margin-top: 10px;border: 3px solid #000;border-radius: 5px;font-size: 20px;}/styletemplatediv classbaseB我是B组件(发布方)button clickpublish发布通知/button/div
/templatescript
import Bus from /utils/EventBus;
export default {methods: {publish() {//发送方通过触发事件的方式发布消息Bus.$emit(sendMsg, 栈老师回家)}}
}
/scriptstyle scoped
.baseB {width: 200px;height: 150px;padding: 10px;margin-top: 10px;border: 3px solid #000;border-radius: 5px;font-size: 20px;
}
/style发送方发送的消息可以被多个接收方订阅
2.2 provide-inject
跨层级孙子和爷爷之间的通信用 provide-inject。
//发送方爷爷
provide() {return {color: this.color, //简单类型非响应式userInfo: this.userInfo //复杂类型响应式}
},
data() {return {color: blue,userInfo: {name: 栈老师,age: 20}}
}//接收方孙子
inject: [color, userInfo]使用 provide-inject 共享数据的时候通常以复杂类型的形式把数据包装成一个对象进行传递这样可以保证数据的响应式。
四、进阶语法
1. v-model 详解
原理v-model 本质上是一个语法糖例如应用在输入框上就是 value 属性和事件的合写。
作用提供数据的双向绑定。
注意$event 用于在模版中获取事件的形参。
!--两个input作用一样--
div classAppinput v-modelmsg typetextinput :valuemsg inputmsg$event.target.value typetext
/div$event.target.value 就是输入框中的值
表单类组件封装
① 父传子数据应该是父组件 props 传递过来的v-model 拆解绑定数据。 ② 子传父监听输入子传父传值给父组件修改。
应用场景举例此下拉框中所有的数据都来自它的父组件所以数据是不能直接修改的子组件中也不能使用 v-model因为 v-model 会修改数据解决办法就是拆解 v-model让 value 和 change 拆开写。 select :valuecityId changehandleChange
...
/selectprops: {cityId: String
},
methods: {handleChange(e) {this.$emit(父组件中的事件名, e.target.value)}
}!--父组件接收--
BaseSelect :cityIdselectId 事件名selectId$event/2. sync 修饰符
作用可以实现子组件与父组件数据的双向绑定简化代码。
特点props 属性名可以自定义非固定为 value。
场景封装弹框类的基础组件visible 属性true 显示false 隐藏。
:属性名.sync本质上就是 :属性名和 update:属性名的合写。
!--父组件与子组件通过:visible.sync即可实现数据的双向绑定--
BaseDialog :visible.sync isShow///子组件正常用props接收数据emit发出修改申请
props: {visible: Boolean
},
methods: {close() {this.$emit(update:visible, false) //update:属性名, 修改后的数据}
}3. ref 和 $refs
作用ref 和 $refs 用于获取 dom 元素或组件实例。
查询范围当前组件内更精准确定。
① 获取 dom 元素
!--给目标标签添加ref属性--
div refchartRef我是渲染图标的容器/div//dom渲染完成后mounted通过this.$refs.属性值获取目标标签
mouted() {console.log(this.$refs.chartRef)
}② 获取组件
!--给目标组件添加ref属性--
BaseForm refbaseForm我是一个组件/BaseForm//使用this.$refs.baseForm可以获取目标组件
this.$refs.baseForm.组件方法()获取到目标组件后就可以直接调用组件对象里面的方法
4. $nextTick
需求点击编辑编辑框自动显示并聚焦。
this.isShowEdit true //显示输入框
this.$refs.inp.focu() //获取焦点问题以上代码并不能立刻获取焦点。
原因Vue 是异步更新提升性能。并不会读一行就执行一行它要等全部代码都读完了才开始执行所以此处 dom 还没更新出来就去获取焦点显然是不可能成功的。
$nextTick等 DOM 更新后才会触发执行此方法里的函数体。
将获取焦点的操作放在 $nextTick 里面就可以了
this.$nextTick(() {this.$refs.inp.focus()
})