使用provide 与 inject实现aside切换
1.在app中定义一个变量menuVisible,用provide标记为所有后代都可以使用
<template>
<router-view/>
</template>
<script lang="ts">
import { ref, provide } from 'vue'
export default {
name: 'App',
setup(){
const menuVisible = ref(false)
provide('xxx',menuVisible) // set
// 标记为所有组件可以使用
}
}
</script>
接下来
(2个子组件去获取,分别用topnav获取'xxx',doc获取'xxx')
2.topnav中inject
<template>
<div>
<div class="topnav">
<div class="logo" @click="toggleMenu">LOGO</div>
<ul class="menu">
<li>菜单1</li>
<li>菜单2</li>
</ul>
</div>
</div>
</template>
<script lang="ts">
import { inject, Ref } from 'vue'
export default {
setup(){
const menuVisible = inject<Ref<boolean>>('xxx') // get 这里用inject获取
console.log('topnav 获取的menuVisible为:'+ menuVisible.value);
const toggleMenu = () => {
menuVisible.value = !menuVisible.value // 当用户点击logo时,toggleMenu获取相反的逻辑值,这个也会致使doc中的v-if的menuVisible改变,menuVisible一变,视图展示的就是显示隐藏
}
return {toggleMenu}
}
}
</script>
<style lang="scss" scoped>
.topnav{
background: pink;
display: flex;
padding: 16px;
position: relative; // 解决logo遮挡
z-index: 10; // 解决logo遮挡
> .logo {
max-width: 6em;
margin-right: auto;
}
> .menu {
display: flex;
white-space: nowrap;
flex-wrap: nowrap;
> li {
margin: 0 1em;
}
}
}
</style>
- doc组件中inject 使用v-if控制显示隐藏
<template>
<div>
<Topnav />
<div class="content">
<aside v-if="menuVisible">
<h2>组件列表</h2>
<ol>
<li>
<router-link to="/doc/switch">Switch 组件</router-link>
</li>
<li>
<router-link to="/doc/button">Button 组件</router-link>
</li>
<li>
<router-link to="/doc/dialog">Dialog 组件</router-link>
</li>
<li>
<router-link to="/doc/tabs">Tab 组件</router-link>
</li>
</ol>
</aside>
<main>主内容</main>
</div>
</div>
</template>
<script lang="ts">
import { inject, Ref } from 'vue'
import Topnav from '../components/Topnav.vue'
export default {
components: {Topnav},
setup(){
const menuVisible = inject<Ref<boolean>>('xxx')
console.log('Doc aside 获取的menuVisible为:'+ menuVisible.value);
return {menuVisible}
}
}
</script>
<style lang="scss" scoped>
aside {
background: lightblue;
width: 150px;
padding: 16px;
position: fixed;
top: 0;
left: 0;
padding-top: 70px; // 解决蓝色部分遮挡
// height: 100%;
> h2 {
margin-bottom: 4px;
}
> ol {
> li {
padding: 4px 0;
}
}
}
</style>
点击logo之前
点击logo之后