把一个组件的所有代码(HTML模板,样式,js(vue对象))写在一个文件里,扩展名是.vue。一个文件里就只有一个组件。这就是单文件组件。
单文件组件实例:
<template>
HTML代码
template>
<script>
vue对象 (使用模块化导出vue对象):可以使用es6的写法
script>
<style scoped> //scoped: 表示局部作用域,表示当前style标签的样式只会应用在当前vue文件里的模板里
样式
style>
通过官方脚手架,(命令行的方式)搭建模块化,工程化,自动化开发环境
注意区分脚手架和vue框架:
vue框架是框架,脚手架是工具
//1、查看版本(这是查看脚手架的版本)
vue -V
//2、如果版本是低于3.X,那么卸载脚手架,安装最新的。
npm uninstall vue-cli -g
//3、安装(脚手架工具)
//1)、装脚手架工具的3.x/4.x
npm install -g @vue/cli
//2)、桥接2.X(兼容脚手架2.X)
npm install -g @vue/cli-init
//4、创建项目:使用脚手架搭建项目(文件夹)
//1)、如果想搭建版本 v3.x/4.x
vue create 项目目录
//2)、如果想搭建版本 2.X
vue init webpack 项目目录
//5、运行项目
npm run serve 项目名
更多详细信息参考搭建脚手架,这里就不过多赘述了。
项目目录如下:
SPA:single page application,单页面应用。
就是整个项目就只有一个html页面(文件),首次加载时,把所有的html,css,js全部加载下来。通过操作dom的删除和创建(添加)来完成页面的切换
优点:
1,局部刷新,所以,用户体验好
2,前后端分离
3,页面效果会比较炫酷(比如切换页面内容时的转场动画)
缺点:
1,不利于seo
2,导航不可用,如果一定要导航需要自行实现前进、后退。
3,初次加载时耗时多
4,页面复杂度提高很多
mock server工具,通俗来说,就是模拟服务端接口数据,即:json-server,是一个存储json数据的server,并且json-server 支持CORS和JSONP跨域请求。
初始化项目:
npm init -y
安装json-server
npm i json-server -D
打开项目编写数据
在项目根目录下创建db.json,并写上合法的json数据,(db名随意,js文件后缀)如下:
{
"shop":[
{
"id":"001",
"title":"瑞幸元气弹系列可口咖啡,清爽十分,活力一下午",
"y_pri":"129",
"x_pri":"99",
"buyed":"8700"
},
{
"id":"002",
"title":"瑞幸咖啡冷却",
"y_pri":"129",
"x_pri":"99",
"buyed":"13800"
}
]
}
//在package.json下增加如下代码:
"scripts": {
"server":"json-server db.json"
},
npm run server (注意是server,不是启动项目的serve)
命令行运行示意图:
数据交互:就是向服务器发送ajax请求,得到数据。
目前,有以下几种方案用于数据交互:
它是ES6新增的的前后端交互方案,是js原生方法
Promise fetch(
url,{
method:
headers:
body
})
返回值:一个 Promise对象,resolve 时回传 Response 对象
URL: 请求地址
配置:(包括请求方式,请求参数等)
method: 请求方法,如 GET、POST
headers:请求的头信息,形式为 Headers 对象或 ByteString。
body: 请求的 body 信息:可能是一个 Blob、BufferSource、FormData、URLSearchParams 或者 USVString 对象。注意 GET 或 HEAD 方法的请求不能包含 body 信息。
实例代码:
//get方式
created() {
fetch("http://localhost:3000/shop?id=1")
.then(res => {
return res.json();//需要先转为json数据,json()为方法
})
.then(data => {//此时data才是我们需要的数据
this.books = data;
});
}
//post方式
fetch(url,{
method:"POST",
headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded' // 指定提交方式为表单提交
}),
body: "id=001&name=张三" // post请求的参数
})
.then(response => response.json())
.then(data => console.log(data))
特点
语法简洁,更加语义化
基于标准 Promise 实现,支持 async/await
同构方便,使用 isomorphic-fetch
Fetch 请求默认是不带 cookie 的,需要设置 fetch(url, {credentials: ‘include’})
服务器返回 400,500 错误码时并不会 reject,只有网络错误这些导致请求不能完成时,fetch 才会被 reject。
一个基于 promise 的 第三方库,可以用在浏览器(前端)和 node.js(后端) 中
npm i axios -S (项目依赖安装)
Promise axios({
url : “地址“
method: “ 提交方式”//默认为get
params:{} 地址栏携带的数据(get方式)
data:{} 非地址栏携带数据(如:post,put等等),
baseURL:如果url不是绝对地址,那么将会加在其前面。当axios使用相对地址时这个设置非常方便
}).then(res=>{
console.log(res.data);
})
axios({配置}).then(成功回调(res)).catch(失败回调(res))
axios.get(url,{配置}).then(成功回调(res)).catch(失败回调(res))
axios.post(url,{配置}).then(成功回调(res)).catch(失败回调(res))
上代码:
//get方式 默认get,可不用写method
created() {
axios({
url:"http://localhost:3000/shop",
params:{
"id":"001"
}
})
.then(res=>{
console.log(res);//这里的res就是我们需要的数据
});
post方式得分情况来说,首先我们要知道post传参是通过data的
axios(
{
method:'post',
url:'regSave.php',
data:'username=jzmdd&userpass=123'
})
.then(res=>{console.log(res.data) });
var params = new URLSearchParams();
params.append('username', 张三疯);
params.append('userpass', '123');
axios(
{
method:'post',
url:'regSave.php',
data:params
})
.then(res=>{ console.log(res.data) });
axios({
url:"/vips",
method:"post",
data:{
name:this.name,
pass:this.pass,
sex:this.sex
},
baseURL:"http://localhost:3000"
})
.then(res=>console.log(res.data))
注意:
使用post方式,在和后端联调时,如果后端接不到数据,需要看network中的
Content-type和数据的格式;
1)、如果data是字符串或者是URLSearchParams
content-type:application/x-www-form-urlencoded
数据格式:form data
2)、如果data是json对象
content-type:application/json
数据格式:request payload
当同时发送多个请求时
axios.all(iterable)//all函数执行所有的请求
axios.spread(callback)//处理响应回来的回调函数
代码:
// 并发
created(){
axios.all([
axios({
url:'/books'
}),
axios({
url:'/readers'
})
])
.then(
axios.spread((resBooks,resReaders)=>{
console.log(resBooks.data);
console.log(resReaders.data);
})
);
在axios中配置项baseURL中
//所有axios请求的基础地址:
axios.defaults.baseURL = 'https://api.example.com';
//所有post请求的默认content-type的值
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
所谓的拦截,并不是真的拦截
请求拦截器是在请求到达后端之前,可以进行“拦截”(所有请求的全局处理),可以对配置进行修改,如:url,检查并在请求头携带token
axios.interceptors.request.use(function(config){ //config是请求时的配置信息。
//一、可以修改baseURL
// config.baseURL = "http://localhost:3000";
//二、可以增加token的携带
// token:是验证身份的。
// token的逻辑:
//1、token什么时候存储的?当登录成功时,后端会产生一个token,发给前端,前端拿到token,
// 保存在cookie或者localStorage。
//2、在请求拦截器里,就需要携带token给服务器端。
// 1)、(假定存储在localStorage中)从localStorage中获取token
let token = localStorage.getItem("token");
if(token){
config.headers.authorization = token;
}
//三、显示loading窗口
// Loading = true;
return config;
},function(){
});
给返回的数据增加公共信息,或者,根据后端返回的状态码,来决定让用户进行再次登录,也可以改变loading的状态为false
axios.interceptors.response.use(
function (response) {//response参数是响应对象
response.data.unshift({“goodsid”:“商品编号”,“goodsname”:“商品名称”,“goodsprice”:“商品价格”});//给响应的数据增加一个对象
//隐藏loading窗口
return response;
}, function (error) {
console.log('响应出错')
return Promise.reject(error)
})
特点:
(1)从浏览器中创建 XMLHttpRequest/从 node.js 创建 http 请求
(2)支持 Promise API
(3)拦截请求和响应
(4)转换请求数据和响应数据
(5)取消请求
(6)自动转换 JSON 数据
(7)客户端支持防御 CSRF
补充:
Ajax、jQuery ajax、axios和fetch的区别
Ajax:
ajax:最早出现的前后端交互技术,是原生js,核心使用XMLHttpRequest对象,多个请求之间如果有先后关系的话,就会出现回调地狱。
Jquery Ajax:
jquery Ajax是原生ajax的封装
Fetch:
fetch是ES6新增的,Fetch是基于promise设计的。fetch不是ajax的进一步封装,而是原生js。Fetch函数就是原生js,没有使用XMLHttpRequest对象。
axios:
axios是原生ajax的封装,基于promise对象的。Axios也可以在请求和响应阶段进行拦截。它不但可以在客户端使用,也可以在nodejs端使用。
当需要操作 ”数据更新影响的(新的)dom时“,就使用$nextTick()。
详细信息请参考$nextTick()
在前后端分离开发的场景,前端有个服务器(提供页面)。后端也有个服务器(提供接口)。
1、开发环境,前端要连后端的接口,就会出现跨域问题。
2、生产(发布)环境:
1)、如果还是前后端分离(在不同的服务器上)。依然有跨域问题(nginx)
2)、如果前后端代码在一起(一个服务器),不存在跨域问题
1)、jsonp
2)、CORS(后端配合) :cross origin resource sharing 后端解决跨域的方案
php 中,这么写:header(“Access-Control-Allow-Origin:*”);
3)、反向代理(前端webpack的devServer)
正向代理隐藏真实客户端,反向代理隐藏真实服务端。
我们要知道,反向代理解决的是跨域问题
通过伪造请求使得http请求为同源的,然后将同源的请求发送到反向代理服务器上,由反向代理服务器去请求真正的url,这样就绕过直接请求真正的url导致跨域问题。
vue-cli3+配置反向代理
. 1.打开项目根/vue.config.js
module.exports = {
devServer:{
//设置代理
proxy: { //代理是从指定的target后面开始匹配的,不是任意位置;配置pathRewrite可以做替换
'/api': { //axios访问 /api == target + /api
target: 'http://localhost:3001',
changeOrigin: true, //创建虚拟服务器
pathRewrite: {
'^/api': '' //重写接口,去掉/api, 在代理过程中是否替换掉/api/路径
}
}
}
}
}
注意:
1、修改完 vue.config.js文件后,必须要重启服务器