案例说明
A页面引用的子组件B
A页面
<template>
<view>
//引用组件
<serviceOrder @change="change" :list="list" :current="type"></serviceOrder>
</view>
</template>
<script setup>
import serviceOrder from '@/components/serviceOrder/serviceOrder.vue'
const type = ref(0)
// 切换tab
function change(e) {
type.value = e
}
</script>
B子组件
<template>
<view>
<view class="orderTab">
<block v-for="(item,index) in tabs" :key="index">
<view class="tabItem" @click="change(index)" :class="index == current2?'active':''">
{{item.name}}
</view>
</block>
</view>
</view>
</template>
<script setup>
import {
ref,
watch
} from 'vue'
// 接收值
const props = defineProps({
current: {
type: Number,
default: 0
}
})
// 接收方法
const emit = defineEmits(['change'])
const tabs = ref([{
name: '全部',
type: 0
}, {
name: '待付款',
type: 1
}, {
name: '待服务',
type: 2
}, {
name: '已完成',
type: 3
}])
const current2 = ref(0) //默认索引为0的样式
watch(
() => props.current,
(newVal, oldVal) => {
current2.value = newVal
}
)
// 切换
const change = (index) => {
current2.value = index // 样式处理
emit('change', current2.value)//传递方法
}
</script>
<style lang="scss" scoped>
.orderTab {
display: flex;
justify-content: space-between;
align-items: center;
height: 88rpx;
background: #FFFFFF;
padding: 0 29rpx;
.tabItem {
font-size: 28rpx;
color: #636363;
}
.active {
position: relative;
}
.active:after {
content: '';
position: absolute;
left: 50%;
bottom: -10rpx;
transform: translateX(-50%);
width: 40rpx;
height: 5rpx;
background: #2CB6DB;
border-radius: 50rpx;
}
}
</style>
在此案例中,子组件中 用来通过判断来显示蓝色下划线样式的 变量为什么没有用current而是用的current2,你会发现组件接收的值不能在下面方法中二次处理使用,所以这个又定义了一个变量current2,改怎么写就怎么写样式判断。之后tab点击的事件暴露出去,在A页面里面使用。
当A页面current属性值被修改的时候,假如C页面中点击某个待服务
跳转到A页面并传了参数2,这时候A页面接受该参数2,并将type的类型赋值为2,之后为了对应的效果显示,需要告诉B组件,目前应该是处于谁被选中的状态【下图】。所有就有了:current = "type"
子组件使用 defineProps
接收传过来的参数2,watch一直监听这个变量,一旦这个变量有变化,那么执行操作,current2等于最新的2,这样“待服务”下面就有蓝条条了。
watch(
() => props.current,
(newVal, oldVal) => {
current2.value = newVal
}
)
问题
如果遇到了ref、watch is not defined等报错,
vue3的setup里面直接使用watch会报错,需要使用import引入之后才可使用。
import { ref, watch } from 'vue'