一、vue2.0
1、父级组件调用子组件counterComponents
ini
<counterComponents v-model="item.totalNumber"/>
2、子组件counterComponents.vue
需求:计数器的输入值在1-30的范围的正整数 主要代码 子组件绑定值::value="innerValue" 组件更新数据: this.$emit('change',newInnerValue + 1)
js
export default {
// 使用 model 配置,支持 v-model
model:{
prop: 'value',
event:'change'
},
props: {
value: {
type: Number,
default: 1
},
},
data() {
return {
innerValue: this.value
}
},
watch: {
// 监听外部 value 变化,同步到内部值
value: {
immediate: true,
handler(newVal) {
this.innerValue = newVal
}
}
}
}
完整代码
js
<template>
<div
class="pi-align-center"
@click.stop="()=>{}">
<span class="pi-pd-right-20">货物件数 </span>
<div class="counter-containers pi-align-center pi-justify-between">
<div
class="pi-pd-lr-10 btn"
@click.stop="handleCount('subtract')">
<pi-icon
name="subtract"
size="30" />
</div>
<pi-input
:value="innerValue"
placeholder=""
:customStyle="{
background: '#ffffff',
borderLeft: '1rpx solid #d7d7d7',
borderRight: '1rpx solid #d7d7d7',
}"
customClass="pi-text-center"
@input="handleInput"
/>
<div
class="pi-pd-lr-10 btn"
@click.stop="handleCount('add')">
<pi-icon
name="add"
size="30" />
</div>
</div>
</div>
</template>
<script>
export default {
// 使用 model 配置,支持 v-model
model:{
prop: 'value',
event:'change'
},
props: {
value: {
type: Number,
default: 1
},
min: {
type: Number,
default: 1,
},
max: {
type: Number,
default: 30,
}
},
data() {
return {
innerValue: this.value
}
},
computed: {
},
watch: {
// 监听外部 value 变化,同步到内部值
value: {
immediate: true,
handler(newVal) {
this.innerValue = newVal
}
}
},
methods: {
handleCount(sign) {
const newInnerValue = this.innerValue
if (sign === 'add') {
if (newInnerValue + 1 > this.max) return
this.$emit('change',newInnerValue + 1)
} else {
if (newInnerValue - 1 < this.min) return
this.$emit('change',newInnerValue - 1)
}
},
handleInput(e) {
const num = e.replace(/[^0-9]/g, '')
const number = num ? num * 1 : 0
if (number) {
const maxNumber = number > this.max ? this.max : number
this.$emit('change',maxNumber)
} else {
this.$emit('change',1)
}
},
},
}
</script>
<style lang="scss" scoped>
.counter-containers {
width: 200rpx;
background-color: #f2f2f2;
border: 1rpx solid #d7d7d7;
border-radius: 10rpx;
overflow: hidden;
box-sizing: border-box;
.btn {
cursor: pointer;
}
}
</style>
二、vue3.4前
父组件代码
xml
<script setup lang="ts">
import { ref } from 'vue';
import dialogComponent from '@/components/dialogComponent.vue';
let isShow = ref(false)
</script>
<template>
<div>
<button @click="isShow = true ">打开</button>
<dialogComponent v-model="isShow"/>
</div>
</template>
子组件代码
xml
<script setup lang="ts">
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
</script>
<template>
<div v-if="props.modelValue">
弹框
<button @click="emit('update:modelValue', false)">关闭</button>
</div>
</template>
三、vue3.4后
父组件代码
xml
<script setup lang="ts">
import CounterComponent from '@/components/CounterComponent.vue';
import { ref } from 'vue';
let count = ref(0)
const add = () =>{
count.value = Number(count.value)+1
}
</script>
<template>
<div>
<button @click="add">+1</button>
<CounterComponent v-model="count"/>
<div>{{ count }}</div>
</div>
</template>
子组件代码
xml
<script setup lang="ts">
// 声明一个双向绑定 prop
const model = defineModel();
</script>
<template>
<div>
<input type="number"v-model="model">
</div>
</template>