目录

1. 环境准备

1.1安装脚手架

1.2 创建项目

1.3 安装 vue devtools

1.4 运行项目

2 Vue组件

2.1 文本插值

2.2 属性绑定 v-bind

2.3 事件绑定 v-on

2.4 计算属性 computed

2.5 vue 底层展示界面的原理

3. Axios

4. 列表渲染v-for和条件渲染 v-if


1. 环境准备

1.1安装脚手架

npm install -g @vue/cli
  • -g 参数表示全局安装,这样在任意目录都可以使用 vue 脚本创建项目

1.2 创建项目

进入到你要创建服务器的目录下,打开命令窗口,执行命令

vue ui

这个的意思就是使用图形界面向导来创建vue项目,运行后跳出此界面

  选择手动配置项目

添加 vue router 和 vuex

选择版本,创建项目

这样就会在文件夹中自动生成vue项目啦~

1.3 安装 vue devtools

这是一个可以进行调试vue项目的浏览器插件,很好用

如果 谷歌应用商店进不去,可以试试以下方法。

1. 先到一个插件下载网址下载插件

下载成功后并解压后就会有下图的.crx后缀文件 。

2. 打开谷歌浏览器, 点击右上角三个点,更多工具——扩展程序

进入到如下页面,并打开右上角的开发者模式。

然后将下载好的.crx后缀文件拖进此浏览器页面中即可。

1.4 运行项目

进入项目目录,prowershell窗口,执行命令

npm run serve

如果报错,尝试用管理员身份运行prowershell,然后进入到项目目录,在执行上述命令。

修改端口

如果前端服务器默认占用了后端 8080 端口,可以进行修改

