项目概况

移动端展示页面

2026-01-294 min read未分类
v-ui-pro

安装依赖

bash
1pnpm add tdesign-mobile-vue

实现1-抽屉

方案 1,文章在抽屉里面显示

vue
1<template> 2 <div class="mo" style="color: black;"> 3 <Drawer 4 attach=".mo" 5 v-model:visible="visible" placement="right"> 6 <template #title> 7 <Navbar title="西魏陶渊明" :fixed="false" left-arrow @left-click="visible=false"/> 8 </template> 9 <h1>Hello</h1> 10 <Empty image="https://tdesign.gtimg.com/mobile/demos/empty1.png" description="描述文字"/> 11 </Drawer> 12 <div class="header" 13 style="opacity: 1;position: fixed; height: 6rem;overflow: hidden;top: 0;width: 100%;display: flex;flex-direction: column"> 14 <Navbar :fixed="false"> 15 <template #left> 16 <Search :placeholder="currentValue" shape="round"/> 17 </template> 18 <template #right> 19 <icon-home/> 20 </template> 21 </Navbar> 22 <Tabs :value="currentValue" size="medium" :space-evenly="false" :list="tabList" @change="onChange"> 23 </Tabs> 24 </div> 25 <div class="content" 26 style="margin: 6.1rem 0 4rem 0;height: calc(100vh - 6.1rem - 4rem);overflow-y: scroll"> 27 <div class="blog-card" v-for="blog in 10" :key="blog" @click="toPostAction"> 28 <div style="width: 100%;display: flex;gap:1rem;align-items: center"> 29 <Skeleton style="flex: 1" theme="paragraph" :row-col="rowCols" :loading="loading"></Skeleton> 30 <Skeleton theme="paragraph" :loading="loading" style="flex: 1;height: 100%"></Skeleton> 31 </div> 32 </div> 33 </div> 34 <div class="footer" style="opacity: 1;position: fixed;bottom: 0;width: 100%;height: 4rem;"> 35 <TabBar v-model="value" theme="tag" :split="false"> 36 <TabBarItem v-for="item in list" :key="item.value" :value="item.value"> 37 {{ item.label }} 38 </TabBarItem> 39 </TabBar> 40 </div> 41 </div> 42</template> 43 44<script lang="ts" setup> 45import {TabBar, TabBarItem, Navbar, Search, Tabs, Skeleton, Drawer, Empty} from 'tdesign-mobile-vue' 46// 引入组件库的少量全局样式变量 47import 'tdesign-mobile-vue/es/style/index.css'; 48import {ref} from 'vue' 49 50const viewCode = ref('home2') 51 52const visible = ref(false); 53 54const toPostAction = () => { 55 visible.value = true; 56} 57 58const value = ref('home'); 59const list = ref([ 60 {value: 'home', label: '前端'}, 61 {value: 'app', label: '后端'}, 62 {value: 'chat', label: '数据'}, 63 {value: 'user', label: 'AI'}, 64 {value: 'us2er', label: '随笔'}, 65]); 66 67const tabList = ref([ 68 { 69 label: '关注', 70 value: '1', 71 }, 72 { 73 label: 'Css', 74 value: '2', 75 }, 76 { 77 label: 'Javascript', 78 value: '3', 79 }, 80 { 81 label: 'Monnrepo', 82 value: '4', 83 }, 84 { 85 label: 'Guide', 86 value: '5', 87 }, 88 { 89 label: 'Tavascript', 90 value: '6', 91 }, 92 { 93 label: 'Uniapp', 94 value: '7', 95 }, 96 { 97 label: 'Vitepress', 98 value: '8', 99 }, 100 { 101 label: 'Vue', 102 value: '9', 103 }, 104 { 105 label: 'V-ui-pro', 106 value: '10', 107 }, 108 { 109 label: '体育', 110 value: '11', 111 }, 112 { 113 label: '财经', 114 value: '12', 115 }, 116 { 117 label: '国际', 118 value: '13', 119 }, 120 { 121 label: '时尚', 122 value: '14', 123 }, 124 { 125 label: '房产', 126 value: '15', 127 }, 128]) 129 130const loading = ref(true); 131 132const rowCols = [{size: '163.5px', borderRadius: '12px'}]; 133 134const currentValue = ref('1'); 135 136const onChange = (value: any, lebal: string) => { 137 currentValue.value = value; 138 console.log(`change to ${value}`); 139}; 140</script> 141 142<style lang="less" scoped> 143.mo { 144 --td-drawer-width: 420px; 145} 146 147.search { 148 width: 100%; 149 border-radius: 999px; 150 overflow: hidden; 151} 152 153.search :deep(.arco-input-wrapper), 154.search :deep(.arco-input-group-wrapper) { 155 border-radius: 999px !important; 156 background-color: #fff !important; 157 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); 158} 159 160.blog-card { 161 padding: 1rem; 162 background-color: white; 163 border-radius: .2rem; 164 margin-bottom: .5rem; 165} 166</style> 167

方案2-Swiper

