项目构建
一、项目构建
1.项目使用vite构建项目
你还可以通过附加的命令行选项直接指定项目名称和你想要使用的模板。例如,要构建一个 Vite + Vue 项目,运行
vite中文网(开始 | Vite 官方中文文档)
# npm 6.x
npm create vite@latest my-vue-app --template vue
# npm 7+, extra double-dash is needed:
npm create vite@latest my-vue-app -- --template vue
# yarn
yarn create vite my-vue-app --template vue
# pnpm
pnpm create vite my-vue-app --template vue
2:安装路由
vue-router是基于路由和组件的
路由用户设定访问路径的,将路径和组件映射起来。
在vue-router的单页面应用中,页面的路径的改变就是组件的切换
npm install vue-router@4
3:安装vuex
vuex是状态管理库,管理复杂的数据状态。(What is Vuex? | Vuex安装 | VuexWhat is Vuex? | Vuex)
npm install vuex@next --save
4:安装vant组件
Vant 是一个轻量、可靠的移动端组件库(Vant 4 - A lightweight Vue UI library for mobile web apps.)
npm i vant
全局vant组件注册,如果是基于 vite 的项目,在 vite.config.js 文件中配置插件:
npm i unplugin-vue-components -D
import vue from '@vitejs/plugin-vue';
import Components from 'unplugin-vue-components/vite';
import { VantResolver } from 'unplugin-vue-components/resolvers';
export default {
plugins: [
vue(),
Components({
resolvers: [VantResolver()],
}),
],
};
5:安装axios
Axios 是一个基于 promise 的 HTTP 库,简单的讲就是可以发送get、post等请求。(axios中文网|axios API 中文文档 | axios)
npm install axios
登录页面
1.创建登录页面表单,表单数据通过双向绑定。
//视图层
<div class="login-container">
<van-nav-bar class="app-nav-bar" title="登录" left-arrow @click-left="onClickLeft" />
<!-- 可以使用 CellGroup 作为容器 -->
<van-form ref="loginForm" @submit="onSubmit">
<van-field v-model="user.mobile" name="mobile" icon-prefix="news" left-icon="shouji" placeholder="请输入手机号"
:rules="userFormRules.mobile" type="number" maxlength="11" />
<van-field v-model="user.code" name="code" icon-prefix="news" left-icon="yanzhengma" placeholder="请输入验证码"
:rules="userFormRules.code" type="number" maxlength="6">
<template #button>
<van-count-down v-if="isCountDownShow" @finish="isCountDownShow = false" :time="time" format="ss s" />
<van-button v-else @click="onSendSms" native-type="button" class="send-btn" size="small"
round>发送验证码</van-button>
</template>
</van-field>
<div class="login-btn-wrap">
<van-button type="info" native-type="submit" block class="login-btn">登录</van-button>
</div>
</van-form>
</div>
//逻辑层
import { reactive, ref } from "vue";
const user = reactive({
mobile: "",
code: "",
});
2.axios 数据请求配置,
import axios from "axios";//引入axios
const request = axios.create({
baseURL: 'http://toutiao.itheima.net',//接口地址
timeout: 1000,
});
export default request;//导出组件
3.api请求接口配置
import request from "@/utils/index"; //
//登录请求
export const login = (data) => {
return request({
method: 'POST',//请求方法
url: '/v1_0/authorizations',
data//数据
})
}
4.vuex数据状态管理
import { createStore } from 'vuex'//导入vuex
export default createStore({
state: {
user: []
},
mutations: {
setuser(state, data) {
state.user = data
}
},
})
5.token存储
1.安装 vueuse/integrations 库
npm i @vueuse/integrations
2 再安装universal-cookie库
npm i universal-cookie
3.定义token方法
import { useCookies } from "@vueuse/integrations/useCookies";
const tokenName = "admin-token";
const cookie = useCookies();
// 1.获取token方法
export function getToken() {
return cookie.get(tokenName)
}
// 2.设置token方法
export function setToken(token) {
return cookie.set(tokenName, token)
}
// 3.移除token方法
export function removeToken() {
return cookie.remove(tokenName)
}
4.login调用方法
import { setToken } from '@/utils/storage';//存储token方法
import { login } from '@/api/user';//请求接口方法
const onSubmit = (values) => {
console.log('submit', values);//表单输入内容
login(values).then((res) => {
console.log(res.data.data);
store.commit('setuser', res.data.data)//通过vuex存储数据
setToken(res.data.data.token)//存储token
}).catch((err) => {
console.log(err);
})
};
首页页面
1.搜索框部分使用vant搜索框组件,并禁用(disabled )。点击提供路由跳转至搜索页面
<van-search disabled placeholder="请输入搜索关键词" @click="$router.push('/search')" />
2.顶部用户频道列表使用van-tab组件,提供axios请求接口用户频道消息。调用请求方法。通过v-for循环遍历渲染到页面。
<van-tabs v-model:active="active">
<van-tab v-for="item in date" key="item.id" :title="item.name">
</van-tab>
</van-tabs>
function getdate() {
getUserChannels().then((res) => {
date.value = res.data.data.channels;
})
}
getdate()
3.新闻列表。
1:通过父传子把点击的频道的id值给子组件;
<van-tab v-for="item in date" key="item.id" :title="item.name">
<channels :id="item.id"></channels>
</van-tab>
//引入子组件
import channels from '@/components/home/channels'
2:子组件通过props接受父组件传递的id值,把id赋值给arr的channel_id;timestamp为接口需要的时间戳。
const props = defineProps({
id: {
type: [String, Number, Object],
required: true,
}
})
const arr = ref({
channel_id: props.id,
timestamp: timestamp.value || Date.now()
})
3:请求新闻列表数据,调用接口。并且一直传递新的时间戳请求数据,知到数据请求结束,停止请求。
const onLoad = () => {
getArticles(arr.value).then((res) => {
date.value.push(res.data.data.results);
console.log(date.value);
loading.value = false
if (res.data.data.results.length) {
timestamp.value = res.data.data.pre_timestamp;
} else {
finished.value = true;
}
}).catch((err) => {
console.log(err);
})
}
4:通过van-list渲染数据,
<van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="onLoad">
<van-cell class="scoll" v-for="item in date">
<van-cell v-for="i in item" :to="{
name: 'detail',
params: {
id: i.art_id,
},
}">
{{ i.title }}
</van-cell>
</van-cell>
</van-list>