vue-next-libs-course
vue-next-libs-course copied to clipboard
我是你b战的一名小观众,我发现tabs有完全摒弃依赖注入的写法,这种写法更简单
我直接把代码贴出来 tabs.tsx
import {
cloneVNode,
defineComponent,
onMounted,
provide,
ref,
watch,
} from 'vue';
import './index.scss';
import { tabsProps } from './types';
const props = tabsProps();
export default defineComponent({
name: 'AfTabs',
props: props,
emits: ['update:modelValue'],
setup(props, { emit, slots }) {
const currentTabName = ref(props.modelValue);
const renderNavs = () => {
return slots.default!().map((pane, index) => {
return (
<div
class="af-tab-pane"
onClick={clickTab.bind(null, (pane.props as any).name)}
>
{(pane.props as any).name}
</div>
);
});
};
watch(
() => props.modelValue,
(newVal) => {
currentTabName.value = newVal;
},
);
const clickTab = (tabName: string) => {
if (currentTabName.value !== tabName) {
currentTabName.value = tabName;
emit('update:modelValue', tabName);
}
};
return () => {
return (
<div class="af-tabs">
<div class="navs">{renderNavs()}</div>
{slots.default!()}
</div>
);
};
},
});
tabPane.tsx
import {
defineComponent,
getCurrentInstance,
inject,
onMounted,
ref,
watch,
} from 'vue';
import { tabPaneProps } from './types';
const props = tabPaneProps();
export default defineComponent({
name: 'TabPane',
props: props,
setup(props, { emit, slots }) {
const parentNode = getCurrentInstance()?.parent;
return () => {
return (
<div class="pane" v-show={parentNode?.props.modelValue === props.name}>
{slots.default!()}
</div>
);
};
},
});
types.ts
const tabPaneProps = () => ({
name: String
})
const tabsProps = () => ({
modelValue: {
type: String,
default: ''
}
})
export { tabsProps, tabPaneProps }