目录
父子关系通讯props和$emit
子类通过$emit发送传值到父类,父类进行修改值
父类App.vue
<template>
<div>
<ViewA :count="calCount" @changeCount="changeCount"></ViewA>
</div>
</template>
<script>
import ViewA from '@/components/ViewA.vue'
export default {
data () {
return {
calCount: 0
}
},
methods: {
changeCount (newValue) {
this.calCount = newValue
}
},
components: {
ViewA
}
}
</script>
<style>
</style>
子类ViewA.vue
<template>
<div>
<button @click="subCount">-</button>
<span class="showStyle">{{ count }}</span>
<button @click="addCount">+</button>
</div>
</template>
<script>
export default {
props: {
count: {
type: Number,
default: 0
}
},
methods: {
subCount () {
this.$emit('changeCount', this.count - 1)
},
addCount () {
this.$emit('changeCount', this.count + 1)
}
}
}
</script>
<style>
.showStyle{
margin: 0 10px;
}
</style>
非父子通讯-event bus事件总线
1.总线utils/EventBus.js
import Vue from 'vue'
const Bus = new Vue()
const MSG_KEY = 'SendMsgKey'
export {
Bus,
MSG_KEY
}
2.订阅者components/ViewA.vue
<template>
<div>消息订阅者:{{ msg }}</div>
</template>
<script>
import { MSG_KEY, Bus } from '@/utils/EventBus.js'
export default {
data () {
return {
msg: ''
}
},
created () {
Bus.$on(MSG_KEY, (msg) => {
this.msg = msg
})
}
}
</script>
<style>
</style>
3.发布者App.vue
<template>
<div>
<ViewA></ViewA>
<div>
<input type="text" v-model="msg">
<button @click="SendMsg">发送</button>
</div>
</div>
</template>
<script>
import ViewA from '@/components/ViewA.vue'
import { Bus, MSG_KEY } from '@/utils/EventBus.js'
export default {
components: {
ViewA
},
data () {
return {
msg: ''
}
},
methods: {
SendMsg () {
Bus.$emit(MSG_KEY, this.msg)
}
}
}
</script>
<style>
</style>
非父子通讯-provide和inject
1.父类组件App.vue
<template>
<div>
<button @click="updateHandle">更新</button>
<ViewA></ViewA>
<ViewAA></ViewAA>
</div>
</template>
<script>
import ViewA from './components/ViewA.vue'
import ViewAA from './components/ViewAA.vue'
export default {
components: {
ViewA,
ViewAA
},
provide () {
return {
// 非响应式:数据更改,不会更改界面
color: this.color,
// 响应式:数据更改,更改界面
userInfo: this.userInfo
}
},
data () {
return {
color: 'pink',
userInfo: {
name: '李四',
age: 20
}
}
},
methods: {
updateHandle () {
this.color = 'red'
this.userInfo.name = '王五'
}
}
}
</script>
<style>
</style>
2.第一层components/ViewA.vue
<template>
<div>
<h1>ViewA</h1>
<div>颜色:{{ color }}</div>
<div>姓名:{{ userInfo.name }}</div>
</div>
</template>
<script>
export default {
inject: ['color', 'userInfo']
}
</script>
<style></style>
3.第二层components/ViewAA.vue
<template>
<div>
<h1>ViewA_A</h1>
<div>颜色:{{ color }}</div>
<div>姓名:{{ userInfo.name }}</div>
</div>
</template>
<script>
export default {
inject: ['color', 'userInfo']
}
</script>
<style>
</style>
v-model原理
v-mode是父子关系通讯(prop和$emit),只是prop属性名称是value(固定)更新方法是input,本质是通过value进行通讯
例子:封装增减值控件
1.ViewA.vue
<template>
<div>
<button @click="subValue">-</button>
<span class="showBox">{{ value }}</span>
<button @click="addValue">+</button>
</div>
</template>
<script>
export default {
props: {
value: {
type: Number,
default: 0
}
},
methods: {
subValue () {
this.$emit('input', this.value - 1)
},
addValue () {
this.$emit('input', this.value + 1)
}
}
}
</script >
<style scoped>
.showBox{
margin: 0 10px;
}
</style>
2.使用App.vue
<template>
<div>
<ViewA v-model="calCount"></ViewA>
</div>
</template>
<script>
import ViewA from '@/components/ViewA.vue'
export default {
components: {
ViewA
},
data () {
return {
calCount: 0
}
}
}
</script>
<style>
</style>
.sync修饰符
作用:可以实现子组件与父组件数据的双向绑定
特定:prop属性名称,可以自定义,非固定value
本质:属性名称和@update:属性名 合写
控件:components/ViewA.vue
<template>
<div>
<select :value="selectedId" @change="changeHandle">
<option value="1">选择1</option>
<option value="2">选择2</option>
<option value="3">选择3</option>
<option value="4">选择4</option>
<option value="5">选择5</option>
</select>
</div>
</template>
<script>
export default {
props: {
selectedId: {
type: String,
default: '1'
}
},
methods: {
changeHandle (e) {
this.$emit('update:selectedId', e.target.value)
}
}
}
</script>
<style>
</style>
使用:App.vue
<template>
<div>
<ViewA :selectedId.sync="selectedID"></ViewA>
<button @click="testMethod">测试</button>
</div>
</template>
<script>
import ViewA from '@/components/ViewA.vue'
export default {
components: {
ViewA
},
data () {
return {
selectedID: '2'
}
},
methods: {
testMethod () {
console.log(this.selectedID)
}
}
}
</script>
<style>
</style>
ref和$refs修饰符
作用:利用ref和$refs可以用于获取dom元素
<template>
<div>
<div ref="boxDiv">this is a div</div>
<button @click="GetDiv">获取</button>
</div>
</template>
<script>
export default {
methods: {
GetDiv() {
//获取
console.dir(this.$refs.boxDiv)
}
}
}
</script>
<style></style>
$nextTick修饰符
作用:等DOM更新后,才会触发执行此方法里的函数体
<template>
<div>
<div v-if="isShow">
<button @click="showInput">点击消失</button>
</div>
<input ref="inp" type="text" v-else>
</div>
</template>
<script>
export default {
data() {
return {
isShow: true
}
},
methods: {
showInput() {
this.isShow = false;
this.$nextTick(() => {
this.$refs.inp.focus()
})
}
}
}
</script>
<style></style>