内容很饱满,过程可能会枯燥,愿你经过风雨,过后能成为不一样的烟火🎇,为了奖励看到最后的小伙伴,博主为你们准备了礼物哦
目录
开始使用Vue
el
$mount
data
插值表达式
vue的响应式-1
vm.$el
vm.$nextTick & Vue.nextTick
vue的响应式-2
扩展_剖析Vue响应式原理
Vue相关指令
v-pre
v-cloak
v-once
v-text
v-html
条件渲染
v-if
v-else
v-else-if
v-show
v-if VS v-show
v-bind 指令
v-on指令
为什么在 HTML 中监听事件?
v-on指令的修饰符
事件修饰符
.stop
.prevent
.capture
.self
.once
.passive
注意
按键修饰符
按键码
系统修饰键
exact 修饰符
鼠标按钮修饰符
列表渲染
在v-for中使用数组
在v-for中使用对象
在v-for中使用数字
在v-for中使用字符串
循环一段包含多个元素的内容
关于key
key的使用方法
v-for 和 v-if 一同使用
练习_仿淘宝商品筛选
练习_todoList
v-model指令
input
type=text 文本框
type=checkbox 复选框
type=radio 单选框
textarea
select
单选
多选
修饰符
.lazy
.number
.trim
练习_简易计算器
练习_调查问卷
计算属性
基础用法
计算属性 vs 方法
深入计算属性
getter 读取
setter 设置
练习_姓名筛选
练习_全选商品
侦听器
值类型
函数类型
字符串类型
对象类型
数组类型
键类型
正常对象key值
字符串类型key值
vm.$watch
侦听器 vs 计算属性
练习_仿百度搜索联想
vue-resource
引入vue-resource
请求方法
POST请求
GET请求
PUT请求
PATCH请求
DELETE请求
HEAD请求
JSONP请求
options 参数说明
响应对象
属性
方法
最后的话
Axios
引入
API
config 配置对象
方法别名
配置默认值
全局配置
实例配置
请求配置
配置的优先顺序
并发
拦截器
请求拦截器
响应拦截器
移除拦截器
为axios实例添加拦截器
取消请求
错误处理
axios 预检
template 选项
Vue生命周期
生命周期图示
生命周期钩子
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
beforeDestroy
destroyed
练习_bilibili首页
组件基础
组件是什么?
组件注册
全局组件
局部组件
组件名
组件复用
自闭合组件
组件的data选项
单个根元素
组件_Prop
注册自定义特性
Prop的大小写
传递静态或动态 Prop
传递一个对象的所有属性
组件_Prop验证
组件_单向数据流
组件_非Prop特性
替换/合并已有的特性
禁用特性继承
组件_监听组件事件
使用事件抛出一个值
事件名
将原生事件绑定到组件
在组件上使用 v-model
.sync 修饰符
v-model VS .sync
组件_插槽
插槽内容
编译作用域
后备内容
具名插槽
作用域插槽
独占默认插槽的缩写语法
解构插槽Prop
动态插槽名
具名插槽的缩写
废弃了的语法
带有slot特性的具名插槽
带有slot-scope特性的作用域插槽
组件_动态组件
基本使用
keep-alive
activated & deactivated
组件_处理边界情况
访问元素 & 组件
访问根实例
访问父级组件实例
依赖注入
访问子组件实例或子元素
程序化的事件侦听器
循环引用
递归组件
组件之间的循环引用
模板定义的替代品
内联模板
X-Template
控制更新
强制更新
通过v-once创建低开销的静态组件
组件_通信
prop
$emit
v-model
.sync
$attrs
$listeners
$root
$parent
$children
ref
provide & inject
eventBus(事件总线)
Vuex
混入
基础
选项合并
全局混入
自定义指令
简介
钩子函数
bind
inserted
update
componentUpdated
unbind
钩子函数参数
练习
模拟 v-show
模拟 v-model
写一个 v-slice(截取文本框)
动态指令参数
函数简写
对象字面量
过滤器
定义过滤器
参数
过滤器串联
练习
首字母大写
数字中间加上逗号
数字添加文字“万”
安装脚手架
安装@vue/cli
快速原型开发
安装vscode插件
练习_树形组件
利用脚手架搭建项目
渲染函数
基础
节点、树、以及虚拟DOM
虚拟DOM
createElement参数
深入数据对象
使用JavaScript代替模板功能
v-if 和 v-for
v-model
事件&按键修饰符
插槽
JSX
插值
指令
v-text
v-html
v-show
v-if
v-for
v-on
v-bind
v-model
v-slot
v-pre
v-cloak
v-once
Ref
自定义指令
过滤器
插槽
函数式组件
slots() VS children
基于模板的函数式组件
过渡_单元素过渡
单元素/组件的过渡
过渡的类名
类名前缀
CSS 动画
自定义过渡的类名
同时使用过渡和动画
显性的过渡时间
初始渲染的过渡
JavaScript 钩子
过渡_多元素过渡
过渡模式
多组件过渡
过渡_列表过渡
列表的排序过渡
列表的交错过渡
过渡_复用过渡
组件_异步组件
VueRouter_基础
什么是路由?
什么时候使用前端路由?
安装路由
使用路由
JavaScript
html
router-link class
hash模式
history 模式
VueRouter_命名路由-嵌套路由-重定向-别名
命名路由
嵌套路由
重定向
别名
VueRouter_编程式的导航
$router
$router.push
$router.replace
$router.go(n)
$route
$route.path
$route.params
$route.query
$route.hash
$route.fullPath
$route.matched
$route.name
$route.redirectedFrom
VueRouter_动态路由匹配
VueRouter_命名视图-路由组件传参
命名视图
路由组件传参
布尔模式
对象模式
函数模式
VueRouter_导航守卫
全局守卫
全局前置守卫 beforeEach
全局解析守卫 beforeResolve
全局后置钩子 afterEach
路由独享守卫
beforeEnter
组件内守卫
beforeRouteEnter
beforeRouteUpdate
beforeRouteLeave
完整的导航解析流程
VueRouter_路由元信息
VueRouter_过渡动效-滚动行为
过渡动效
滚动行为
Vuex_State
安装
使用
State
在Vue组件中获得Vuex状态
mapState 辅助函数
Vuex_Getter
通过属性访问
通过方法访问
mapGetters 辅助函数
Vuex_Mutation
在组件中提交 Mutation
提交载荷(Payload)
对象风格的提交方式
使用常量替代 Mutation 事件类型
Mutation 需遵守 Vue 的响应规则
表单处理
双向绑定的计算属性
Mutation 必须是同步函数
严格模式
开发环境与发布环境
Vuex_Action
分发Action
组合 Action
Vuex 管理模式
Vuex_Module
命名空间
模块的局部状态
最后
开始使用Vue
引入vue.js
引入vue.js后,给我们提供了一个构造函数 Vue
在js中,new Vue()
new Vue() 后会返回一个vue实例对象,我们用变量接着它
const vm = new Vue()
传递一个配置对象{} -- > const vm = new Vue({})
el
<!-- 被Vue控制的区域,我们称之为模板 --> <div id="app"></div>
const vm = new Vue({ el: '#app' // 控制id为app的元素 })
$mount
- 作用和el一致,都是配置控制的元素,使用哪个都可以,二选一
<div id="app"></div>
const vm = new Vue({}) vm.$mount('#app');
问:和el有什么不同?
data
- 类型:对象
- 作用:存放要用到的数据,数据为响应式的
const vm = new Vue({ el: '#app', data: { 'mrDeng': '风姿绰约、花枝招展' } })
插值表达式
- 使用方法: {undefined{ }}
- 可以将vue中的数据填在插值表达式中,如:
<div id="app">{{ mrDeng }}</div>
const vm = new Vue({ el: '#app', data: { mrDeng: '邓哥:风姿绰约、花枝招展' } })
除了填写data之外,还可以直接填写数据值(数字、字符串、布尔值、undefined、null、数组、对象),如:
<div id="app"> {{ 5201314 }} {{ '婀娜多姿、亭亭玉立' }} {{ true }} {{ ['邓旭明', '小刘', '王小宝'] }} {{ {name: '邓旭明', age: 80, height: '140cm', weight: '100kg'} }} </div>
注意:在插值表达式中直接书写对象类型值时,不要将三个{}连在一起,这样会报错,如:<div id="app"> <!-- 这样可是不行滴 --> {{{name: '邓旭明', age: 80, height: '140cm', weight: '100kg'}}} </div>
还可在插值表达式中写表达式,如:
<div id="app"> <!-- 运算表达式 --> {{ 'you' + 'me' }} {{ 10 - 5 }} {{ 100 * 7 }} {{ 1000 / 12 }} <!-- 逻辑表达式 --> {{ liu || li }} {{ deng && liu }} {{ !wang }} <!-- 三元表达式 --> {{ 1 + 1 === 3 ? '邓旭明' : '正常人' }} <!-- 函数调用也是表达式,也可以使用,这个以后再学哈... --> </div>
还可以填写其他的吗?不可以,No,以下这些都是不行滴:
<div id="app"> <!-- 这是语句,不可以写在插值表达式中 --> {{ var Deng = 'shuaige'; console.log(deng) }} <!-- 流程控制也不可以 --> {{ if(Deng.looks === 'shuai'){ console.log('不可能')} }} </div>
- 记住:插值表达式中,可以写:data、js数据、表达式,其他的想都不要想。
- 注意,只要插值表达式中使用了数据,必须在data中声明过,否则会报错
<!-- 此时就报错啦,因为mrCheng,未在data中声明过 --> <div id="app"> {{ mrCheng }} </div>
const vm = new Vue({ el: '#app', data: { mrDeng: '邓哥:风姿绰约、花枝招展' } })
还有另外一种可能,使用了未被声明过的数据,不报错:
<!-- 此时不报错啦,why? --> <!-- 在作用域上找不到,报错 --> <!-- 在原型链上找不到,值为undefined --> <!-- undefined为js基本类型值,所以就不报错啦 --> <div id="app"> {{ mrDeng.wife }} </div>
const vm = new Vue({ el: '#app', data: { mrDeng: { name: '邓旭明', age: 80, height: '140cm', weight: '100kg' } } })
vue的响应式-1
- 数据变化,页面就会重新渲染
- 怎么更改数据?so easy
<div id="app"> {{ mrDeng }} </div>
const vm = new Vue({ el: '#app', data: { mrDeng: '邓哥:风姿绰约、花枝招展' } }); vm.mrDeng = '手如柔荑、肤如凝脂'; // 见证奇迹的时刻,页面变化啦
问:为什么data会直接出现在vm实例对象中咧?问:实例中除了data数据外,其他东西是啥子?
- 更改的数据必须是存在的数据,否则不能重新渲染页面,因为他监听不到,如:
<!-- 即使更改了数据,也不会重新渲染页面 --> <div id="app"> {{ mrDeng.wife }} </div>
const vm = new Vue({ el: '#app', data: { mrDeng: { name: '邓旭明', age: 80, height: '140cm', weight: '100kg' } } }) vm.mrDeng.wife = 'liu';
- 更改的数据必须已渲染过的数据,否则从性能角度考虑,不会重新渲染页面,如:
<!-- 即使更改了数据,也不会重新渲染页面 --> <div id="app"> {{ mrDeng.wife }} </div>
<!-- 即使更改了数据,也不会重新渲染页面 -->
<!-- 即使更改了数据,也不会重新渲染页面 --> <div id="app"> {{ mrDeng.wife }} </div>
const vm = new Vue({ el: '#app', data: { msg: '邓哥:风姿绰约、花枝招展', mrDeng: { name: '邓旭明', age: 80, height: '140cm', weight: '100kg' } } }) vm.mrDeng.wife = 'liu'; vm.msg = '邓哥:手如柔荑、肤如凝脂';
更改数据后,页面会立刻重新渲染吗?
<div id="app">{{ msg }}</div>
const vm = new Vue({ el: '#app', data: { msg: '杉杉' } }) vm.msg = '杉杉超美的'; console.log(vm.msg); // 杉杉超美的,此时数据已更改 console.log(vm.$el.innerHTML); // 杉杉。此时页面还未重新渲染
vm.$el
- 值为被Vue控制的元素(或者说,Vue挂载的元素)
vm.$nextTick & Vue.nextTick
- 如何在更改数据后,看到渲染后的页面上的值?
<div id="app">{{ msg }}</div>
const vm = new Vue({ el: '#app', data: { msg: '杉杉' } }) vm.msg = '杉杉超美的'; console.log(vm.msg); // 杉杉超美的,此时数据已更改 // 1. 使用vm.$nextTick vm.$nextTick(() => { console.log(vm.$el.innerHTML); // 杉杉超美的 }) // 2. 使用Vue.nextTick Vue.nextTick(() => { console.log(vm.$el.innerHTML); // 杉杉超美的 })
- vm.nextTick和Vue.nextTick还可以作为Promise使用
<div id="app">{{ msg }}</div>
const vm = new Vue({ el: '#app', data: { msg: '杉杉' } }) vm.msg = '杉杉超美的'; // 1. 使用vm.$nextTick vm.$nextTick().then(() => { console.log(vm.$el.innerHTML); // 杉杉超美的 }) // 2. 使用Vue.nextTick Vue.nextTick().then(() => { console.log(vm.$el.innerHTML); // 杉杉超美的 })
vm.$nextTick 和 Vue.nextTick的区别?
Vue.nextTick(function () { console.log(this); // window })
vm.$nextTick(function () { console.log(this); // vm实例 })
- 好奇nextTick是怎么实现的吗?
- 异步任务分为宏任务(macro)和微任务(micro)
- 宏任务比较慢(如setTimeout等),微任务比较快(如Promise.then()等)
- 微任务在前,宏任务在后(eventloop,事件环)
// 控制台打印顺序:promise > timeout setTimeout(() => { console.log('timeout'); }, 0) Promise.resolve().then(() => { console.log('promise'); })
在nextTick的实现源码中,会先判断是否支持微任务,不支持后,才会执行宏任务
if(typeof Promise !== 'undefined') { // 微任务 // 首先看一下浏览器中有没有promise // 因为IE浏览器中不能执行Promise const p = Promise.resolve(); } else if(typeof MutationObserver !== 'undefined') { // 微任务 // 突变观察 // 监听文档中文字的变化,如果文字有变化,就会执行回调 // vue的具体做法是:创建一个假节点,然后让这个假节点稍微改动一下,就会执行对应的函数 } else if(typeof setImmediate !== 'undefined') { // 宏任务 // 只在IE下有 } else { // 宏任务 // 如果上面都不能执行,那么则会调用setTimeout }
- 曾经vue用过的宏任务
- MessageChannel 消息通道 宏任务
vue的响应式-2
- 除了未被声明过和未被渲染的数据外,还有什么数据更改后不会渲染页面?
<!-- 即使向数组中添加了第4项,数组仍然显示3项 --> <!-- 咳咳,一家三口,有第4个人也不能摆出来给大家看呀~ --> <div id="app">{{ list }}</div>
const vm = new Vue({ el: '#app' data: { dengFamily: ['邓哥', '小刘', '王小宝'] } }) vm.dengFamily[3] = '铁锤妹妹'; // 不是响应式的