vue
1<template> 2 <div class="mo" style="color: black;"> 3 <Swiper v-model:current="current" :autoplay="false" @click="handleClick" @change="handleChange"> 4 <SwiperItem style="height: 100vh"> 5 <div class="header" 6 style="opacity: 1;position: fixed; height: 6rem;overflow: hidden;top: 0;width: 100%;display: flex;flex-direction: column"> 7 <Navbar :fixed="false"> 8 <template #left> 9 <Search :placeholder="currentValue" shape="round"/> 10 </template> 11 <template #right> 12 <icon-home/> 13 </template> 14 </Navbar> 15 <Tabs :value="currentValue" size="medium" :space-evenly="false" :list="tabList" @change="onChange"> 16 </Tabs> 17 </div> 18 <div class="content" 19 style="margin: 6.1rem 0 4rem 0;height: calc(100vh - 6.1rem - 4rem);overflow-y: scroll"> 20 <div class="blog-card" v-for="blog in 10" :key="blog" @click="toPostAction"> 21 <div style="width: 100%;display: flex;gap:1rem;align-items: center"> 22 <Skeleton style="flex: 1" theme="paragraph" :row-col="rowCols" :loading="loading"></Skeleton> 23 <Skeleton theme="paragraph" :loading="loading" style="flex: 1;height: 100%"></Skeleton> 24 </div> 25 </div> 26 </div> 27 <div class="footer" style="opacity: 1;position: fixed;bottom: 0;width: 100%;height: 4rem;"> 28 <TabBar v-model="value" theme="tag" :split="false"> 29 <TabBarItem v-for="item in list" :key="item.value" :value="item.value"> 30 {{ item.label }} 31 </TabBarItem> 32 </TabBar> 33 </div> 34 </SwiperItem> 35 <SwiperItem style="height: 100vh"> 36 <Navbar title="西魏陶渊明" fixed left-arrow @left-click="goHome"/> 37 </SwiperItem> 38 <SwiperItem style="height: 100vh"> 39 <h1>H3</h1> 40 </SwiperItem> 41 </Swiper> 42 </div> 43</template> 44 45<script lang="ts" setup> 46import {TabBar, TabBarItem, Navbar, Search, Tabs, Skeleton, Drawer, Empty, Swiper, SwiperItem} from 'tdesign-mobile-vue' 47// 引入组件库的少量全局样式变量 48import 'tdesign-mobile-vue/es/style/index.css'; 49import {ref} from 'vue' 50 51const current = ref(0) 52 53const handleChange = (index: number, context: any) => { 54 console.log('基础示例,页数变化到》》》', index, context); 55}; 56 57const handleClick = (value: number) => { 58 console.log('click: ', value); 59}; 60 61const goHome = () => { 62 current.value = 0; 63 console.log('current: ', current.value) 64} 65 66const toPostAction = () => { 67 current.value = 1; 68} 69 70const value = ref('home'); 71const list = ref([ 72 {value: 'home', label: '前端'}, 73 {value: 'app', label: '后端'}, 74 {value: 'chat', label: '数据'}, 75 {value: 'user', label: 'AI'}, 76 {value: 'us2er', label: '随笔'}, 77]); 78 79const tabList = ref([ 80 { 81 label: '关注', 82 value: '1', 83 }, 84 { 85 label: 'Css', 86 value: '2', 87 }, 88 { 89 label: 'Javascript', 90 value: '3', 91 }, 92 { 93 label: 'Monnrepo', 94 value: '4', 95 }, 96 { 97 label: 'Guide', 98 value: '5', 99 }, 100 { 101 label: 'Tavascript', 102 value: '6', 103 }, 104 { 105 label: 'Uniapp', 106 value: '7', 107 }, 108 { 109 label: 'Vitepress', 110 value: '8', 111 }, 112 { 113 label: 'Vue', 114 value: '9', 115 }, 116 { 117 label: 'V-ui-pro', 118 value: '10', 119 }, 120 { 121 label: '体育', 122 value: '11', 123 }, 124 { 125 label: '财经', 126 value: '12', 127 }, 128 { 129 label: '国际', 130 value: '13', 131 }, 132 { 133 label: '时尚', 134 value: '14', 135 }, 136 { 137 label: '房产', 138 value: '15', 139 }, 140]) 141 142const loading = ref(true); 143 144const rowCols = [{size: '163.5px', borderRadius: '12px'}]; 145 146const currentValue = ref('1'); 147 148const onChange = (value: any, lebal: string) => { 149 currentValue.value = value; 150 console.log(`change to ${value}`); 151}; 152</script> 153 154<style lang="less" scoped> 155.mo { 156 --td-drawer-width: 420px; 157} 158 159.search { 160 width: 100%; 161 border-radius: 999px; 162 overflow: hidden; 163} 164 165.search :deep(.arco-input-wrapper), 166.search :deep(.arco-input-group-wrapper) { 167 border-radius: 999px !important; 168 background-color: #fff !important; 169 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); 170} 171 172.blog-card { 173 padding: 1rem; 174 background-color: white; 175 border-radius: .2rem; 176 margin-bottom: .5rem; 177} 178</style> 179