打开 vue.config.js 文件添加

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({// ...devServer: {port: 7070}})

添加代理

为了避免前后端服务器联调时, fetch、xhr 请求产生跨域问题,需要配置代理

打开 vue.config.js 文件添加

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({// ...devServer: {port: 7070,proxy: {'/api': {target: 'http://localhost:8080',changeOrigin: true}}}})

 vue的项目结构

  • assets - 静态资源

  • components - 可重用组件

  • router - 路由

  • store - 数据共享

  • views - 视图组件

以后还会添加

  • api - 跟后台交互,发送 fetch、xhr 请求,接收响应

  • plugins - 插件

2 Vue组件

Vue 的组件文件以 .vue 结尾,每个组件由三部分组成

<template></template><script></script><style></style>
  • template 模板部分,由它生成 html 代码

  • script 代码部分,控制模板的数据来源和行为

  • style 样式部分,一般不咋关心

入口组件是 App.vue

先删除原有代码,来个 Hello, World 例子

<template><h1>{{msg}}</h1>
</template><script>
export default {data() {return {msg: "Hello, Vue!"}}
}
</script>

解释

  • export default 导出组件对象,供 main.js 导入使用

  • 这个对象有一个 data 方法,返回一个对象,给 template 提供数据

  • {{}} 在 Vue 里称之为插值表达式,用来绑定 data 方法返回的对象属性,绑定的含义是数据发生变化时,页面显示会同步变化

2.1 文本插值

<template><div><h1>{{ name }}</h1><h1>{{ age > 60 ? '老年' : '青年' }}</h1></div>
</template>
<script>
const options = {data: function () {return { name: '张三', age: 70 };}
};
export default options;
</script>
  • {{}} 里只能绑定一个属性,绑定多个属性需要用多个 {{}} 分别绑定

  • template 内只能有一个根元素

  • 插值内可以进行简单的表达式计算

2.2 属性绑定 v-bind

vue中可以将组件和时间进行绑定。如下代码

<template><div><!-- 属性绑定 v-bind --><div><input type="text" v-bind:value="name"/></div><div><input type="date" v-bind:value="birthday"/></div><!-- v-bind简写 v-bind可以省略 --><div><input type="text" :value="age"/></div></div></template>
<script>const options = {data:function(){return {name: '张三',birthday: '1995-01-01',age: 18}}}export default options;
</script>
  • 简写方式:可以省略 v-bind 只保留冒号

2.3 事件绑定 v-on

<!-- 事件绑定 -->
<template><div><div><input type="button" value="点我执行m1" v-on:click="m1"></div><div><input type="button" value="点我执行m2" @click="m2"></div><div>{{count}}</div></div>
</template>
<script>
const options = {data: function () {return { count: 0 };},methods: {m1() {this.count ++;console.log("m1")},m2() {this.count --;console.log("m2")}}
};
export default options;
</script>
  • 简写方式:可以把 v-on: 替换为 @

  • 在 methods 方法中的 this 代表的是 data 函数返回的数据对象

2.4 计算属性 computed

<!-- 计算属性 -->
<template><div><h2>{{fullName}}</h2><h2>{{fullName}}</h2><h2>{{fullName}}</h2></div>
</template>
<script>
const options = {data: function () {return { firstName: '三', lastName: '张' };},/* methods: {fullName() {console.log('进入了 fullName')return this.lastName + this.firstName;}},*/computed: {fullName() {console.log('进入了 fullName')return this.lastName + this.firstName;}}
};
export default options;
  • 普通方法调用必须加 (),没有缓存功能

  • 计算属性使用时就把它当属性来用,不加 (),有缓存功能:

    • 一次计算后,会将结果缓存,下次再计算时,只要数据没有变化,不会重新计算,直接返回缓存结果

2.5 vue 底层展示界面的原理

这里我们那App.vue举例。因为它是vue项目创建出来后自带的

首先,先将App.vue导入到main.js文件中

然后在main.js中执行了new Vue中的render

那么,这个#app的文件又是啥呢,其实在vue项目中已经给我们默认创建出来了 

如图:

这就是vue将组件渲染到页面上的原理啦~

3. Axios

axios 它的底层是用了 XMLHttpRequest(xhr)方式发送请求和接收响应,xhr 相对于之前讲过的 fetch api 来说,功能更强大,但由于是比较老的 api,不支持 Promise,axios 对 xhr 进行了封装,使之支持 Promise,并提供了对请求、响应的统一拦截功能

安装

npm install axios -S

导入

import axios from 'axios'
  • axios 默认导出一个对象,这里的 import 导入的就是它默认导出的对象

方法

请求 备注
axios.get(url[, config]) ⭐️
axios.delete(url[, config])
axios.head(url[, config])
axios.options(url[, config])
axios.post(url[, data[, config]]) ⭐️
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])
  • config - 选项对象、例如查询参数、请求头...

  • data - 请求体数据、最常见的是 json 格式数据

  • get、head 请求无法携带请求体,这应当是浏览器的限制所致(xhr、fetch api 均有限制)

  • options、delete 请求可以通过 config 中的 data 携带请求体

代码演示(这里包含了 发送get、post请求,发送请求头,发送是携带查询参数,用格式urlencode 请求体发送数据,用multipart格式请求体发送数据,用json格式请求体发送数据)

代码:提示,这里我配置了跨域的问题,/stu 代表localhost:8080,

前端代码:

<template>
<!-- axios --><div>{{data}}<input type="button" value="点击获取数据" @click="sendAsync"></div></template><script>
/* 导入axios */
import axios from '../util/myaxios'const options = {data:function(){return { data:''}},methods: {async sendAsync(){// 发送 get请求// const resp = await axios.get('stu/a1');//发送 post请求,需要携带一个参数对象,这里为空对象// const resp = await axios.post('stu/a2',{});//发送请求头,除了请求地址,参数,还有config对象// const resp = await axios.post('stu/a3',{},{//     headers:{//         Authorization: 'authorization'//     }// });//发送请求时携带查询参数, url?name=xxx&age=xxx/* 第一种方法,拼接字符串 */// const name = encodeURIComponent('&&&');// const age = 18;// const resp = await axios.post(`stu/a4?name=${name}&age=${age}`);/* 只是这种方法对于特殊字符串,需要重新编码 ,例如&&&*//* 第二种方法,就是在config对象中设置param对象 这种方法会自动对特殊字符进行重新编码*/// const resp = await axios.post('stu/a4',{},{//     params:{//         name: '&&&',//         age: 18//     }// });//用请求体发送数据,格式为urlencoded// const param = new URLSearchParams();// param.append('name','张三');// param.append('age','18');// const resp = await axios.post('stu/a4',param);//用请求体发送数据,格式为 multipart// const param = new FormData();// param.append('name','李四');// param.append('age','19');// const resp = await axios.post('stu/a4',param);// //用请求体发送数据,格式为json,需在后端加上@RequestBody注解// const resp = await axios.post('stu/a5',{//     name: '张三',//     age: 18// });this.data = resp.dataconsole.log(resp)},sendSync(){axios.get('stu/student').then(resp =>{console.log(resp)this.data = resp.data})}}}export default options;
</script>

后端:

为了方便,代码都写在可Controller层

package com.hua.controller;import com.hua.domain.A5;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpSession;/*** @Author 华子* @Date 2023/1/8 15:51* @Version 1.0*/
@Controller
@RequestMapping("stu")
public class AxiosController {@GetMapping("/a1")@ResponseBodypublic String a1(){return "get request";}@PostMapping("/a2")@ResponseBodypublic String a2(){return "post request";}@PostMapping("/a3")@ResponseBodypublic String a3(@RequestHeader("Authorization") String authorization){System.out.println("Authorization:"+authorization);return "post request";}@PostMapping("/a4")@ResponseBodypublic String a4(String name, Integer age){System.out.println("name:"+name+",age:"+age);return "post request";}@PostMapping("/a5")@ResponseBodypublic String a5(@RequestBody A5 a5){System.out.println("name:"+a5.getName()+",age:"+a5.getAge());return "post request";}@PostMapping("/a6Set")@ResponseBodypublic String a6Set(HttpSession session){System.out.println("==========a6Set==============");System.out.println(session.getId());session.setAttribute("name","张三");return "post request";}@PostMapping("/a6Get")@ResponseBodypublic String a6Get(HttpSession session){System.out.println("==========a6Get==============");System.out.println(session.getId());System.out.println(session.getAttribute("name"));return "post request";}}

axios可以进行默认配置

创建实例

const _axios = axios.create(config);
  • axios 对象可以直接使用,但使用的是默认的设置

  • 用 axios.create 创建的对象,可以覆盖默认设置,config 见下面说明

常见的 config 项有

名称 含义
baseURL 将自动加在 url 前面
headers 请求头,类型为简单对象
params 跟在 URL 后的请求参数,类型为简单对象或 URLSearchParams
data 请求体,类型有简单对象、FormData、URLSearchParams、File 等
withCredentials 跨域时是否携带 Cookie 等凭证,默认为 false
responseType 响应类型,默认为 json

const _axios = axios.create({baseURL: 'http://localhost:8080',withCredentials: true
});
await _axios.post('/api/a6set')
await _axios.post('/api/a6get')
  • 生产环境希望 xhr 请求不走代理,可以用 baseURL 统一修改

  • 希望跨域请求携带 cookie,需要配置 withCredentials: true,服务器也要配置 allowCredentials = true,否则浏览器获取跨域返回的 cookie 时会报错

这里提供一个默认写好的axios配置~

myaxios.js文件 (里头有拦截器,包括请求和响应两种拦截器)

import axios from 'axios'
const _axios = axios.create({// baseURL: 'http://localhost:8080',withCredentials: true
});// 9. 拦截器
_axios.interceptors.request.use(function (config) {// 比如在这里添加统一的 headersconfig.headers = {Authorization: 'aaa.bbb.ccc'}return config;},function (error) {return Promise.reject(error);}
);_axios.interceptors.response.use(function (response) {// 2xx 范围内走这里return response;},function (error) {if (error.response?.status === 400) {console.log('请求参数不正确');return Promise.resolve(400);} else if (error.response?.status === 401) {console.log('跳转至登录页面');return Promise.resolve(401);} else if (error.response?.status === 404) {console.log('资源未找到');return Promise.resolve(404);}// 超出 2xx, 比如 4xx, 5xx 走这里return Promise.reject(error);}
);export default _axios;

我们导入axios就可以这么写

4. 列表渲染v-for和条件渲染 v-if

这里用一个例子来展示

从后端拿去学生数据,展示到前端

<template><div><!-- <input type="button" value="点击获取数据" @click="sendAsync"> --><div class="title">学生列表</div><div class="thead"><div class="row bold"><div class="col">编号</div><div class="col">姓名</div><div class="col">性别</div><div class="col">年龄</div></div></div><div class="tbody"> <!-- 条件渲染v-if:如果读取到学生数据不为空,就展示 --><div v-if="students.length > 0"><!-- 列表渲染v-for,循环得到的学生数据并展示 --><div class="row" v-for="student of students" :keys="student.id"><div class="col">{{student.id}}</div><div class="col">{{student.name}}</div><div class="col">{{student.sex}}</div><div class="col">{{student.age}}</div></div>  </div><!-- 如果为空 --><div class="row" v-else>暂无学生数据</div></div></div>
</template>
<script>import axios from  '../util/myaxios'const options = {mounted: function(){this.sendAsync();},data: function(){return {students: []}},methods:{async sendAsync(){const resp = await axios.get('stu/student');console.log(resp.data.data)this.students = resp.data.data}}}export default options;
</script><style scoped>div {font-family: 华文行楷;font-size: 20px;}.title {margin-bottom: 10px;font-size: 30px;color: #333;text-align: center;}.row {background-color: #fff;display: flex;justify-content: center;}.col {border: 1px solid #f0f0f0;width: 15%;height: 35px;text-align: center;line-height: 35px;}.bold .col {background-color: #f1f1f1;}
</style>

重用组件

主要语法就是在components文件夹中定义一个常用组件,也就是子组件

然后导入到父组件中

<script>import MyButton from  '../components/MyButton.vue'const options = {components:{MyButton}}export default options;
</script>

在父组件中打上标签即可。

<template>
<!-- 可重用组件 --><div><h1>父组件</h1><div><h2>子组件</h2><my-button>1</my-button></div></div>
</template>

具体代码:

子组件MyButtons:

<template><div class="button" :class="[type,size]"><slot></slot><!-- 加入插槽,可以在父组件中添加按钮名称 --></div>
</template>
<script>
const options = {props:["type","size"]
};
export default options;
</script>
<style scoped>
.button {display: inline-block;text-align: center;border-radius: 30px;margin: 5px;font: bold 12px/25px Arial, sans-serif;padding: 0 2px;text-shadow: 1px 1px 1px rgba(255, 255, 255, .22);box-shadow: 1px 1px 1px rgba(0, 0, 0, .29), inset 1px 1px 1px rgba(255, 255, 255, .44);transition: all 0.15s ease;
}.button:hover {box-shadow: 1px 1px 1px rgba(0, 0, 0, .29), inset 1px 1px 2px rgba(0, 0, 0, .5);
}.button:active {box-shadow: inset 1px 1px 2px rgba(0, 0, 0, .8);
}.primary {background-color: #1d6ef9;color: #b5e3f1;
}.danger {background-color: rgb(196, 50, 50);color: white;
}.success {background-color: #a5cd4e;;color: #3e5706;
}.small {width: 40px;height: 20px;font-size: 10px;line-height: 20px;
}.middle {width: 50px;height: 25px;font-size: 14px;line-height: 25px;
}.large {width: 60px;height: 30px;font-size: 18px;line-height: 30px;
}
</style>

父组件:

<template>
<!-- 可重用组件 --><div><h1>父组件</h1><div><h2>子组件</h2><my-button type="primary" size="small">1</my-button><my-button type="danger" size="middle">2</my-button><my-button type="success" size="large">3</my-button></div></div>
</template>
<script>import MyButton from  '../components/MyButton.vue'const options = {components:{MyButton}}export default options;
</script><style scoped>
.button {display: inline-block;text-align: center;border-radius: 30px;margin: 5px;font: bold 12px/25px Arial, sans-serif;padding: 0 2px;text-shadow: 1px 1px 1px rgba(255, 255, 255, .22);box-shadow: 1px 1px 1px rgba(0, 0, 0, .29), inset 1px 1px 1px rgba(255, 255, 255, .44);transition: all 0.15s ease;
}.button:hover {box-shadow: 1px 1px 1px rgba(0, 0, 0, .29), inset 1px 1px 2px rgba(0, 0, 0, .5);
}.button:active {box-shadow: inset 1px 1px 2px rgba(0, 0, 0, .8);
}.primary {background-color: #1d6ef9;color: #b5e3f1;
}.danger {background-color: rgb(196, 50, 50);color: white;
}.success {background-color: #a5cd4e;;color: #3e5706;
}.small {width: 40px;height: 20px;font-size: 10px;line-height: 20px;
}.middle {width: 50px;height: 25px;font-size: 14px;line-height: 25px;
}.large {width: 60px;height: 30px;font-size: 18px;line-height: 30px;
}
</style>

前端学习第三站——Vue2基础篇相关推荐

  1. Vue2基础篇教程合集

    Vue2基础篇教程合集 点击跳转具体教程,该教程基于HTML书写,深度理解Vue如何运行. 一.Vue2基础篇-初识Vue 二.Vue2基础篇-模板语法 三.Vue2基础篇-理解MVVM模型 三.Vu ...

  2. [Python从零到壹] 三十七.图像处理基础篇之图像融合处理和ROI区域绘制

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  3. [Python从零到壹] 三十三.图像处理基础篇之什么是图像处理和OpenCV配置

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  4. 强化学习笔记(一)基础篇

    强化学习笔记(一)基础篇 目录 1.强化学习相关概念 2.强化学习与监督学习和非监督学习的区别 3.强化学习分类 4.三对重要概念 目录 写在前面:本文系小编学习邹伟老师等人编著的<强化学习&g ...

  5. android前端怎样php后台交互(基础篇)

    android前端怎样php后台交互(基础篇) android客户端和php+mysql+apache搭建的服务器之间的简单交互,实现登入功能. 实现原理就是android客户端发送请求,传给服务器登 ...

  6. J2EE学习笔记三:EJB基础概念和知识 收藏

    J2EE学习笔记三:EJB基础概念和知识 收藏 EJB正是J2EE的旗舰技术,因此俺直接跳到这一章来了,前面的几章都是讲Servlet和JSP以及JDBC的,俺都懂一些.那么EJB和通常我们所说的Ja ...

  7. FPGA系统性学习笔记连载_Day1数字电路基础篇

    FPGA系统性学习笔记连载_Day1数字电路基础篇 连载<叁芯智能FPGA设计与研发就业班-第一天> <数字电路基础1> 原创作者:紫枫术河 转载请联系群主授权,否则追究责任 ...

  8. HFSS学习笔记(一)基础篇 操作界面简介和使用前的准备工作

    HFSS学习笔记(一)基础篇 操作界面简介和使用前的准备工作 一.HFSS工作界面简介 各区域的功能: 二.设计的步骤 1.创建工程文件 2.进行设计前的准备工作 一.HFSS工作界面简介 各区域的功 ...

  9. 学习C++:C++进阶(三)CMake基础篇---用一个小型项目了解CMake及环境构建

    V1.1 于2022年7月15日第二次修改:添加了比较多的解释图,解读了各类库的CMakelist.txt文件 目录 第一部分 基础篇(Basics) 1.0 本部分主要学什么(Intro) 1.1 ...

最新文章

  1. Mol2vec | 一种无监督机器学习方法的分子亚结构向量表示
  2. 反思快乐:融入 真实 不回忆 聪明应对
  3. 《重构:改善既有代码的设计》阅读笔记
  4. Oracle的不完全恢复
  5. Linux系统的操作命令
  6. python生成器yield原理_Python generator生成器和yield表达式详解
  7. python设计模式5-原型模式
  8. Tomcat控制台乱码
  9. 系统学习 TypeScript(四)——变量声明的初步学习
  10. 本周小结!(二叉树系列三)
  11. 51cto,一个创造能让IT人员成长的论坛
  12. 计算机控制系统a卷-答案,微型计算机控制技术试卷附标准答案A
  13. 道指30只成分股的股价及历史股价抓取分析
  14. Vfed大橙子模板 苹果cms自动采集 的方法
  15. 【转】艺术设计、数字媒体、环艺、影视动画、摄影、广编专业…等…视频、教程、资讯、图库、作品汇总大全
  16. 笔记本光驱拆解——让整个世界变得安静
  17. 整数规划Python
  18. Heart-Shaped Box
  19. Ipad电容笔买原装还是平替?高性价比的ipad平替电容笔推荐
  20. PMBOK(第六版) PMP笔记——《九》第九章(项目资源管理)

热门文章

  1. 2023最新SSM计算机毕业设计选题大全(附源码+LW)之java社区闲置物品交易平台z10mc
  2. 高级驾驶辅助系统ADAS技术介绍
  3. OpenGL ES EGL eglDestroyContext
  4. php映射脚本,代替php脚本
  5. 微信开发,微信开发者平台
  6. 为什么受伤的总是我,赢的总是她?
  7. Git 命令使用体验的神器 -- tig
  8. X-Brain:如此美丽可爱的大脑工作原理
  9. 美团codeM资格赛 优惠券
  10. 如何让同步/刷新的图标(el-icon-refresh)旋转起来