本文作者系360奇舞团前端开发工程师
亲爱的小伙伴们,《奇舞精选》正在参加掘金年度人气创作者评选活动。请您动动发财的小手,帮《奇舞精选》投上宝贵的两票。我们也会再接再厉创作出更加优质的技术文章!
Vant组件
简介
Vant 是有赞前端团队开源的一套轻量、可靠的移动端组件库。
安装
通过 npm 安装
在现有项目中使用 Vant 时,可以通过 npm
进行安装:
bash
# Vue3 项目,安装最新版 Vant
npm i vant
引入Vant组件
基础用法:
例:
javascript
import { createApp } from 'vue'
import App from './App.vue'
import Vant from 'vant'
import 'vant/lib/index.css'
const app =createApp(App)
app.use(Vant)
app.mount('#app')
自动按需引入请参考vant官方指导意见:vant-contrib.gitee.io/vant/#/zh-C...
Vue Router组件
安装
在现有项目中使用Vue Router 时,可以通过 npm
进行安装:
bash
npm install vue-router@4
引入Vue Router组件
1、在src目录下创建一个文件夹views,然后在内创建两个vue页面,分别为AppHome和AppUser,用作路由跳转;
2、在src目录下创建一个文件夹router,然后在文件夹内创建一个router.js 文件。然后在router.js文件内添加如下代码:
js
import { createRouter, createWebHistory } from 'vue-router'
import AppHome from '@/views/AppHome'
import AppUser from '@/views/AppUser'
import AppClassify from '@/views/AppClassify'
const routes =[
{
path: '/',
component: AppHome
},
{
path: '/appClassify',
name: 'appClassify',
component: AppClassify
},
{
path:'/appUser',
name:'appUser',
component: AppUser
}
]
const router =createRouter({
history:createWebHistory(),
routes
})
export default router
3、在main.js文件中引入路由,这样就可以在项目中使用Vue Router组件
js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router/router'
const app =createApp(App)
app.use(router)
app.mount('#app')
axios http库
安装
在现有项目中使用 axios 时,可以通过 npm
进行安装:
bash
npm install axios
axios 网络请求封装
1、在src目录下创建一个文件夹utils,然后在文件夹内创建一个request.js 文件。
2、在request.js 文件内创建基础API接口,如下:
js
import axios from 'axios'
const request=axios.create({
baseURL: 'https://www.example.com'
})
export default request;
3、在src目录下再次创建一个文件夹API,然后在文件内创建一个articleListApi.js文件,实现列表数据请求接口,用于后续填充列表数据。
js
import request from '@/utils/request.js'
export const getArticleListApi = function(page,limit){
return request.get('/articles',{
params: {
_page: page,
_limit: limit
}
})
}
使用Vant自定义组件
van-tabbar添加
在App.vue 文件内添加van-tabbar组件,并搭配路由自动切换标签。App.vue 实现如下:
vue
<template>
<router-view/>
<div id="home-container">
<!--实现tabbar功能,并搭配路由自动切换标签-->
<van-tabbar route v-model="active" active-color="#1989fa" inactive-color="#000">
<van-tabbar-item to="/" icon="home-o">首页</van-tabbar-item>
<van-tabbar-item to="/appUser" icon="user-o">我的</van-tabbar-item>
</van-tabbar>
</div>
</template>
<script>
import { ref } from "vue";
export default {
name: 'App',
setup() {
const active = ref(0);
return { active };
},
}
</script>
<style lang="less" scoped>
</style>
创建图文混排单元格组件
在src目录下的components文件夹内创建图文混排单元格组件AppArticleInfo.vue。实现如下:
vue
<template>
<div>
<van-cell>
<!--标题区域插槽-->
<template #title>
<div class="title-box">
<!--标题-->
<span>{{ title }}</span>
<!--单张图片-->
<img :src="cover.images[0]" v-if="cover.type === 1" alt="" class="thumb" />
</div>
<!--三张图片-->
<div class="thumb-box" v-if="cover.type === 3">
<img
:src="item"
v-for="(item, i) in cover.images"
:key="i"
alt=""
class="thumb"
/>
</div>
</template>
<!--label 区域的插槽-->
<template #label>
<div class="label-box">
<span>
作者 {{ author }} {{ commCount }} 评论 发布时间
{{ time }}</span
>
<!--关闭按钮-->
<van-icon name="cross" />
</div>
</template>
</van-cell>
</div>
</template>
<script setup>
//自定义属性
defineProps({
title: {
//文章标题
type: String,
default: "",
},
author: {
//作者
type: String,
default: "",
},
commCount: {
//评论数
type: parseInt,
default: 0,
},
time: {
//发布时间
type: String,
default: "",
},
cover: {
//封面的信息对象
type: Object,
default: function () {
return { type: 0 };
},
},
});
</script>
<style lang="less" scoped>
.label-box {
display: flex;
justify-content: space-between;
align-items: center;
}
.thumb {
width: 113px;
height: 70px;
background-color: #f8f8f8;
object-fit: cover;
}
.title-box {
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.thumb-box {
display: flex;
justify-content: space-between;
}
</style>
下拉刷新及上拉加载更多
在AppHome.vue 页面内引入图文混排组件AppArticleInfo.vue,并实现下拉刷新和上拉加载更多
vue
<template>
<div class="home-container">
<van-nav-bar title="首页" :fixed="true"></van-nav-bar>
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
<van-list
v-model="loading"
:finished="finished"
finished-text="没有更多了"
@load="loadMore"
>
<app-article-info
v-for="item in state.list"
:key="item.id"
:title="item.title"
:author="item.aut_name"
:time="item.pubdate"
:comm-count="item.comm_count"
:cover="item.cover"
></app-article-info>
</van-list>
</van-pull-refresh>
</div>
</template>
<script>
import { getArticleListApi } from "@/api/articleListApi.js";
import AppArticleInfo from "@/components/AppArticleInfo.vue";
import { ref, onMounted, reactive } from "vue";
export default {
name: "AppHome",
components: {
AppArticleInfo,
},
setup() {
const page = ref(1);
const limit = ref(10);
const refreshing = ref(false);
const loading = ref(true);
const finished = ref(false);
const state = reactive({
list: [],
});
onMounted(() => {
initArticleList(page.value, limit.value);
});
async function initArticleList() {
const { data: res } = await getArticleListApi(page.value, limit.value);
if (refreshing.value === true) {
refreshing.value = false;
state.list = [];
state.list = res;
loading.value = false;
console.log("refreshing", refreshing.value, finished.value);
} else {
state.list = [...state.list, ...res];
console.log("loadMore",loading.value);
if (res.length === 0) {
finished.value = true;
}
loading.value = false;
}
console.log("返回数据:", state.list, page.value);
}
function loadMore() {
page.value++;
initArticleList();
console.log("上拉", page.value);
}
function onRefresh() {
refreshing.value = true;
finished.value = false;
page.value = 1;
initArticleList();
console.log("下拉", page.value);
// console.log("返回数据:", state.list, page.value, loading.value, finished.value);
}
return {
refreshing,
loading,
finished,
page,
limit,
state,
initArticleList,
loadMore,
onRefresh,
};
},
};
</script>
<style lang="less" scoped>
.home-container {
padding: 46px 0 50px 0;
}
.van-nav-bar {
background-color: #1989fa;
}
/deep/.van-nav-bar__title {
color: #ffffff;
}
</style>
总结
本文是基于Vue3和Vant移动端组件库的一些常规组件的实际使用举例,只是对一个基础的功能的实践,更多实际应用组件功能请结合业务参考Vant。