极客时间-vue开发实战笔记

2,374 阅读5分钟

第一章:基础篇

第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应用场景:

涉及到数据流问题:

vuecomonents作用:独立存储响应式数据 Actions作用:起到异步获取数据 Devtools作用:起到跟踪数据变化的作用

第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最佳实践

购物车案例:

computed:mapState({ products:state=>state.products.all, xxxxxxxx:xxxxxxxxxx, yyyyyyyy:yyyyyyyyyy }),*比 计算属性方便

开启命名空间: namespaced:true 源代码地址: github.com/geektime-ge…

第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的获取方式