视频笔记是根据B站 千锋 涛哥 - SpringBoot+vue+前后端分离项目《锋迷商城》实战课-完结版 进行整理的
笔记可上 gitee仓库 自取
前端三框架:HTML、CSS、JavaScript
UI 框架:(只提供样式、显示效果)
JS 框架:
项目结构经历的三个阶段:
后端 MVC :可以理解为单体结构,流程控制是由后端控制器来完成
前端 MVC :前后端分离开发,后端只负责接收响应请求
MVVM是MVC的增强版,实质上和MVC没有本质区别,只是代码的位置变动而已
MVVM 前端请求后端接口,后端返回数据,前端接收数据,并将接收到的数据设置为 “VM”,HTML 从 vm 取值
Model-View-ViewModel —— 概念图
Vue (读音 /vju/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
离线引用:下载 vue 的 js 文件,添加到前端项目,在网页中通过 script 标签引用 vue.js 文件
CDN 引用:
直接使用在线 CDN 的方式引入
文本:数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值:
{{message}}
创建一个 HTML 文件
引入 vue.js 文件
示例:
Title
Mustache 标签将会被替代为对应数据对象上 message
property 的值。无论何时,绑定的数据对象上 message
property 发生了改变,插值处的内容都会更新。
{{code}}
从 0 开始: {{message}}
支持 ognl 语法
v-if : 用来控制切换一个元素是否显示 (底层控制是 DOM 元素,操作 DOM)
注:在浏览器中网页打开这个文件 F12,从标签上可以看到没有 stu.stuGender == 'F'
对应的元素。即条件不成立,网页不会渲染该 DOM,连标签都不会有。
学号:{{stu.stuNum}}
姓名:{{stu.stuName}}
性别:
年龄:{{stu.stuAge}}
v-for
指令基于一个数组来渲染一个列表。在
v-for
块中,我们可以访问所有父作用域的 property。v-for
还支持一个可选的第二个参数,即当前项的索引。
序号
学号
姓名
性别
年龄
{{index + 1}}
{{stu.stuNum}}
{{stu.stuName}}
男
女
{{stu.stuAge}}
v-bind:属性名 缩写::属性名
序号 | 学号 | 姓名 | 性别 | 年龄 | |
---|---|---|---|---|---|
{{index + 1}} | {{stu.stuNum}} | {{stu.stuName}} | 男
|
{{stu.stuAge}} |
只能使用在表单输入标签
v-model:value 可以简写为 v-model
每个使用 vue 进行数据渲染的网页文档都需要创建一个 vue 实例 — — ViewModel
vue 实例生命周期 — — vue 实例从创建到销毁的过程
创建对象 ---- 属性初始化 ---- 获取属性值 ----- GC 回收
为了便于开发者在 vue 实例生命周期的不同阶段进行特定的操作,vue 在生命周期四个阶段的前后分别提供了一个函数,这个函数无需开发者调用,当 vue 实例到达生命周期的指定阶段会自动调用对应的函数。
data 中的属性可以通过声明获得,也可以通过在 computed 计算属性的 getter 获得
特性:计算属性所依赖的属性值发生变化会影响计算属性的值同时发生变化
示例
Title
{{message3}}
侦听器,就是 data 中属性的侦听器,当 data 中的属性值发生变化就会触发侦听器函数的执行
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch
选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
Title
{{message3}}
Title
Title
Hello World!
Hello World!!
Hello World!!!
Hello World!!!!
条件判断语句:
v-if
v-else-if
v-else
v-if
指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。
Title
Hello :可以看到
flag 为 true, 可以看到
v-else
指令来表示v-if
的“else 块”
Hello :可以看到
World :可以看到
分数 {{code}}
对应的等级:
优秀
良好
中等
及格
挂科
v-show
:同样用于根据条件展示元素。从功能上 v-show 与 v-if 作用是相同的,只是渲染过程有区别。
v-if 与 v-show 的区别:
v-if
是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。v-if
也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。v-show
就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。v-if
有更高的切换开销,而 v-show
有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show
较好;如果在运行时条件很少改变,则使用 v-if
较好。编码过程中,发现网页出现报错:
Uncaught Error: Bootstrap's JavaScript requires jQuery at bootstrap.min.js:6
解决方法:在引进JQuery文件时,将其放在 bootstrap 前面即可。
Title
在使用 vue 进行数据渲染时,如果使用原生 js 事件绑定 (例如 onclick),如果需要获取 vue 实例中的数据并传参则需要通过拼接来完成
vue 提供了 v-on 指令用于绑定各种事件 (v-on:click),简化了从 vue 取值的过程,但是触发的方法需要定义在 vue 实例的 methods 中
v-on:click
可以简写为@click
Title
学号
照片
姓名
性别
年龄
操作
{{s.stuNum}}
{{s.stuName}}
{{s.stuAge}}
(推荐)
有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event
把它传入方法
修饰符是由点开头的指令后缀来表示的。
当使用 v-on 进行事件绑定的时候,可以添加特定后缀,设置事件触发的特性
常用的事件修饰符:
.stop
.prevent
.capture
.self
.once
.passive
.prevent 用来阻止标签的默认行为
.stop 阻止事件冒泡
.self 设置只能自己触发事件(子标签不能触发)
.once 限定事件只能触发一次
按键修饰符:针对键盘事件的修饰符,限定哪个按键会触发事件
常用的按键修饰符:
.enter
.tab
.delete
(捕获“删除”和“退格”键).esc
.space
.up
.down
.left
.right
.enter 只有在 key
是 Enter
时调用(触发 enter
按键之后触发事件)
还可以通过全局 config.keyCodes
对象自定义按键修饰符别名:
// 输入 按键 j 触发事件 test
// 按键 j 的别名
Vue.config.keyCodes.aaa = 74
组合键
示例:CTRL + J 触发事件
常用的修饰符:
.ctrl
.alt
.shift
.meta
windows 键
表单输入绑定,即双向绑定:就是能够将 vue 实例的 data 数据渲染到表单输入视图 (input extareaselect),
也能够将输入视图的数据同步到 vue 实例的 data中。
A
B
C
D
篮球
足球
羽毛球
乒乓球
组件,就是讲通用的 HTML 模块进行封装 —— 可复用的 Vue 实例
通常一个应用会以一棵嵌套的组件树的形式来组织:
将通用的 HTML 模块封装注册到 vue 中
自定义组件 my-components.js:
Vue.component('header-button', {
template: `
`
});
定义组件需要依赖 vue.js,在引用自定义组件 js 文件要先引用 vue.js
组件的引用必须在 vue 实例 el 指定的容器中 ,即要在Vue实例范围内
TitleVue.component()
注册组件data
定义组件的模板渲染的数据template
组件的 HTML 模块(HTML 标签 CSS 样式)methods
定义组件中的标签事件中绑定的 JS 函数my-components.js:
Vue.component('header-button', {
data: function () {
// 组件中 data 是通过函数返回的对象
return {
name: "貂蝉"
};
},
template: `
`,
methods: {
test: function () {
alert("组件中 header-button 定义的函数事件")
}
}
});
Vue 组件封装的结构
注:在编码过程中学到,Vue 中同一个 DOM 元素绑定多个点击事件:可以使用逗号分隔。
Title
vue 实例本身就是一个组件(模板就是 el 指定容器,data 就是组件数据,methods 就是组件的事件函数)
在 vue 实例指定的 el 容器中引用的组件称为子组件,当前 vue 实例就是父组件
注:子组件按钮模板不能触发父组件的方法,子组件的按钮可以触发子组件的方法。
vue 实例引用组件的时候,传递数据到引用的组件中
通过组件的属性实现父组件传递数据到子组件
示意图
props
属性动态传递参数通过子组件的按钮“调用”父组件的函数,通过函数传值
流程示意图
父组件:
Title
子组件传到父组件的标题名称: {{title}}
子组件:
Vue.component('header-bar', {
data: function() {
return {
title: "三国 -- √"
}
},
template: `
`,
props: ["name"],
methods: {
childMethod: function () {
this.$emit("my-event", this.title);
}
}
});
父组件通信子组件
props
: 子组件通过props获取定义父组件传递的自定义属性
this.$refs
: 引用子组件
this.$children
: 父组件childrens属性,存储着所有的子组件
子组件通信父组件(或根组件)
this.$emit
: 子组件通过$emit
访问父组件传递的自定义事件
this.$parent
: 访问父组件
this.$root
: 访问根组件。根组件root就是new Vue({el: "#app"});
中的el元素
当我们自定义 vue 组件时,允许组件中的部分内容在调用组件时进行定义 —— 插槽
slot
标签在组件的模板中定义插槽my-components-bar-slot.js:
Vue.component('header-bar', {
data: function() {
return {
title: "三国 -- √"
}
},
template: `
`,
props: ["name"],
methods: {
childMethod: function () {
this.$emit("my-event", this.title);
}
}
});
示例1:插槽填充 搜索框
示例2:插槽填充 按钮
当组件中的插槽数量 > 1 时,需要给组件中的
slot
标签添加name
属性指定插槽的名字
定义组件
Vue.component(‘page-frame’, {
template:
,
slot1 :
props: [“title”, “cr”]
});
引用组件
slot
标签my-components-bar-slot.js:
Vue.component('page-frame-scope', {
template: `
{{title}}
slot1 :
slot2 :
`,
props: ["title", "cr"],
data: function () {
return {
sites: [
{
"name": "菜鸟教程",
"url": "www.runoob.com"
},
{
"name": "google",
"url": "www.google.com"
},
{
"name": "微博",
"url": "www.weibo.com"
}
]
}
}
});
引用组件时,在填充插槽的模板上使用 slot-scopt
属性获取插槽绑定的值
名称 | 网站 |
---|---|
{{site.name}} | {{site.url}} |
vue 可以实现数据的渲染,但是如何获取数据呢?
vue 本身不具备通信能力,通常结合 axios —— 一个专注于异步通信的 js 框架来使用(Vue.js 2.0 版本推荐使用 axios 来完成 ajax 请求。)
- axios 数据通信
- vue 数据渲染
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
axios
说明文档:https://www.runoob.com/vue2/vuejs-ajax-axios.htmlaxios 提供了多种异步请求方法,实现对 RESTful 风格的支持
axios.get(url).then(function);
使用 response.data 读取 JSON 数据:
axios
.get('json/json_demo.json')
.then(response => (this.info = response.data.sites))
.catch(function (error) {
console.log(error)
})
axios.get(url,{}).then(function);
GET 方法传递参数格式 (使用 axios 的 get 请求传递参数,需要将参数设置在 params 下)
// 直接在 URL 上添加参数 ID=12345
axios.get('/user?ID=12345')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
// 也可以通过 params 设置参数:
axios.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
axios.post(url, {}).then(function);
axios
.post("https://localhost:9098/blog/upload", {
name: "张三",
age: "20"
})
.then(response => (this.info2 = response))
.catch(function (error) {
console.log(error)
})
自定义请求:自定义请求方式、请求参数、请求头、请求体(post)
axios({
url: "https://localhost:9098/blog/upload",
method: "post",
params: {
// 设置请求行传值
name: "张三",
limit: 15
},
headers: {
// 设置请求头
},
data: {
// 设置请求体 (post / put)
}
}).then(function (res) {
console.log(res)
});
当使用别名方法时,不需要在config中指定url,method和data属性。
axios.all()、axios.spread() 两个辅助函数用于处理同时发送多个请求,可以实现在多个请求都完成后再执行一些逻辑。
处理并发请求的助手函数:
- axios.all(iterable)
- axios.spread(callback)
注:两个请求执行完成后,才执行 axios.spread() 中的函数,且 axios.spread() 回调函数的的返回值中的请求结果的顺序和请求的顺序一致
F12 查看控制台输出情况
res 并不是接口返回的数据,而是表示一个响应数据:res.data 才表示接口响应的数据
router 是由 vue 官方提供的用于实现组件跳转的插件。
Vue Router 是 Vue.js (opens new window)官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。
当你要把 Vue Router 添加进来,我们需要做的是,将组件 (components) 映射到路由 (routes),然后告诉 Vue Router 在哪里渲染它们。
Title
-
首页
-
Java
-
Python
-
Vue
点击链接,根据路由,跳转并显示对应的组件模板
*
可以匹配任意路径
例如:
/user-*
匹配所有以 user-
开头的任意路径
/*
匹配所有路径
const my_router = new VueRouter({
routes: [
{
path: ‘/user-’,
component: t4
},
{
path: '/’,
component: t5
}
]
});
注意:如果使用通配符定义路径,需要注意路由声明的顺序
/index/:id
可以匹配/index/
开头的路径
如果一个路径匹配了多个路由,则按照路由的配置顺序:路由定义的越早优先级就越高。
在一级路由的组件中显示二级路由
首页
首页-t2
首页-t3
// 1. 字符串
my_router.push("/index");
// 2. 对象
my_router.push({path: "/index"});
// 3. 命名的路由 name 参数指的是定义路由时指定的名字
my_router.push({name: "r1", params: {id: 101}});
// 4. URL 传值,相当于 /index?id=101
my_router.push({path: "/index", query: {id: 101}});
功能与 push() 一致,区别在于 replace() 不会向 history 添加新的浏览记录
参数为一个整数,表示在浏览器历史记录中前进或后退多少步 相当于
windows.history.go(-1)
的作用
命名路由:在定义路由的时候可以给路由指定 name,我们在进行路由导航时可以通过路由的名字导航
t1
t1
t2
访问 /index
, 重定向到 /login
登录
首页
根据路由命名重定向
// 2. 定义路由
const my_router = new VueRouter({
routes: [
{
path: ‘/login’,
name: “r1”,
component: t1
},
{
path: ‘/index’,
// 根据路由路径重定向
// redirect: “/login”
// 根据路由命名重定向
redirect: {name: “r1”}
}
]
});
登录
(别名)-登录
可以通过 /url/:attr
方式实现通过路由传值给组件
登录
通过 props
传参
首页t2