Vue.js 初步使用与接口请求
我听说隔壁专业的 JavaWeb 要用 Vue.js (喜),于是我来复盘一下 Vue 的简单使用。我们专业作业、课设好几个 Unity ,鲨了我吧!😥
本文将介绍 Vue.js 的基本使用,以及如何使用 axios 进行接口请求。并集成 Element UI 组件库,实现一个简单的界面。
为什么要使用框架
Vue 是一个渐进式的 JavaScript 框架,它的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。它和 React 、 Angular 并称为三大前端框架(但!我更喜欢 React,本博客基于 React)。
那么为什么要使用框架呢?
首先,框架可以帮助我们更好的组织代码,使得代码更加清晰,易于维护。其次,框架可以帮助我们更好的管理数据,使得数据的流动更加清晰,便于调试。简单来说,就是方便好写!
准备工作
前端项目严重依赖于 Node.js ,所以我们需要先安装 Node.js 。这里就不再赘述,可以参考我之前写的文章:
安装完之后,就可以开始 Vue 的旅程了!🎄
从 Vue CLI 开始
Vue CLI 是 Vue.js 官方提供的脚手架工具,可以帮助我们快速搭建项目。
让我们选择一个文件夹,我们把项目安装在这里面。在该文件夹的空白处按住 Shift 键,点击鼠标右键,选择 “在此处打开Powershell” ,打开命令行窗口。
在命令行窗口中输入以下命令:
npm install -g @vue/cli
npm 服务器在境外,请确保你有稳定可用的代理。否则可能会出现安装失败的情况。
如下图即为安装成功,(可以忽略警告):
接着,我们使用 Vue CLI 创建一个项目:
vue create [工程名,自定义] # 例如:vue create vue-demo
这里我会用 Vue2 来讲解,请选择 Vue2.(Vue3 还没学哈哈哈)。
安装中:
安装完成:
启动项目
安装完成之后,我们就可以启动项目了。用 Visual Studio Code 打开项目文件夹:
注意,必须确保你的 package.json 文件在打开后的根目录,否则按照下面的步骤操作会出现错误。
Vue 开发可能需要一些插件,这里不再赘述,可以参考:
Vue 开发必备 VSCode 插件
选择顶部菜单栏,点击 “终端” ,选择 “新终端” :
在终端中输入以下命令:
npm run serve
运行完成,在浏览器中打开 http://localhost:8080/ ,即可看到 Vue 的欢迎界面:
引入 Element UI
Element UI 是一套基于 Vue 2.0 的组件库,它由饿了么技术团队开源,它可以帮助我们快速搭建漂亮的页面。(真的好清新的页面!)
安装 Element UI
新建终端,在终端中输入以下命令:
npm i element-ui -S
按回车键,等待安装完成。
引入 Element UI
在项目的 src/main.js
文件中,引入 Element UI:
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
好了!现在我们就可以使用 Element UI 了。
Vue 项目结构
在 Vue 项目中,我们可以看到有很多文件,这些文件是干什么的呢?
node_modules文件夹
vue项目的文件依赖存放在这个文件夹。【暂时不用管】
public文件夹
存放页面图标和内部资源。
package.json文件
存放项目的依赖配置(比如引入vuex,element-UI) 【暂时不用管】
vue.config.js文件
vue 的配置文件 【暂时不用管】
yarn.lock
用来构建依赖关系树 【暂时不用管】
.gitignore
git 忽略文件 【暂时不用管】
src文件夹
存放 vue 项目的源代码。其文件夹下的各个文件(文件夹)分别为:
1. assets
:资源文件,比如存放 css,图片等资源。
2. component
:组件文件夹,用来存放 vue 的公共组件(注册于全局,在整个项目中通过关键词便可直接输出)。
3. router
:用来存放 index.js
,这个 js 用来配置路由
4. views
:用来放主体页面,虽然和组件文件夹都是 vue 文件,但 views 下的 vue 文件是可以用来充当路由 view 的。
5. main.js
:是项目的入口文件,作用是初始化 vue 实例,并引入所需要的插件。
6. app.vue
:是项目的主组件,所有页面都是在该组件下进行切换的。
src
文件夹是我们的主战场!那让我们开始吧!
修改 App.vue
入口组件用于放全局显示的组件,包含导航栏等公共组件。Vue 和原生 html 不同,Vue 创建的是单页面应用,也就是说,不需要刷新页面就可以实现页面的跳转。
在 src
文件夹下,找到 App.vue
文件,打开它,我们可以看到如下代码:
<!-- 第一部分,页面模板,书写 html 代码 -->
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>
<!-- 第二部分,页面的逻辑,书写 js 代码 -->
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
}
}
</script>
<!-- 第三部分,页面的样式,书写 css 代码 -->
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
让我们先观察 <template>
标签下的代码,我们可以看到有一个 <img>
标签,这个标签是用来放置 logo 的,我们可以将它删除,然后在 <HelloWorld>
标签下添加一段文字,如下所示:
<template>
<div id="app">
<HelloWorld msg="Welcome to Your Vue.js App"/>
<h1>这是一个测试</h1>
</div>
</template>
我们可以看到,页面上多了一段文字,这就是我们在 <template>
标签下添加的内容。
此外,我们还注意到,这里有个 <HelloWorld>
标签,这个标签是用来引入组件的,我们可以在 src
文件夹下的 components
文件夹下找到 HelloWorld.vue
文件,打开它,我们可以看到如下代码:
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
它和 App.vue
文件的结构是一样的,让我们修改其中的内容,如下所示:
<template>
<div class="hello">
<h1>我改了这里面的内容!</h1>
</div>
</template>
<script>
export default {
name: "HelloWorld",
props: {},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>
你可以看出来,我删去了原有的很多文字、超链接标签,取而代之的是一个 <h1>
标签,它的内容是 我改了这里面的内容!
。
在浏览器刷新页面后,你可以看到,页面上的内容已经发生了变化。
你可能高呼:我懂了!这就是组件的用法!我们把 HelloWorld 组件写在了别的文件中,我只要在 App.vue 文件中引入它,就可以使用它了!这给了我启发,那么我在 components
文件夹下新建一个 MyComponent.vue
文件,然后在 App.vue
文件中引入它,看看会发生什么?
<template>
<div class="hello">
<h1>我是 MyComponent 组件!</h1>
</div>
</template>
然后,我们要用 js 将这个组件导出:
<script>
export default {
name: "MyComponent",
props: {},
};
</script>
接着,我还希望给他加上一些样式,所以我在 <style>
标签中写了一些样式:
<style scoped>
.hello {
color: red;
}
</style>
我把这个类绑定到 h1
标签上,这样就可以让 h1
标签的文字变成红色了。
<template>
<div>
<h1 class="hello">我是 MyComponent 组件!</h1>
</div>
</template>
这时,你刷新页面,你会发现,啥也没变!那是因为我们还没有在 App.vue
文件中引入这个组件。
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Welcome to Your Vue.js App" />
<MyComponent />
</div>
</template>
<script>
import MyComponent from "./components/MyComponent.vue";
export default {
name: "App",
components: {
HelloWorld,
MyComponent,
},
};
</script>
接下来,我们可以划分页面的结构了。
使用 Element UI
接下来,让我们使用 Element UI 来快速搭建页面的结构。
首先,我们需要一个导航栏,因此,我到 Element UI 官网 找到了 Menu
组件。
我们看到他为我们提供了代码,我们选一种样式的代码,然后复制到 App.vue
文件中。
<el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect">
<el-menu-item index="1">处理中心</el-menu-item>
<el-submenu index="2">
<template slot="title">我的工作台</template>
<el-menu-item index="2-1">选项1</el-menu-item>
<el-menu-item index="2-2">选项2</el-menu-item>
<el-menu-item index="2-3">选项3</el-menu-item>
<el-submenu index="2-4">
<template slot="title">选项4</template>
<el-menu-item index="2-4-1">选项1</el-menu-item>
<el-menu-item index="2-4-2">选项2</el-menu-item>
<el-menu-item index="2-4-3">选项3</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="3" disabled>消息中心</el-menu-item>
<el-menu-item index="4"><a href="https://www.ele.me" target="_blank">订单管理</a></el-menu-item>
</el-menu>
现在的 App.vue
文件长这样,我删除了原来的图片和示例的组件。
<template>
<div id="app">
<el-menu
:default-active="activeIndex"
class="el-menu-demo"
mode="horizontal"
@select="handleSelect"
>
<el-menu-item index="1">处理中心</el-menu-item>
<el-submenu index="2">
<template slot="title">我的工作台</template>
<el-menu-item index="2-1">选项1</el-menu-item>
<el-menu-item index="2-2">选项2</el-menu-item>
<el-menu-item index="2-3">选项3</el-menu-item>
<el-submenu index="2-4">
<template slot="title">选项4</template>
<el-menu-item index="2-4-1">选项1</el-menu-item>
<el-menu-item index="2-4-2">选项2</el-menu-item>
<el-menu-item index="2-4-3">选项3</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="3" disabled>消息中心</el-menu-item>
<el-menu-item index="4"
><a href="https://www.ele.me" target="_blank">订单管理</a></el-menu-item
>
</el-menu>
</div>
</template>
<script>
export default {
name: "App",
components: {},
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
打开浏览器,刷新页面,我们可以看到效果了。
我们只需要修改上面代码中的中文即可改变标签内容,不需要的标签删去即可。
新的页面和路由
首先,我们要使用到 vue 的路由管理,因此,我们需要安装 vue-router
的 vue 2 版。
npm install vue-router@2
ok,让我们创建两个子页面用于展示不同的内容:
新建 views
文件夹,然后在 views
文件夹中新建 Home.vue
和 About.vue
文件。
<template>
<div>
<h1>Home</h1>
</div>
</template>
<script>
export default {
name: "Home",
};
</script>
<style scoped></style>
<template>
<div>
<h1>About</h1>
</div>
</template>
<script>
export default {
name: "About",
};
</script>
<style scoped></style>
接着,我们需要新建 router/index.js
文件夹并在其中配置路由。路由也就是我们点击菜单后,页面跳转到哪里的路径。
import Vue from "vue";
import VueRouter from "vue-router";
// 引入两个页面
import Home from "../views/home.vue"; // 😊
import About from "../views/about.vue"; // 😊
Vue.use(VueRouter);
const routes = [
// 规定页面的路径及名称
{
path: "/", // 路径
name: "Home", // 名称
component: Home, // 依赖的组件,必须和上面的 😊 处一致
},
{
path: "/about", // 路径
name: "About", // 名称
component: About, // 依赖的组件,必须和上面的 😊 处一致
},
];
const router = new VueRouter({
routes,
});
export default router;
下面,我们就可以在 App.vue
中使用路由了。router-view
是路由的占位符,当我们点击菜单时,会根据路由的配置,跳转到对应的页面。
<template>
<div id="app">
<el-menu
:default-active="activeIndex"
class="el-menu-demo"
mode="horizontal"
@select="handleSelect"
>
<el-menu-item index="1">处理中心</el-menu-item>
<el-submenu index="2">
<template slot="title">我的工作台</template>
<el-menu-item index="2-1">选项1</el-menu-item>
<el-menu-item index="2-2">选项2</el-menu-item>
<el-menu-item index="2-3">选项3</el-menu-item>
<el-submenu index="2-4">
<template slot="title">选项4</template>
<el-menu-item index="2-4-1">选项1</el-menu-item>
<el-menu-item index="2-4-2">选项2</el-menu-item>
<el-menu-item index="2-4-3">选项3</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="3" disabled>消息中心</el-menu-item>
<el-menu-item index="4"
><a href="https://www.ele.me" target="_blank">订单管理</a></el-menu-item
>
</el-menu>
<router-view />
</div>
</template>
<script>
import router from "./router/index.js"; // 😊
export default {
name: "App",
router, // 😊
};
</script>
<style>
</style>
你可能看见如下报错:
在vue.config.js文件下,加入以下代码:
lintOnSave: false // 关闭eslint校验
这个报错不管也行,它只是说代码不规范,不影响。
为了让菜单更明显,我删除了不必要的代码:
<template>
<div id="app">
<el-menu
:default-active="activeIndex"
class="el-menu-demo"
mode="horizontal"
@select="handleSelect"
>
<el-menu-item index="1">Home</el-menu-item>
<el-menu-item index="2">About</el-menu-item>
</el-menu>
<router-view />
</div>
</template>
<!-- .... -->
然后,我们用路由触发器包裹导航栏:
<template>
<div id="app">
<router-link to="/"><el-menu-item index="1">Home</el-menu-item></router-link>
<router-link to="/about"><el-menu-item index="2">About</el-menu-item></router-link>
<router-view />
</div>
</template>
<!-- .... -->
现在,我们可以点击导航栏,切换到对应的页面了。
Details
axios 的使用
axios 是一个基于 promise 的 HTTP 库,可以用来发送 HTTP 请求。
我们先安装 axios:
npm install axios
由于我不会 Spring Boot 框架,所以我用 Express 框架搭建一个简单的 Node.js 服务器,用来模拟后端接口。(见源代码的 server.js 文件),这个相当于 Spring Boot 中创建的 API 接口。
const express = require("express");
const app = express();
const port = 3001;
// 设置跨域,允许所有域名访问
app.all("*", function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Headers",
"Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild"
);
res.header("Access-Control-Allow-Methods", "PUT, POST, GET, DELETE, OPTIONS");
if (req.method == "OPTIONS") {
res.send(200);
} else {
next();
}
});
const testdata = [
{
bookName: "The Lord of the Rings",
price: 100,
author: "J.R.R. Tolkien",
publishDate: "1954-07-29",
},
{
bookName: "The Hobbit",
price: 50,
author: "J.R.R. Tolkien",
publishDate: "1937-09-21",
},
{
bookName: "Harry Potter and the Philosopher's Stone",
price: 80,
author: "J.K. Rowling",
publishDate: "1997-06-26",
},
{
bookName: "西游记",
price: 30,
author: "吴承恩",
publishDate: "1986-06-26",
},
{
bookName: "红楼梦",
price: 30,
author: "曹雪芹",
publishDate: "1986-06-26",
},
];
app.get("/books", (req, res) => {
// 发送 testdata 数组
res.send(testdata);
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});
启动服务器:
node server
服务器运行于 localhost:3001
端口,我们只要请求 localhost:3001/books
就可以获取到 testdata 数组。
好了,让我们在前端请求这个接口吧。我们需要在 Home
组件初始化时,请求这个接口,然后将数据存储到 data
中。
<script>
// 引入 axios
import axios from "axios"; // 😊
export default {
name: "Home",
data() {
return {
books: [], // 创建数据容器
};
},
mounted() {
// 请求接口
axios.get("http://localhost:3001/books").then((res) => {
this.books = res.data;
// 必须要用 this 发个文上面的数据容器
});
},
};
</script>
现在,我们需要在页面渲染 books
数组中的数据,我们可以使用列表渲染。列表渲染的语法是 v-for
,它可以遍历数组或对象,然后渲染到页面上。相当于 C 语言中的 for
循环。
<template>
<div class="home">
<!-- 列表渲染 books -->
<ul>
<li v-for="book in books" :key="book.bookName">
<!-- v-for 列表渲染 -->
<h2>{{ book.bookName }}</h2>
<p>作者:{{ book.author }}</p>
<p>价格:{{ book.price }}</p>
<p>出版日期:{{ book.publishDate }}</p>
</li>
</ul>
</div>
</template>
上述代码可以用 for
循环来做比喻,但是 v-for
会更加简洁。
for (let i = 0; i < this.books.length; i++) {
const book = this.books[i];
console.log(book.bookName);
console.log(book.author);
console.log(book.price);
console.log(book.publishDate);
}
mounted
是 Vue 的生命周期钩子,当组件挂载到 DOM 上时,就会执行 mounted
函数。我们在这里请求接口,将数据存储到 data
中。更多关于生命周期钩子的内容,可以参考 Vue.js 官方文档。更多关于列表渲染的内容,可以参考 Vue.js 官方文档。
axios
的请求主要由 axios.get
和 axios.post
两个函数来完成。axios.get
用于发送 GET
请求,axios.post
用于发送 POST
请求。这里我们使用了 get 请求。更多关于 axios
的内容,可以参考 axios 官方文档。
刷新页面,我们可以看到数据已经渲染到页面上了。
下面我们再举一个例子,我想在按钮点击时,向服务器发送一个请求,然后将返回的数据渲染到页面上。
<template>
<div class="about">
<h1>这是一个关于页面</h1>
<button @click="getBooks">获取图书</button>
<ul>
<li v-for="book in books" :key="book.bookName">
<h2>{{ book.bookName }}</h2>
<p>作者:{{ book.author }}</p>
<p>价格:{{ book.price }}</p>
<p>出版日期:{{ book.publishDate }}</p>
</li>
</ul>
</div>
</template>
Details
这里的 {{}}
是 Vue 的插值语法,可以将 js 的数据渲染到页面上。我们这里的原理正是动态改变了 data 中的数据,然后 Vue 会自动渲染到页面上。
<h1>{{ title }}</h1>
data() {
return {
title: "这是一个标题"
}
}
显示的结果是:这是一个标题。
好了,我们继续写代码。
<script>
import axios from "axios";
export default {
name: "About",
data() {
return {
books: [],
};
},
methods: {
getBooks() {
axios.get("http://localhost:3001/books").then((res) => {
this.books = res.data;
});
},
},
};
</script>
在这里,我们不再需要自动执行了,因为我们只有在点击按钮时才需要请求数据。所以我们将 axios
请求放在 getBooks
函数中,不再放在 mounted
中。method
中的 getBooks
函数,就是我们在 template
中绑定的 @click
事件。
导出静态文件
实际上 Vue 最终输出的是静态文件,也就是 index.html
、js
、css
等文件。我们可以通过 npm run build
来将 Vue 项目打包成静态文件。
npm run build
你会发现在项目根目录下多了一个 dist
文件夹,里面就是我们的静态文件。你可以直接将 dist
文件夹部署到服务器上,就可以访问你的网页了。
其他资源
- Vue.js 官方文档
- Vue.js 插值语法
- axios 官方文档
- Vue CLI 官方文档
- Vue Router 官方文档
- ELement for Vue 2 官方文档
- Spring Boot 官方文档
- 基于 Spring Boot 的后端 + Vue2 前端的全栈项目案例
Demo 代码开源
我将这个项目的代码开源在了 Github 仓库 上,你可以下载使用。
下载后,在控制台中输入 npm install
安装依赖,然后输入 npm run serve
,再 node server
运行项目。
支持我
感谢你的阅读,如果你觉得这篇文章对你有帮助,欢迎给我的博客点个赞,你的支持是我最大的动力。
在右上角点击 Star
,你的支持是我最大的动力!如果有任何问题,请联系我,我很乐意和你交流。