Vue.js 是一款流行的 JavaScript 前端框架,它具有轻量级、易用性和高可定制性等特点,能够快速构建现代化的 Web 应用。Vant-UI 是基于 Vue.js 的一套移动端 UI 组件库,拥有丰富的 UI 组件和良好的视觉效果,是构建 Vue 移动端应用的不二之选。本篇文章将介绍如何利用 Vue.js + vant-ui 构建基于 Vue 的单页应用,并提供详细的学习和指导意义。
什么是单页应用
单页应用(SPA)是一种基于 Web 技术的应用程序模型,在一个 Web 页面内实现多个组件或模块的切换和交互,而不是每次请求都加载新的 HTML 页面。SPA 的优点在于降低网络传输压力、提高用户体验和性能优化等方面,适合构建富交互的 Web 应用。
Vue.js 简介
Vue.js 是一款渐进式的 JavaScript 前端框架,它通过模板和组件化的方式实现数据的双向绑定和交互性能的提高。Vue.js 拥有灵活的组件系统、高效的渲染引擎和强大的路由功能等特点。Vue.js 还提供了完善的生命周期钩子、自定义指令和过滤器等功能,方便开发者快速构建 Web 应用。
vant-ui 简介
Vant-UI 是一款基于 Vue.js 的移动端 UI 组件库,其中包括丰富的 UI 组件和良好的视觉效果。Vant-UI 提供了组件化的方式实现移动端页面的构建,同时支持按需加载和体积优化,方便开发者快速构建移动端应用。
项目架构
下面是基于 Vue.js + vant-ui 的单页应用的项目架构:
- src - assets // 存放项目的静态资源文件 - components // 存放项目的组件文件 - router // 存放项目的路由配置文件 - store // 存放项目的 Vuex 状态管理文件 - views // 存放项目的页面文件 App.vue // 项目主页面 main.js // 项目入口文件
实现方式
在上面的项目架构中,需要使用 main.js 配置 Vue Router 和 Vuex,以及引入 vant-ui 组件库。这里以一个简单的登录注册页面为例,介绍如何利用 Vue.js + vant-ui 构建基于 Vue 的单页应用。
安装 vant-ui
要使用 vant-ui,需要先安装它:
npm i vant -S
引入 vant-ui
在 main.js 中引入 vant-ui:
import Vue from 'vue'; import Vant from 'vant'; import 'vant/lib/index.css'; Vue.use(Vant);
配置路由
在 router 目录下,创建 index.js 文件,并配置路由:
// javascriptcn.com 代码示例 import Vue from 'vue'; import VueRouter from 'vue-router'; import Login from '../views/Login.vue'; import Register from '../views/Register.vue'; Vue.use(VueRouter); const routes = [ { path: '/', redirect: '/login' }, { path: '/login', component: Login }, { path: '/register', component: Register } ]; const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes }); export default router;
这里的路由模式使用了 history 模式,需要在后端服务器配置 URL 重写,以支持 HTML5 History API。
配置 Vuex
在 store 目录下,创建 index.js 文件,并配置 Vuex:
// javascriptcn.com 代码示例 import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); export default new Vuex.Store({ state: { user: null }, mutations: { setUser(state, user) { state.user = user; } }, actions: { setUser({ commit }, user) { commit('setUser', user); } }, modules: {} });
这里的 Vuex Store 只包含一个通用的用户信息 state,同时提供了 setUser 的 mutation 和 action。
编写组件
在 components 目录下,创建一个公用的 Header 组件:
// javascriptcn.com 代码示例 <template> <van-nav-bar v-if="showNavBar" :title="title" :fixed="fixed" /> </template> <script> export default { name: 'Header', props: { title: String, showNavBar: { type: Boolean, default: true }, fixed: { type: Boolean, default: true } } }; </script>
在 views 目录下,创建 Login.vue 页面:
// javascriptcn.com 代码示例 <template> <div class="login"> <Header title="登录" /> <van-cell-group> <van-field v-model="username" label="用户名" placeholder="请输入用户名" /> <van-field v-model="password" label="密码" type="password" placeholder="请输入密码" /> </van-cell-group> <van-button class="submit-btn" type="info" @click="login">登录</van-button> </div> </template> <script> import Header from '@/components/Header.vue'; import { Toast } from 'vant'; export default { name: 'Login', components: { Header }, data() { return { username: '', password: '' }; }, methods: { login() { if (!this.username || !this.password) { Toast('请输入用户名和密码'); } else { this.$store.dispatch('setUser', { username: this.username, password: this.password }); this.$router.push('/home'); } } } }; </script> <style lang="scss" scoped> .login { padding-top: 65px; .submit-btn { margin: 20px; } } </style>
在 views 目录下,创建 Register.vue 页面:
// javascriptcn.com 代码示例 <template> <div class="register"> <Header title="注册" /> <van-cell-group> <van-field v-model="username" label="用户名" placeholder="请输入用户名" /> <van-field v-model="password" label="密码" type="password" placeholder="请输入密码" /> <van-field v-model="confirmPassword" label="确认密码" type="password" placeholder="请再次输入密码" /> </van-cell-group> <van-button class="submit-btn" type="danger" @click="register">注册</van-button> </div> </template> <script> import Header from '@/components/Header.vue'; import { Toast } from 'vant'; export default { name: 'Register', components: { Header }, data() { return { username: '', password: '', confirmPassword: '' }; }, methods: { register() { if (!this.username || !this.password || !this.confirmPassword) { Toast('请输入用户名和密码'); } else if (this.password !== this.confirmPassword) { Toast('两次输入的密码不一致'); } else { this.$store.dispatch('setUser', { username: this.username, password: this.password }); this.$router.push('/home'); } } } }; </script> <style lang="scss" scoped> .register { padding-top: 65px; .submit-btn { margin: 20px; } } </style>
在 views 目录下,创建 Home.vue 页面:
// javascriptcn.com 代码示例 <template> <div class="home"> <Header title="首页" :showNavBar="false" /> <div class="greeting">欢迎回来,{{ $store.state.user.username }}!</div> <van-button class="logout-btn" type="warning" @click="logout">退出登录</van-button> </div> </template> <script> import Header from '@/components/Header.vue'; export default { name: 'Home', components: { Header }, methods: { logout() { this.$store.dispatch('setUser', null); this.$router.push('/login'); } } }; </script> <style lang="scss" scoped> .home { padding-top: 65px; .greeting { margin-top: 20px; margin-left: 20px; font-size: 24px; } .logout-btn { margin: 20px; } } </style>
安装其他依赖
除了 vant-ui 之外,还需要安装以下依赖:
npm i vue-router vuex axios -S
这里 axios 是用来模拟数据请求的。
编写模拟数据接口
在 src 目录下,创建 api.js 文件,用来模拟数据接口:
// javascriptcn.com 代码示例 import axios from 'axios'; export const login = params => { return axios.post('/api/login', params); }; export const register = params => { return axios.post('/api/register', params); }; export const getUserInfo = () => { return axios.get('/api/userinfo'); }; export const logout = () => { return axios.post('/api/logout'); };
这里的接口都会返回 Promise 对象。
配置开发环境
在根目录下创建一个 vue.config.js 文件,配置开发环境:
// javascriptcn.com 代码示例 module.exports = { devServer: { proxy: { '/api': { target: 'http://localhost:3000', ws: true, changeOrigin: true } } } };
这里的 proxy 配置表明,如果 URL 匹配以 /api 开头的请求,会被代理到本地的 3000 端口,以实现跨域请求。
启动应用
在命令行中运行以下命令,启动应用:
npm run serve
总结
利用 Vue.js + vant-ui 构建基于 Vue 的单页应用,需要以下几个步骤:
- 安装 vant-ui 和其他依赖;
- 配置路由和 Vuex;
- 引入 vant-ui 组件;
- 编写组件和模拟数据接口;
- 配置开发环境;
- 启动应用。
本篇文章详细介绍了以上每一步,并提供了示例代码,希望读者能够掌握利用 Vue.js + vant-ui 的技术。在实际项目中,还需根据实际需要进行定制和优化。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/653ed61f7d4982a6eb838a54