环境的配置就不过多赘述了,教程很多
express上手小项目
来源指路:https://blog.csdn.net/jolinoy/article/details/124921104?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522169892769516800197082140%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=169892769516800197082140&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-2-124921104-null-null.142v96pc_search_result_base3&utm_term=vue%20express&spm=1018.2226.3001.4187
后端 | 创建express项目
名称为sever
express --no-view server
–no-view即不需要界面,此处做的是前后端分离的,所以要写入–no-view
此处创建了一个名为server的无视图的express后端
项目目录
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
bin/www : 用来启动项目,默认端口3000
routes : 路由文件,这里面的代码主要用于接收前端的请求,然后进行响应
app.js : 整个项目的入口文件,在这里可以引入一些需要的模块,进行总体路由设置等
node_modules : 安装好项目所需的依赖模块就会出现,存放的是下载的依赖模块
安装项目所需的依赖模块
进入到server文件中,输入以下命令安装安装项目所需的依赖模块
npm install
启动项目,测试后端
npm run start
npm start
上面两个命令应该都可以使用的
打开浏览器输入
localhost:3000
默认端口一般是3000
完善后端代码
在routes目录创建test.js文件,输入以下代码
var express=require('express');
//创建web服务器
var router=express.Router();
router.get('/',function(req,res,next){
res.send('响应成功!');
});
module.exports=router;
在app.js中添加代码
//引入自定义路由文件
var testRouter=require('./routes/test');
//根据路由分配页面
app.use('/test',testRouter);
新建了一个js文件之后都需要在app.js中添加这两行代码
它将/test这个路径对应于了test.js这个文件
修改完成后,重启项目,即ctrl+c退出后,再次npm run start一下
再次访问localhost:3000/test
就可以访问到了
前端 | 创建vue项目
创建vue项目来源指路:https://blog.csdn.net/adminsir0/article/details/127250463
vue create client
可以在vs-code的TERMINAL上输入命令创建,但是可能需要开启一个设置
可参考文章:https://blog.csdn.net/qq_66345100/article/details/128727031
此处创建了一个名为client的前端
通过命令添加路由组件
vue add router
切记要在client文件夹里输入此命令
项目目录
assets : 存放静态资源,比如图片(images),视频(videos),音频(audio)
router : 需要后建的,用来管理路由
components : 存放全局组件,即不同页面都会用到的组件
views : 存放子组件
App.vue : 项目的根文件,后面会介绍一下
App.vue
HTML代码需要的这里里面编写
App.vue中的HTML代码解析示例如下:
<template>
<div class="appVue">
<nav>
<!--使用 router-link 组件进行导航 -->
<!--通过传递 `to` 来指定链接 -->
<!--`<router-link>` 将呈现一个带有正确 `href` 属性的 `<a>` 标签-->
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</nav>
<!-- 路由出口 -->
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view/>
</div>
</template>
中只能有一个类,比如这里的appVue
在这个类中有多少小类都没关系
启动vue项目
npm run serve
启动成功后,打开浏览器输入
localhost:8080
默认端口为8080
前后端交互
创建vue视图
vue安装axios组件
前后端需要通过HTTP进行数据交换
在expree中已经集成了HTTP相关模块,可以使用express.Router()对象来进行HTTP操作
在vue中就需要安装axios这一基于promise的HTTP库,因此要在client项目根目录下执行以下命令完成axios组件的安装
npm install axios --save
在views目录下新建Test.vue
<!-- html -->
<template>
<div>
<h1>{{ this.msg }}</h1>
</div>
</template>
<script>
import axios from "axios";
//前后端交互
export default{
name:"Test",
// 数据
data(){
return{
msg:""
};
},
created(){
//钩子函数
axios
.get("http://localhost:3000/test")
.then((res)=>{
this.msg=res.data;
})
.catch((err)=>{
console.log(err);
});
},
};
</script>
<style>
/* CSS */
h1,
h2{
font-weight:normal;
}
</style>
钩子函数
参考来源:https://www.php.cn/faq/563544.html
每个组件在被创建、挂载、更新、销毁等阶段都会有一些特定的行为
这些行为可以通过钩子函数来定义和执行
钩子函数是在特定生命周期阶段被触发的函数,可以用来执行一些特定的逻辑
可以分成两类:生命周期钩子函数;自定义事件钩子函数
一、生命周期钩子函数
在Vue实例运行期间自动调用的函数
1.beforeCreate
在vue实例创建之前:组件实例还没有被初始化;这个阶段只能访问组件实例的选项对象
2.created
在vue实例创建之后:组件实例已经创建,但还没有挂载到DOM之上;这个阶段可以访问组件实例的选项对象和数据,但是不可以访问DOM
3.beforeMount
在组件挂载到DOM之前:组件实例已经完成了初始化,但是还没有被渲染到页面上
4.mounted
在组件挂载到DOM之后:组件实例已经完成了初始化,并且已经被渲染到页面上,可以访问DOM元素
5.beforeUpdate
数据更新之前:组件还没有被重新渲染
6.updated
数据更新之后:组件已经被重新渲染;可以访问更新后的DOM元素
7.beforeDestroy
组件被销毁之前:组件实例仍然可用
8.destroyed
组件被销毁之后:组件实例及所有指令和事件监听器都已经被销毁;不应该再访问组件实例或组件的DOM元素
一个vue文件就是一个实例对象?
DOM和BOM参考文章:https://blog.csdn.net/qq_34402069/article/details/130984867
二、自定义钩子函数
在特定事件触发时,由开发人员手动调用
export和import
参考文章:https://blog.csdn.net/qq_38210427/article/details/129487497
import 导入其他模块成员
export 向外共享模块成员
export default是默认导出成员
每个模块中,只允许使用唯一的一次export default,否则会报错
then
参考文章:https://blog.csdn.net/qq_26942049/article/details/126090214
then()方法是异步执行
当.then()方法前执行完之后再执行then内部的程序,避免里数据没获取到的情况
then()当中有两个参数:
第一个是成功时的回调方法,默认给这个方法传递了成功的数据;
第二个是失败时的回调方法和失败的数据
catch
catch()方法是防止因错误而造成系统崩溃
可以捕获错误,但是不会影响程序的运行
一般情况下,为了不报错会在then()的后面调用.catch()
主要区别:
then的第一个函数里抛出了异常,后面的catch能捕获到,而then的第二个函数捕获不到
因此,建议总是使用catch方法,而不使用then方法的第二个参数
绑定路由
在router目录下的index.js里绑定路由
//导入模块
import Test from '../views/Test.vue'
{
//前端路径
path:'/test',
name:'Test',
//组件
component:Test
}
完整的index.js代码
import { createRouter, createWebHashHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import Test from '../views/Test.vue'
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
},
{
path:'/test',
name:'Test',
component:Test
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router
实现跨域
我们在vue中引入了axios模块,对URL localhost:3000/test进行了get请求
将响应的data赋值给变量msg并渲染到页面上
为了实现express与vue之间的跨域问题,需要在express_app的app.js中添加以下内容
app.all("*", function (req, res, next) {
//设置允许跨域的域名,*代表允许任意域名跨域
res.header("Access-Control-Allow-Origin", "*");
//允许的header类型
res.header("Access-Control-Allow-Headers", "appversion,authorization,content-type,deviceid");
//跨域允许的请求方式
res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
// if (req.method.toLowerCase() == 'options')
// res.send(200); //让options尝试请求快速结束
// else
// next();
req.method == "OPTIONS" ? res.send(200) : next();
});
app.js完整代码:
一定要注意跨域这部分的代码的位置,不然的话会报错
//引入中间件
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
//引入自定义的路由文件
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var testRouter=require('./routes/test');
var app = express();
// var testRouter = require('./routes/test')
// app.use('/test', testRouter)
//设置跨域访问(放在app实例化之后)
app.all("*", function (req, res, next) {
//设置允许跨域的域名,*代表允许任意域名跨域
res.header("Access-Control-Allow-Origin", "*");
//允许的header类型
res.header("Access-Control-Allow-Headers", "appversion,authorization,content-type,deviceid");
//跨域允许的请求方式
res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
// if (req.method.toLowerCase() == 'options')
// res.send(200); //让options尝试请求快速结束
// else
// next();
req.method == "OPTIONS" ? res.send(200) : next();
});
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
//根据路径分配页面
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/test',testRouter);
// 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')
// res.header('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS')
// res.header('X-Powered-By', ' 3.2.1')
// req.method == "OPTIONS" ? res.send(200) : next()
// })
module.exports = app;
报错Parsing error: No Babel config file detected for D:\VuecliWorkspace\vue_test\src\main.js.
参考文章:https://blog.csdn.net/weixin_44350315/article/details/125480036?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522169898892016800197087000%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=169898892016800197087000&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-1-125480036-null-null.142v96pc_search_result_base4&utm_term=Parsing%20error%3A%20No%20Babel%20config%20file%20detected%20for%20D%3A%5C%5Cvue_file%5C%5Cclient%5C%5Csrc%5C%5Cviews%5C%5Ctest.vue.%20Either%20disable%20config%20file%20checking%20with%20requireConfigFile%3A%20false%2C%20or%20configure%20Babel%20so%20that%20it%20can%20find%20t&spm=1018.2226.3001.4187
完整报错信息:Parsing error: No Babel config file detected for D:\VuecliWorkspace\vue_test\src\main.js. Either disable config file checking with requireConfigFile: false, or configure Babel so that it can find the config files
将 "requireConfigFile"改成false