vue入门,完成一个简单的应用程序
-
- 创建工程
- 添加路由
- 路径别名
- 开发静态页面
- axios封装
- 跳转详情页
- 开发商品详情页
-
-
- 第一部分(数据的获取)
- 第二部分(制作轮播图)
- 渲染SKU模块
-
- SKU他来了动态功能:smile: :stuck_out_tongue_winking_eye::sparkling_heart:
-
-
- SKU显示和隐藏模块
- 选择产品规格
- 动态渲染尺寸和价格
-
- 开发登录页面
-
-
- 登录引导页开发
- 开发登录页
- 开发注册页
-
- 开发订单模块
-
-
- 实现订单静态页面
- 结果页开发
-
- 环境部署
-
-
- vue打包
-
- 终于 更新完成!
-
-
-
- 除了不写静态页面,我愿意称之为最保姆级的指导
-
-
本项目通过实现得物APP 用户登录/注册、商品列表、商品详情页、商品订单及支付功能,最终包装项目,完成完整的项目开发。 通过这个项目,我们可以学到的是:
- 如何建设项目,包括如何引用项目所需的基本包,如何规范项目
- 路由的配置
- 开发公共组件
- 使用axios调用后端接口
- 寻找和使用第三方库
- 包装、发布、环境部署 本项目的功能主要包括三个部分 1.APP注册和登录帐户 2.浏览商品列表和浏览商品细节 3.购买和支付商品
新用户进入APP可在初始页面中选择用户注册按钮进行注册页面,并使用手机号码进行注册
老用户进入APP点击用户登录后—>登录页面—>输入帐号密码 登录成功后,可以进入商品列表页面浏览商品 点击商品列表中的商品,输入商品详细信息页面查看 商品详情
进入商品详细信息页面,点击详细信息页面下方的立即购买,弹出商品尺寸选择框,进入订单确认页面,点击提交订单 即可付钱
付款后,您将跳转到付款成功和付款失败页面
创建工程
在vscode 中启动项目
- 打开项目 在terminal(Mac)或者CMD(Windows)项目创建后,可以直接创建vscode(注意:此时尚未实施npm install、npm run dev)
- 打开终端
- 命令在终端执行 执行依赖下载命令和启动项目命令 安装依赖 进入项目根目录
cd dewu-web 下载基础依赖于本地
每次添加新的依赖或拉动其他代码后,执行以下命令
npm install 或者 yarn
启动工程
npm run dev 或者yarn dev
添加路由
安装路由 脚手架vite 默认不安装router是的,我们需要自己安装,在项目根目录下 执行
npm install vue-router@next 或者yarn add vue-router@next
路由配置
- 创建路由文件 在src 目录下新建router文件夹 并加入index.js文件
// src/router/index.js import {
createRouter, createWebHistory } from "vue-router"; const routes = [ // 待添加路由 ]; const router = createRouter({
history: createWebHistory(), routes }); export
default router
;
- 加载路由 在main.js文件引入路由
// main.js
import {
createApp } from "vue";
import App from "./App.vue";
import router from "./router/index";
createApp(App).use(router).mount("#app");
路径别名
开发中我们其实会经常遇到引入的文件路径很深,或者文件名很长的情况,例如下面的路径
import Home from “…/…/components/nav/Index.vue”;
这时候我们希望 有一种类似于代码自动提示的东西,帮助我们自动引入路径,这种功能是有的,但是需要手动配置
- 配置路径别名 路径别名可以让我们告别…/操作 在根目录下的vite.config.js文件中添加如下代码
import {
defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
// 不要忘记引入path库
import path from "path";
// https://vitejs.dev/config/
export default defineConfig({
resolve: {
// 路径别名选项
alias: [
{
find: "@", // 当在你的路径中找到@ 就用下面replacement路径替换
replacement: path.resolve(__dirname, "src") // 拼接根路径
}
]
},
plugins: [vue()]
});
重新启动项目后,文章开头的路径可以这样引入
import Home from “@/components/nav/Index.vue”;
到这里我们其实没有实现路径的自动提示功能 2. 配置路径的自动提示 在根目录下面新建jsconfig.json 填入下面的代码
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@/*": ["src/*"] // 匹配src目录下的所有目录
}
},
"exclude": ["node_modules", "dist"]
}
这样子我们重启vscode以后,再去尝试,引入路径,会实现代码的自动提示功能 每次引入文件的时候,都要以@开头 到这里其实 路径别名的设置和使用已经完成了
静态页面的开发
- 新建目录 需要新建如下目录结构所示的目录 在index.vue添加基础的代码
src
|__pages
|__products
|__index.vue
在index.vue添加基础的代码
<template>商品列表</template>
<script setup></script>
<style scoped></style>
添加页面到路由 在src/router/index.js 文件下 添加路由到路由列表
import {
createRouter, createWebHistory } from "vue-router";
const routes = [
{
path: "/products",
name: "products",
alias: "/",
component: () => import("@/pages/products/index.vue")
}
];
const router = createRouter({
history: createWebHistory(),
routes
});
export default router;
alias是路由别名,相当于给路由起个外号,如下两个方式否可以访问products页面
http://localhost:3000/products http://localhost:3000/
这时候其实是访问不到products 页面的,因为没有添加router-view 在App.vue中添加router-view标签,来显示对应的路由组件
<template>
<!-- 添加router-view -->
<router-view />
</template>
<script setup></script>
<style> body {
/* 去除body的默认margin */ margin: 0; } #app {
font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; /* 删除margin-top */ } </style>
既然可以 配置好了,那么就可以开发静态页面了
注意: 在这里其实商品列表的商品只需要开发一个商品小格子即可,其他的商品在后面的章节中,可以根据从后端请求来得数据进行循环渲染。
这是目前所要建的文件
axios封装
Axios官方的解释就是:Axios是一个基于promise的HTTP 库,可以用在浏览器的node.js中
- 安装Axios 在终端输入下面的命令
npm install axios@next 或者yarn add axios@next @next可以保证安装的依赖是最新的版本
- 封装接口调用函数
axios支持基础的get、post请求,如
import axios from "axios";
// get请求
const res = await axios.get(url, {
// 参数对象
});
// post请求
const res = await axios.post(url, {
// 参数对象
});
但是这种调用的方式不够通用,所以在项目中,我们会将请求封装成一个方法来统一调用 在src目录下新建Utils文件夹,并加入http.js文件 在文件中加入如下的代码
import axios from "axios";
axios.defaults.baseURL = import.meta.env.VITE_BASE_URL;
//这段代码的意思就是从项目根目录中的.env文件中获取VITE_BASE_URL字段的值,这个字段要以VITE_开头,否则无法识别
//.env文件用于配置通用字段,方便以后同意更改,在目录下新建.env文件要
//>VITE_BASE_URL=https://www.fastmock.site/mock/c3af16c01eaad121c58feccb492a088c/f8
axios.defaults.timeout = 5000; // 请求过期时间5s
const requests = async ({
url,
method = "get", // 请求方法 get、post 默认为get
params = {
}, // get请求参数
data = {
} // post请求参数
} = {
}) => {
method = method.toLocaleLowerCase();
const res = await axios.request({
method, url, params, data });
return res.data;
};
export default requests;
- 调用接口 axios封装好以后,接下来就可以调用接口来获取商品的列表了 为了可以让项目更加的整洁,我们需要将请求接口的函数统一管理起来 在src目录下新建api文件夹,该文件夹就是用来统一管理api的,又因为我们的接口可能有很多种,比如用户。商品。登录等。所以每一个.js文件就是对接口的一种归类 比如我们要调用获取商品列表的接口,所以这个调用接口的办法应该放在product.js文件内 新建product.js文件,并键入如下的代码
// /src/api/product.js
import requests from "@/utils/http";
async function queryProducts({
url } = {
}) {
const result = await requests({
url: url,
method: "GET"
});
return result && result.data;
}
export {
queryProducts };
最后只需要在.vue文件内调用queryproductsj就可以获取到数据了
// src/pages/product/index.vue
<script setup>
import {
onMounted } from "@vue/runtime-core";
import {
queryProducts } from "@/api/product";
onMounted(async () => {
const res = await queryProducts({
url: "/get/products" });
console.log(res);
});
</script>
如果不出意外的好,就可以在控制台看到打印的数据了,要是没有的话,要好好检查一下代码哦
在axios封装的时候,做一些更具体的说明,真的是 超级详细哦
- 安装axios的时候,使用这个命令yarn add axios@next
- 封装 axios 在src目录下新建utils目录,并在该目录下新建http.js文件,完成axios 的封装装,封装http的baseUrl为VITE_BASE_URL=https://www.fastmock.site/mock/c3af16c01eaad121c58feccb492a088c/f8 // 该链接在根目录下新建.env文件,并将该链接黏贴进去
- 实现商品api 。 在src目录下新建api目录,在改目录下新建product.js文件。在该文件中写请求商品的API
- 调用api 在/src/products/index.vue文件中使用请求商品的api实现数据的请求
- 使用api 数据替换死数据、这样我们就可以用从接口请求过来的数据去替换之前在data.js中的数据来实现页面的渲染。
跳转详情页
根据下面的目录结构,新建商品的详情页面
- 注册路由 在src/router/index.js文件夹里面注册详情页面的路由
const routes = [
{
path: "/products",
name: "products",
alias: "/",
component: () => import("@/pages/products/index.vue")
},
// 注册详情页路由
{
path: "/product-detail",
name: "product-detail",
component: () => import("@/pages/product-detail/index.vue")
}
];
- 跳转详情页 在列表页面添加跳转方法,点击列表中的每个格子,跳转到详情页
<script setup>
import {
onMounted, ref } from "vue";
import {
queryProducts } from "@/api/product";
import {
useRouter } from "vue-router";
const products = ref([]);
const router = useRouter();
onMounted(async () => {
products.value = await queryProducts({
url: "/get/products" });
});
function getImgUrl(imgUrl) {
return imgUrl.split(";")[0];
}
function goDetail(id) {
router.push({
path: "/product-detail", query: {
productId: id } });
}
</script>
详细的步骤
- 添加商品详情页 。 在src/pages目录下新建product-detail目录,并在该目录下新建Index.vue填充基础的代码
<template>商品详情页面</template> <script setup></script> <style lang="scss" scoped></style>
- 注册商品详情页路由 在router/index.js 文件中的路由列表中添加商品详情页的路由
- 页面跳转。 在商品 列表中添加点击事件,保证点击每一个格子后可以跳转到商品的详情页,跳转商品详情页的时候,需要传递参数,参数为商品id,可以命名为productId
商品详情页的开发
第一部分(数据的获取)
当页面跳转到详情页的时候,首先要做的就是根据商品的id 获取数据 之前我们使用路由,将商品的Id传递到本页面,那么在商品详情页面,就需要用路由去获取商品的id,然后用商品的id去查询商品的详情的信息
- 获取商品的id 商品id是通过useRouter()函数 通过参数的形式传递过来的,如果要获取参数,就要用useRoute()函数
<script setup>
import {
{
onMounted}} from "vue";
import {
{
useRoute}} from "vue-router";
const route = useRoute();
onMounted(async()=>{
// 这里的productId要与router.push(path:"",query:{productId:xxx})中的productId一致
const {
productId}=route.query;
console.log(productId);
});
</script>
-
根据商品id 查询商品 (1)写查询函数 在product.js文件中写查询商品详情的函数
async function getPorduct({ id = "" }) { const res = await requests({ url: "/product/get", params: { id } }); return res && res.data; } // 不要忘记导出哦 export { queryProducts, getPorduct };- @description 获取商品详情
- @param {*} productId 商品id
- @returns {} 商品对象
(2)调用查询函数 在生活详情页调用刚写好的查询函数
<script setup>
import {
onMounted } from "@vue/runtime-core";
import {
useRoute } from "vue-router";
import {
ref } from "vue";
import {
getPorduct } from "@/api/product";
const route = useRoute();
// 定义商品对象
const product = ref({
});
onMounted(async () => {
const {
productId } = route.query;
// 调用查询函数,并赋值
product.value = await getPorduct({
id: productId });
});
</script>
此时我们就已经得到了一个商品对象,接下来只需要将得到的数据渲染在页面中即可,除了商品详情之外,其他的两个接口也是需要自己写查询函数,并且调用,获取数据,原理其实都是差不多的,可以参考查询商品的调用的方式
详细的教程:
- 完成接口的书写,在product.js文件中 完成下面两个接口的书写
- 调用接口渲染页面 在商品详情页面调用写好的函数,获取数据,并渲染页面
第二部分(轮播图的制作)
轮播图可以使用element-ui的carousel(走马灯)组件来实现
- 安装element-ui 在项目根目录下执行下面的命令
npm install element-plus或者yarn add element-plus
安装完毕以后,需要全局引入element-ui组件
- 全局引入 在main.js文件中引入element-ui的组件库以及样式
import {
createApp } from "vue";
import App from "./App.vue";
import router from "./router/index";
// 引入组件库
import ElementPlus from "element-plus";
// 引入样式
import "element-plus/lib/theme-chalk/index.css";
// 使用组件库
createApp(App).use(router).use(ElementPlus).mount("#app");
经过以上的操作,就可以在任何页面中使用element-ui组件了 3. 初识 element-ui 这里可以参考官网,毕竟官网才是最权威的 element-ui官网 图一主要的内容就是一些初始化及个性的配置,这一点我们暂时是不需要去关注的,因为到目前为止,我发已经做好初始的配置,我们的重点是下面 点开一个组件,可以看见文档中有组件的基本的用法,以及对应用法的基本的示例,在最下面对应属性的说明 4. 使用Carousel(走马灯)组件 在左侧栏里找到carousel(走马灯)组件,并点开“基础用法”下面的显示代码,复制里面的组件代码
<el-carousel height="150px">
<el-carousel-item v-for="item in 4" :key="item">
<h3 class="small">{
{
item }}</h3>
</el-carousel-item>
</el-carousel>
接下来将页面拉到下方,根据如下图所示的属性表进行修改 首先将走马灯的高度修改的跟设计稿的高度是一样的,这里可以用height属性 然后将走马灯的内容进行替换
<!-- 将h3标签修改 -->
<h3 class="small">{
{ item }}</h3>
<!-- 替换为img标签,因为我们的走马灯现实的是图片 -->
<img src="" />
最后将走马灯中的v-for循环的数据改成接口中获得的数据 接口获取到的product中的productImages属性就是轮播图的图片数据,但是因为这个图片数据是字符串,并且每个图片地址之间用分号(;)隔开,所以需要处理一下
const productImages = computed(
() =>
(product.value.productImages && product.value.productImages.split(";")) ||
[]
);
另外我们还需要加一个属性就是indicator-position(指示器的位置)
<el-carousel height="175px" indicator-position="outside"> </el-carousel>
渲染SKU模块
这里要写的其实是这个页面
- 静态页面的书写,这里就不做赘述,这个大家可以自己动手去试试,虽然有点麻烦,但是很简单的,不要怕麻烦,多去尝试 由于这个项目是比较大的,所以这个模块的静态页面最好是写成一个组件。 因为这个组件是只有在详情页面才会使用的,所以写在product-detail目录下,新建一个sku.vue文件 在商品的详情页,引入sku组件,并在页面中添加
<!-- index.vue -->
<template>
<!-- 省略无关代码 -->
<sku />
</template>
<script setup>
// 引入sku组件
import sku from "./components/sku.vue";
</script>
<style lang="scss" scoped></style>
- 完成接口函数 这个函数的接口是: 在product.js文件中完成接口函数的书写
// 省略无关代码
/** * @description 获取商品SKU * @returns {} */
async function getProductSKU() {
const res = await requests({
url: "/product/sku" });
return res && res.data;
}
// 导出
export {
getProductSKU };
- sku模块的渲染 在sku.vue中调用接口函数,获取到数据,渲染在页面中 我们得到的数据只能渲染页面中的每个小格子和顶部的图片,顶部的价格以及结算按钮的价格是根据用户点击后的结果来渲染的
<!-- 省略无关代码 --> <!-- 顶部商品图片 --> <img :src="sku.productImage" class="img" /> <!-- 商品尺寸、价格列表 --> <li v-for="(product, index) in sku.products" :key="product.id"> <div class="item"> <span class="size">{ { product.size }}</span> <span class="price">¥{ { product.price }}<