第一章:基础篇
第1讲:课程介绍
基础篇:Vue核心知识点
生态篇:大型Vue项目所需的周边技术
实战篇:开发基于Vue的Ant Design Pro
福利篇:Vue3.0相关知识介绍
第2讲:Vue简介
发展趋势
什么是vue
1.Vue是一套用于构建用户界面的渐进式框架。
2.与其它大型框架不同的是,Vue被设计为可以自底向上逐层应用。
3.Vue的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。
4.另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue也完全能够为复杂的单页应用提供驱动。
vue有哪些特点
1.更加轻量20kb min+gzip(React35kb,Angular60kb)
2.渐进式框架
3.响应式的更新机制(底层做了处理)
4.学习成本低(如果会html容易上手)
第3讲:内容综述
基础篇:Vue核心知识点
【属性、事件、插槽、个人总结:
(1)如何通过属性传递vnode并在子组件里进行渲染
(2)如何在template语法中使用临时变量】
生态篇:大型Vue项目所需的周边技术【vueRouter|vuex】
实战篇:开发基于Vue的Ant Design Pro【项目足够大】
福利篇:Vue3.0相关知识介绍
第4讲:开发第一个vue程序
1.安装开发环境【官网:https://cn.vuejs.org/v2/guide/installation.html】
2.引入<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
3.模板引擎{{message}} 响应式,支持表达式,不支持语句
2.有哪些指令:
v-bind 简写::bind绑定动态值
v-if、 v-else-if、 v-else 不满足条件的话不渲染
v-show 相当于display:none已挂载DOM节点
v-for eg:v-for="item for items"
第5讲:组件基础及组件注册
1.定义:
它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用。几乎任意类型的应用界面都可以抽象为一个组件树。
2.作用:复用
3.用法:
Vue.component('组件名称',{
props:{
title:String,
del:{
type:Boolean,
default:false
}
},
template:``,
data(){return {}},
methods:{},
});
4.注意事项:
父组件中若有未使用的属性则会传递到子组件的根元素上,组件可以嵌套使用,组件名为唯一的
第6讲:Vue组件的核心概念:事件
可以用v-on指令监听DOM事件,并在触发时运行一些JavaScript代码
1.普通用法 v-on:click="方法名或表达式" 缩写:@click=“fn”
2.组件间通信用法 this.$emit('delete',参数) @delete="fn"
3.事件修改符
v-model="" 实时更新
v-model.lazy=""光标离开才改变
v-model.trim=""去掉前后空格
v-model.number=""先输入数字就会限制输入只能是数字,先字符串就相当于没有加number
@click.stop=""阻止事件冒泡,相当于调用了event.stopPropagation()方法,从内向外执行顺序
@click.prevent阻止默认行为,相当于调用了event.preventDefault()方法,比如表单的提交、a标签的跳转就是默认事件
@click.self=""只有元素本身触发时才触发方法,就是只有点击元素本身才会触发。比如一个div里面有个按钮,div和按钮都有事件,我们点击按钮,div绑定的方法也会触发,如果div的click加上self,只有点击到div的时候才会触发,变相的算是阻止冒泡
@click.once=""只能用一次,无论点击几次,执行一次之后都不会再执行
@keyup.enter
@keyup.13=""
@click.capture=""从外向内执行顺序
@scoll.passive=""没用preventDefault阻止默认动作,可以大大提升滑动的流畅度。
第7讲:Vue组件的核心概念:插槽
1.用法:<slot></slot>
2.作用:分发内容
3.表现方式:
(1)匿名插槽(默认插槽)
(2)具名插槽
方式一:<template v-slot:content><span>内容</span></template> ----name="content"
方式二:<span slot=content>内容</span> ----name="content"
(3)作用域插槽
<template v-slot:pre="{value}"
插槽中的内容{{value}}
</template>
<slot name="pre" :value="value">默认值</slot>
第8讲:理解单文件组件
传统组件用法缺点:
1.全局定义,命名不得重复
2.字符串模板:缺乏语法高亮,换行用\
3.不支持css
4.没有构建步骤:eg:Babel
创建项目:
node安装:
安装vue-cli:npm install -g @vue/cli
查看vue版本:vue --version
创建项目:vue create vue-demo1
实例:传统组件转成vue单文件
可以在main.js全局定义组件Vue.components();
scoped自动生成哈希值
第9讲:双向绑定和单向数据流不冲突
1.input:v-model是语法糖 value 和 @input的缩写
2.自定义事件v-model
eg:
Vue.component('base-checkbox', {
model: {
prop: 'checked',
event: 'change'
},
props: {
checked: Boolean
},
template: `
<input
type="checkbox"
v-bind:checked="checked"
v-on:change="$emit('change', $event.target.checked)"
>
`
})
3. .sync用法
父组件:
<child :isShow.sync="isShow" v-show="isShow"/>
【:isShow.sync="isShow"
@update:isShow="bol=>isShow=bol"语法糖,其实是
@upIsShow="changeIsShow" changeIsShow(bol){this.isShow=bol;}语法糖】
子组件:
this.$emit("update:isShow","xxx");
第10讲:理解虚拟Dom及key属性的作用
Virtual DOM
结构:state(数据)+template(模板)=》DOM树结构(通过算法机制更新dom减少性能消耗)
Virtual DOM Diff(DOM比对)
场景一:移动
场景二:删除、新建
场景三:更新、删除、新建(无key)
场景四:移动
有key提高比较性能,for循环里需要key作为唯一标识符
第11讲:如何触发组件的更新
数据来源:
1.来自父元素的属性
2.来自组件自身的状态data
3.来自状态管理器,如vuex,Vue.observable
状态data vs 属性props
状态是组件自身的数据;
属性是来自父组件的数据;
状态的改变未必会触发更新;
属性的改变未必会触发更新
(当数据改变页面未使用时不更新,不调用updated)
第12讲:合理应用计算属性和侦听器
computed计算属性优势:
1.减少模板中计算逻辑 依赖于相应数据
2.数据缓存
3.依赖固定的数据类型(响应式数据,数据大的时候起到提高性能的作用)
watch侦听器优势:
1.更加灵活、通用
2.watch中可以执行任何逻辑,如函数节流,Ajax异步获取数据,甚至操作DOM
watch多层嵌套写法:
watch:{
"a"(){},
"b.c"(){},
"d":{
handler(val,oldVal){},
deep:true
}
}
computed和watch区别:
1.computed能做到,watch都能做,反之则不行
2.能用computed的尽量用computed
*调用强制更新方法this.$forceUpdate()会更新视图和数据,触发updated生命周期。
第13讲:生命周期的应用场景和函数式组件
函数式组件:
1.函数式组件和普通组件的区别:
(1)渲染快
(2)没有实例,意味着没有this
(3)没有生命周期(没有响应式数据)
2.组件函数的使用
(1) 以局部组件为例,将组件标记为 functional=ture;
因为函数式没有实例,因此组件需要的一切都是通过context参数传递,它是一个包括如下字段的对象:
props:提供所有 prop 的对象
children: VNode 子节点的数组
slots: 一个函数,返回了包含所有插槽的对象
scopedSlots: (2.6.0+) 一个暴露传入的作用域插槽的对象。也以函数形式暴露普通插槽。(函数式组件)
data:传递给组件的整个数据对象,作为 createElement 的第二个参数传入组件
parent:对父组件的引用
listeners: (2.3.0+) 一个包含了所有父组件为当前组件注册的事件监听器的对象。这是 data.on 的一个别名。
injections: (2.3.0+) 如果使用了inject选项,则该对象包含了应当被注入的属性。
eg:作为临时变量,为了重复计算使用var1、var2数据案例
default{
functional:true,
render:(h,ctx)=>{
return ctx.scopedSlots.default && ctx.scopedSlots.default(ctx.props||{})
}
}
<TemplateVar :var1="" :var2="">
<template v-slot="{var1,var2}"></tempalate>
</TemplateVar>
eg:渲染元素案例
var comp2={
props:['cmpData'],
render:function(createElement,context){
return createElement('el-button',{
props:{
type:this.cmpData
}
});
}
}
第14讲:指令的本质是什么
内置指令(语法糖标志位):
v-text、
v-html(不建议存在xss风险)、
v-show(相当于display:none)、
v-if、v-else、v-else-if、
v-for、v-on、v-bind、v-model、
v-slot、
v-pre(大括号的内容不执行逻辑)、
v-cloak(在html中可用)、
v-once(只执行一次 )
自定义指令:
用法:directives:{}
钩子函数 (均为可选):
bind: 只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。
钩子函数的参数:
el:指令所绑定的元素,可以用来直接操作 DOM。
binding:一个对象,包含以下属性:
name:指令名,不包括 v- 前缀。
value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。
oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。
arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"。
modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。
vnode:Vue 编译生成的虚拟节点
oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
eg:案例
<div id="hook-arguments-example" v-demo:foo.a.b="message"></div>
Vue.directive('demo', {
bind: function (el, binding, vnode) {
var s = JSON.stringify
el.innerHTML =
'name: ' + s(binding.name) + '<br>' +
'value: ' + s(binding.value) + '<br>' +
'expression: ' + s(binding.expression) + '<br>' +
'argument: ' + s(binding.arg) + '<br>' +
'modifiers: ' + s(binding.modifiers) + '<br>' +
'vnode keys: ' + Object.keys(vnode).join(', ')
}
})
new Vue({
el: '#hook-arguments-example',
data: {
message: 'hello!'
}
})
输出:
第15讲:常用的高级特性provide/inject
作用:在父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量。
需要注意的是这里不论子组件有多深,只要调用了inject那么就可以注入provider中的数据。而不是局限于只能从当前父组件的prop属性来获取数据。
eg:
1.定义一个parent component
<template>
<div>
<childOne></childOne>
</div>
</template>
<script>
import childOne from '../components/test/ChildOne'
export default {
name: "Parent",
provide: {
for: "demo"
},
components:{
childOne
}
}
</script>
2.定义一个子组件
<template>
<div>
{{demo}}
<childtwo></childtwo>
</div>
</template>
<script>
import childtwo from './ChildTwo'
export default {
name: "childOne",
inject: ['for'],
data() {
return {
demo: this.for
}
},
components: {
childtwo
}
}
</script>
3.定义另一个子组件
<template>
<div>{{demo}}</div>
</template>
<script>
export default {
name: "",
inject: ['for'],
data() {
return {
demo: this.for
}
}
}
</script>
第16讲:如何优雅的获取跨层级组件实例(拒绝递归)
如何获取实例:
<p>hello</p>
this.$refs.xxxx(普通元素获取的是该节点元素;组件获取的是该实例)
this.$parent.xxx
this.$children
多层级获取实例:
callback ref
主动通知(setXxxRef)
主动获取(getXxxRef)
eg:
components:{
ChildrenG
},
inject:{
setChildrenRef:{
}
}
第17讲:template和JSX的对比以及它们的本质
JSX:
1.是一种JavaScript的语法扩展,运用于React架构中,其格式比较像是模版语言,但事实上完全是在JavaScript内部实现的。元素是构成React应用的最小单位,JSX就是用来声明React当中的元素,React使用JSX来描述用户界面。通过插件可以在vue中使用JSX。
2.数据绑定使用单引号
template:
1.是一种模板语法(HTML的扩展)
2.数据绑定使用双大括号{{}}
优点:
第18讲:为什么需要Vuex 状态管理
目的:
1.提供动态注册响应式数据
2.需要命名空间管理、组织数据
3.通过插件记录数据的更改方便调试
vuex应用场景:
第19讲:如何在Vue中使用Vuex
安装步骤:
vue create vuex-demo
default...
cd vuex-demo
npm install vuex (安装vuex)
npm run serve
使用方法:
main.js
import Vuex from 'vuex'
Vue.use(Vuex)
const store=new Vue.Store({
state:{
count:0
},
mutations:{
increment(state,n){
state.count++
}
},
actions:{
increment(state,n){
setTimeout(()=>{
state.count++
})
}
},
getters:{//相当于计算属性,起到缓存的作用
doubleCount(state){
return state*2
}
}
})
new Vue({
store,
reder:h=>h(App),
}).$mount('#app')
App.vue
<button @click="$store.commit('increment',2)"></button>(mutations)
<button @click="$store.dispatch('increment',2)"></button>(actions)
{{$store.getters.doubleCount}}
computed:{
return this.$store.state.count
}
第20讲:Vuex核心概念及底层原理
第21讲:Vuex最佳实践
第22讲:Vue Router使用场景
传统模式:
www.xxx.com ---index.html
www.xxx.com/about --- about.html
www.xxx.com/xxx --- xxx.html
每一个url对应一个html页面,需要重新加载,影响用户体验诞生了单页面(SPA)开发模式
单页面应用优势:
1.监听url的变化,并在变化前后执行相应的逻辑
2.不同的url对应不同的不同的组件
3.提供多种方式改变url的api(url的改变不能导致浏览器刷新)
使用方式:
1.提供一个路由配置表,不同的url对应不同组件的配置
2.初始化路由实例new VueRouter()
3.挂载到Vue实例上
4.提供一个路由占位,用来挂载url匹配到的组件
第23讲:选择何种模式的路由及底层原理
路由类型:
Hash模式:丑,无法使用锚点定位(带有#)
History模式:需要后端配合,Ie9不兼容(可使用强制刷新处理)
使用:
new VueRouter({
mode:'history'
})
底层原理:
第24讲:Nuxt解决了哪些问题?
单页面应用的劣势:
1.不利于SEO(搜索引擎的优化百度搜索爬取排名)解决方案:服务端渲染SSR
2.首屏渲染时间长。解决方案:预渲染Prerendering,eg:home.html/xxx.html;SSR同构,动态渲染、配置繁琐
Nuxt作用:
1.生成静态站点
2.动态渲染
3.简化配置
官网:https://zh.nuxtjs.org/
第25讲:Nuxt核心原理是什么?
第26讲:UI组件库对比:Element UI、Ant Design Vue、iView
第27讲:提升开发效率和体验的常用工具:ESLint、Prettier、vue-devtools
Vetur:
1.vscode插件
2.语法高亮
3.标签补全、模板生成
4.Lint检查
5.格式化
ESLint
1.代码规范
2.错误检查
Prettier
1.格式化
Vue DevTools(chrome插件)
1.集成Vuex
2.可远程调试
3.性能分析
第28讲:单元测试的重要性及其使用
重要性:
1.保证研发质量
2.提高项目的稳定性
3.提高开发速度
使用方式:
1.jest或mocha
2.@vue/test-utils
3.sinon
eg:
vue create test1-demo
Unit Testing
Jest
In dedicaated config files(放在一个独立的文件)
第29讲:生态篇习题解答(上)
1.vuex是通过什么方式提供响应式数据的?
答:new Vue({})
2.扩展简化版的min-vuex,实现getters,并实现vuex的方式注入$store
答:计算属性computed实现getters缓存
beforeCreate中混入$store的获取方式