Skip to main content

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” ,打开命令行窗口。

2

在命令行窗口中输入以下命令:

npm install -g @vue/cli
注意

npm 服务器在境外,请确保你有稳定可用的代理。否则可能会出现安装失败的情况。

如下图即为安装成功,(可以忽略警告):

2

接着,我们使用 Vue CLI 创建一个项目:

vue create [工程名,自定义] # 例如:vue create vue-demo

3

这里我会用 Vue2 来讲解,请选择 Vue2.(Vue3 还没学哈哈哈)。

2

安装中:

3

安装完成:

4

启动项目

安装完成之后,我们就可以启动项目了。用 Visual Studio Code 打开项目文件夹:

2

3

注意,必须确保你的 package.json 文件在打开后的根目录,否则按照下面的步骤操作会出现错误。

3

插件推荐

Vue 开发可能需要一些插件,这里不再赘述,可以参考:
Vue 开发必备 VSCode 插件

选择顶部菜单栏,点击 “终端” ,选择 “新终端” :

2

在终端中输入以下命令:

npm run serve

2

3

运行完成,在浏览器中打开 http://localhost:8080/ ,即可看到 Vue 的欢迎界面:

3

引入 Element UI

Element UI 是一套基于 Vue 2.0 的组件库,它由饿了么技术团队开源,它可以帮助我们快速搭建漂亮的页面。(真的好清新的页面!)

Element UI 官网

安装 Element UI

新建终端,在终端中输入以下命令:

npm i element-ui -S

按回车键,等待安装完成。

2

3

引入 Element UI

在项目的 src/main.js 文件中,引入 Element UI:

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);

3

好了!现在我们就可以使用 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> 标签下添加的内容。

2

此外,我们还注意到,这里有个 <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> 标签,它的内容是 我改了这里面的内容!

在浏览器刷新页面后,你可以看到,页面上的内容已经发生了变化。

2

你可能高呼:我懂了!这就是组件的用法!我们把 HelloWorld 组件写在了别的文件中,我只要在 App.vue 文件中引入它,就可以使用它了!这给了我启发,那么我在 components 文件夹下新建一个 MyComponent.vue 文件,然后在 App.vue 文件中引入它,看看会发生什么?

2

MyComponent.vue
<template>
<div class="hello">
<h1>我是 MyComponent 组件!</h1>
</div>
</template>

然后,我们要用 js 将这个组件导出:

MyComponent.vue
<script>
export default {
name: "MyComponent",
props: {},
};
</script>

接着,我还希望给他加上一些样式,所以我在 <style> 标签中写了一些样式:

MyComponent.vue
<style scoped>
.hello {
color: red;
}
</style>

我把这个类绑定到 h1 标签上,这样就可以让 h1 标签的文字变成红色了。

MyComponent.vue
<template>
<div>
<h1 class="hello">我是 MyComponent 组件!</h1>
</div>
</template>

这时,你刷新页面,你会发现,啥也没变!那是因为我们还没有在 App.vue 文件中引入这个组件。

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>

3

接下来,我们可以划分页面的结构了。

2

使用 Element UI

接下来,让我们使用 Element UI 来快速搭建页面的结构。

首先,我们需要一个导航栏,因此,我到 Element UI 官网 找到了 Menu 组件。

2

我们看到他为我们提供了代码,我们选一种样式的代码,然后复制到 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 文件长这样,我删除了原来的图片和示例的组件。

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>

打开浏览器,刷新页面,我们可以看到效果了。

2

我们只需要修改上面代码中的中文即可改变标签内容,不需要的标签删去即可。

新的页面和路由

首先,我们要使用到 vue 的路由管理,因此,我们需要安装 vue-router 的 vue 2 版。

npm install vue-router@2

ok,让我们创建两个子页面用于展示不同的内容:

新建 views 文件夹,然后在 views 文件夹中新建 Home.vueAbout.vue 文件。

Home.vue
<template>
<div>
<h1>Home</h1>
</div>
</template>

<script>
export default {
name: "Home",
};
</script>

<style scoped></style>
About.vue
<template>
<div>
<h1>About</h1>
</div>
</template>

<script>
export default {
name: "About",
};
</script>

<style scoped></style>

接着,我们需要新建 router/index.js 文件夹并在其中配置路由。路由也就是我们点击菜单后,页面跳转到哪里的路径。

2

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 是路由的占位符,当我们点击菜单时,会根据路由的配置,跳转到对应的页面。

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>
<router-view />
</div>
</template>

<script>
import router from "./router/index.js"; // 😊

export default {
name: "App",
router, // 😊
};
</script>

<style>
</style>

你可能看见如下报错:

2

在vue.config.js文件下,加入以下代码:

vue.config.js
lintOnSave: false // 关闭eslint校验

这个报错不管也行,它只是说代码不规范,不影响。

为了让菜单更明显,我删除了不必要的代码:

App.vue
<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>

<!-- .... -->

然后,我们用路由触发器包裹导航栏:

App.vue
<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 接口。

server.js
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 中。

Home.vue
<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 循环。

Home.vue
<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.getaxios.post 两个函数来完成。axios.get 用于发送 GET 请求,axios.post 用于发送 POST 请求。这里我们使用了 get 请求。更多关于 axios 的内容,可以参考 axios 官方文档

刷新页面,我们可以看到数据已经渲染到页面上了。

2

下面我们再举一个例子,我想在按钮点击时,向服务器发送一个请求,然后将返回的数据渲染到页面上。

about.vue
<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: "这是一个标题"
}
}

显示的结果是:这是一个标题。

好了,我们继续写代码。

about.vue
<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 事件。

2

导出静态文件

实际上 Vue 最终输出的是静态文件,也就是 index.htmljscss 等文件。我们可以通过 npm run build 来将 Vue 项目打包成静态文件。

npm run build

你会发现在项目根目录下多了一个 dist 文件夹,里面就是我们的静态文件。你可以直接将 dist 文件夹部署到服务器上,就可以访问你的网页了。

2

其他资源

Demo 代码开源

我将这个项目的代码开源在了 Github 仓库 上,你可以下载使用。

2

下载后,在控制台中输入 npm install 安装依赖,然后输入 npm run serve,再 node server 运行项目。

支持我

感谢你的阅读,如果你觉得这篇文章对你有帮助,欢迎给我的博客点个赞,你的支持是我最大的动力。

2

在右上角点击 Star,你的支持是我最大的动力!如果有任何问题,请联系我,我很乐意和你交流。