1.10 开始
尚硅谷Vue2.0+Vue3.0全套教程丨vuejs从入门到精通_哔哩哔哩_bilibili
https://www.bilibili.com/video/BV1Zy4y1K7SH?p=4&spm_id_from=pageDriver

Vue 前言

虚拟DOM

Diff 算法

Vue文档介绍

开发环境

chrome://extensions/ 安装插件 Vue.js devtools

打开 开发者模式
image.png
允许这两项
image.png
然后
image.png

开始整活~

new Vue()

先有容器

,再创建Vue实例

实例跟容器,一一对应

如果绑定的容器有重复(比如两个div class 一样,则Vue 实例就解析第一个div)
如果一个容器有多个Vue 绑定(比如两个new Vue el:’#sample’,则容器由第一个new Vue接管,第二个实例无用)

容器里的代码被称为Vue模板

真实开发中只有一个Vue实例,并且会配合着组件一起使用

{{ xxx }} 中要写 js表达式 ,且xxx 可以自动读取到data中的所有属性

一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新。

js表达式 和 js代码(语句)

  1. 表达式:a, a+b, demo( ) …. 表达式有返回值
  2. js代码(语句):if ( ){ }, for( ){ }

    控制台开发者工具

    image.png

    模板语法

    插值语法

    功能:用于解析标签体内容
    {{ name }} : {{ address}}
    {{ xxx }} 是 js表达式,可直接读取data中的所有属性

    指令语法

    功能:用于解析标签(标签属性,标签体内容,绑定事件 … )

baidu
v-bind 后面的 “url” 为 js表达式,可直接读取data中的所有属性。

v-bind: 简写为 :
baidu

数据绑定(vue中有2种数据绑定方式)

v-bind 单向绑定

数据只能从data 流向页面

v-model 双向绑定

双向绑定:数据不仅能从data流向页面,还可以从页面流向data
v-model 只能用在表单类元素(输入元素)上,比如 input , select 等有value值的 , 有交互才有双向

简写

v-bind:value=”name”, 简写 :value=”name”
v-model 默认收集的就是 value 值,v-model:value=”name”, 简写 :v-model =”name”

el和data的两种写法

el

  1. el:”#root”
  2. const v = new Vue( {} ) ; v.$mount(“#root”)

    data

  3. 对象式。 data:{ name: “ jara” }

  4. 函数式。函数的返回值是数据。 data: function( ){ return{ name: “jara”} }

组件的时候,用函数式的,防止作用域污染。
data 函数没有箭头函数,箭头函数的this不是vue实例,而是window.

架构模型 MVVM,双向数据绑定

image.png
View => DOM (页面结构)=> 模板
data中的所有属性,最后都出现在了vm身上,(数据代理)
vm身上所有属性及vue原型上的所有属性,在vue模板中都可以直接使用

image.png

数据代理(双向绑定原理

1、回顾Object.defineproperty方法

v-model 是靠这个函数实现的
实现数据层到显示层的实时绑定,且不需要重新赋值

2、何为数据代理

通过一个对象代理对另一个对象中的属性的操作 读/写
image.png

3、Vue中的数据代理(底层原理)

一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新。
image.png

事件处理

事件的基本使用:

1、使用 v-on:xxx 或者 @ xxx 绑定事件,其中xxx 是事件名
2、事件的回调需要配置在methods对象中,最终会在vm上
3、methods中配置的函数,不要用箭头函数,否则this就不是vm了
4、methods中配置的函数,都是被Vue管理的函数,this指向vm 或者组件实例对象
5、@ click = “demo” 和 @ click=”demo($event)” 效果一致,但后者可以传参

事件修饰符

image.png
@ click . prevent
一般事件采用冒泡,然后用了.capture 就使用事件的捕获阶段
image.png

键盘事件

image.png

计算属性 computed

姓名案例

插值语法和methods实现

数据发生变化,vue会重新解析模板

计算属性实现

(计算data里的数据)
有缓存,当数据发生变化,会重新加载

定义

要用的属性不存在,要通过已有属性计算得来

原理

低层借助了 Object.defineproperty 方法提供的getter 和 setter

getter 什么时候执行

1、初次读取时会执行一次。
2、当依赖的数据发生改变时,会被再次调用

优势

与 methods 相比,内部有缓存机制(复用),效率更高,调试方便

备注

计算属性最终会出现在vm上,直接读取使用即可
如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变

监视属性 watch

天气案例

当被监视的属性发生变化时,回调函数自动调用,进行相关操作
监视的属性必须存在,才能进行监视
两种写法:
new Vue 时传入 watch 配置
通过vm. $watch 监视

深度监视

Vue中的watch默认不监测对象内部值的改变(一层)
配置 deep:true 可以监测对象内部值的改变(多层)

姓名案例

image.png
watch 可以异步,computed 不可以
image.png

computed 和 watch 的区别

  1. computed 能完成的功能,watch 都可以完成
  2. watch 能完成的功能,computed 不一定能完成,例如,watch 可以进行异步操作

两个重要的小原则:(反正this要指向vm)

  1. 所有被Vue 管理的函数,最好写成普通函数,这样 this 的指向才是vm 或者组件实例对象。
  2. 所有不被Vue 管理的函数(定时器的回调函数、ajax 的回调函数、Promise的回调函数),最好写成箭头函数,这样this 的指向才是vm 或组件实例对象

    绑定样式

class 绑定

image.png

style绑定

image.png

总结

image.png

条件渲染

v-show

频率高的

v-if

频率低的
与 template 配合使用

总结

image.png

列表渲染

基本列表

image.png

key 的原理(虚拟DOM对比算法 diff )

如果不写 key, vue 自动将索引值 index 设为 key。
image.png
image.png

key 总结 !

image.png

列表过滤

watch 实现

image.png

computed 实现 (better)

image.png

列表排序

image.png
image.png

更新时的一个问题

Vue检测数据改变的原理

模拟一个数据检测 ??WTF

底层源码
这个不太懂。。。
Vue 监视的是数组这个对象,没有监视数组里面的元素

vue.set 的使用

大总结!Vue 监视数据的原理

vue会监视data中所有层次的数据

如何监测对象中的数据?

通过 setter 实现监视,且要在 new Vue 时就传入要监测的数据。
1、对象中追加的属性,Vue 默认不作响应式处理
2、如需给后添加的属性做响应式,请用如下API :
Vue.set(target, propertyName / index , value) 或
vm.$set(target, propertyName / index , value)

如何监测数组中的数据?

通过包裹数组更新元素的方法实现。本质就是做了两件事:
1、调用原生对应的方法对数组进行更新。
2、重新解析模板,进而更新页面。

在Vue修改数组中的某个元素一定要用如下方法:

1、使用这些API : push( ) 、pop( ) 、shift( ) 、unshift( )、splice( )、sort( )、reverse( )
2、Vue.set( ) 或 vm.$set( )
特别注意:Vue.set( ) 和 vm.$set( ) 不能给 vm 或 vm 的根数据对象 添加属性

收集表单数据

, 则v-model 收集的是value值,用户输入的就是value值
, 则v-model 收集的是value值,要标签配置value值

1、没有配置 input的 value 属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)
2、配置input的value属性:
(1)v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)
(2)v-model的初始值是数组,那么收集的就是value 组成的数组
备注:v-model 的三个修饰符:
lazy : 失去焦点再收集数据
number : 输入字符串转为有效的数字
trim : 输入首位空格过滤

过滤器

本质是个函数,可以对前面写的数据进行某种形式加工处理
管道符 |
定义:对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)。
语法:
1、注册过滤器:Vue.filter(name, callback) 或 new Vue{ filters:{ } }
2、使用过滤器:{{ xxx | 过滤器名 }} 或 v-bind:属性=”xxx | 过滤器名”
备注:
1、过滤器也可以接收额外参数、多个过滤器也可以串联
2、并没有改变原本的数据,是产生新的对应的数据

内置指令

image.png

v-text

image.png

v-html

  1. 作用:向指定节点中渲染包含html 结构的内容
  2. 与插值语法的区别:
    1. v-html会替换掉节点中所有内容,{{ xx }} 则不会
    2. v-html 可以识别 html 结构
  3. 严重注意:v-html 有安全性问题!!

    1. 在网站上动态渲染任意html 是非常危险的,容易导致 xss 攻击
    2. 一定要在可信的内容上使用v-html, 永不要用在用户提交的内容上

      v-cloak

      image.png
  4. 没有值的,本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性

  5. 使用css配合v-cloak 可以解决网速慢时页面展示出 {{ xxx }} 的问题

    v-once

  6. v-once 所在节点在初次动态渲染后,就视为静态内容了。

  7. 以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。

    v-pre

  8. 跳过其所在节点的编译过程。就是不用vue解析它了。

  9. 可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。

    自定义指令

    image.png

    总结

    image.png

    生命周期

    引入生命周期

    mounted()
    Vue 完成模板的解析并把最初的真实DOM元素放入页面后(挂载完毕)调用mounted
    特殊时间点 调用方法
    image.png

    生命周期.png

    挂载流程

    image.png

    更新流程

    image.png

    销毁流程

    image.png

    总结

    四对
    image.png
    初始化的事在 mounted()
    收尾的事在 beforeDestroy()
    image.png

    Vue组件化编程

    对组件化的理解

    封装 复用
    image.png
    image.png

    非单文件组件

    一个文件中包含n个组件

    单文件组件

    一个文件中只包含一个组件

    基本使用,创建组件

    image.png
    image.png
    image.png
    image.png

    几个注意点

    image.png

    组件的嵌套

根节点之外的嵌套组件:
image.png
image.png

VueComponent

image.png

Vue 实例 与 组件 Vc 实例

image.png

一个重要的内置关系:vc可以访问到vue原型上的属性和方法

image.png
image.png

单文件组件

.vue == .css + .html + .js
image.png
image.png
image.png

使用Vue脚手架 CLI (command line interface)

第一次安装 cli

image.png

分析脚手架结构

  1. ├── node_modules
  2. ├── public
  3. ├── favicon.ico: 页签图标
  4. └── index.html: 主页面
  5. ├── src
  6. ├── assets: 存放静态资源
  7. └── logo.png
  8. │── component: 存放组件
  9. └── HelloWorld.vue
  10. │── App.vue: 汇总所有组件
  11. │── main.js: 入口文件
  12. ├── .gitignore: git版本管制忽略的配置
  13. ├── babel.config.js: babel的配置文件
  14. ├── package.json: 应用包配置文件
  15. ├── README.md: 应用描述文件
  16. ├── package-lock.json:包版本控制文件

image.png

render 函数

image.png
(log加tab直接出来console.log)

关于不同版本的Vue

  1. vue.js与vue.runtime.xxx.js的区别:
    1. vue.js是完整版的Vue,包含:核心功能 + 模板解析器。
    2. vue.runtime.xxx.js是运行版的Vue,只包含:核心功能;没有模板解析器。
  2. 因为vue.runtime.xxx.js没有模板解析器,所以不能使用template这个配置项,需要使用render函数接收到的createElement函数去指定具体内容。

    修改默认配置 vue.config.js

  3. 使用vue inspect > output.js可以查看到Vue脚手架的默认配置。

  4. 使用vue.config.js可以对脚手架进行个性化定制,详情见:https://cli.vuejs.org/zh

    ref 属性

  5. 被用来给元素或子组件注册引用信息(id的替代者)

  6. 应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)
  7. 使用方式:

    1. 打标识:<h1 ref="xxx">.....</h1><School ref="xxx"></School>
    2. 获取:this.$refs.xxx

      Props 配置

  8. 功能:让组件接收外部传过来的数据

  9. 传递数据:<Demo name="xxx"/>
  10. 接收数据:
    1. 第一种方式(只接收):props:['name']
    2. 第二种方式(限制类型):props:{name:String}
    3. 第三种方式(限制类型、限制必要性、指定默认值):
      1. props:{
      2. name:{
      3. type:String, //类型
      4. required:true, //必要性
      5. default:'老王' //默认值
      6. }
      7. }

      备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。

mixin 混入

  1. 功能:可以把多个组件共用的配置提取成一个混入对象
  2. 使用方式:
    第一步定义混合:
    第二步使用混入:
    全局混入:Vue.mixin(xxx)
    局部混入:mixins:['xxx']

    {
    data(){....},
    methods:{....}
    ....
    }
    

    scoped 样式

  3. 作用:让样式在局部生效,防止冲突。

  4. 写法:<style scoped>

    插件

  5. 功能:用于增强Vue

  6. 本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据。
  7. 定义插件:

    对象.install = function (Vue, options) {
    // 1. 添加全局过滤器
    Vue.filter(....)
    
    // 2. 添加全局指令
    Vue.directive(....)
    
    // 3. 配置全局混入(合)
    Vue.mixin(....)
    
    // 4. 添加实例方法
    Vue.prototype.$myMethod = function () {...}
    Vue.prototype.$myProperty = xxxx
    }
    
  8. 使用插件:Vue.use()

    to-do-list 案例

    首先实现 静态页面

    image.png

    初始化列表

    image.png

    添加 功能

    nanoid 库:生成唯一的Id
    image.png

    组件间通讯(低级:通过父组件) 后面会学其他高级方法

    子组件里面的数据想要传给父组件,需要前提:父组件先定义一个函数方法,并且将这个函数方法传给子组件,然后子组件的数据代入为函数形参,这样父组件就可以有子组件的数据了。
    参数变了,vue 会重新解析模板。

    props 用法

    有个细节就是 其实子组件的props里面的属性 实际上是对父组件绑定的属性的代理
    image.png
    image.png

    勾选功能

    方法一:组件之间props传方法

    数据在哪,方法在哪
    data 在 App.vue,则在这里写勾选方法
    所以老师说了数据在哪里,你的增删改查就在哪里,不要在接收数据传递过去的子组件里面改,子组件也就是给给参数,通知哪个东西要改了。
    数据在哪个组件就在哪个组件去修改它,这样方便维护。

App.vue -> MyList.vue -> MyItem.vue , 勾选方法从App.vue 传到孙子组件 MyItem.vue ,连续传两次。
image.png
image.png
image.png

方法二:v-model

不建议
image.png

  • 这个和const定义的数据一样,用const定义对象,对象里面的数据增删都会报错,但是修改对象数据的值是没问题的。
  • a变量引用一个基本数据类型,值变了,a就变了。a引用一个引用数据类型(对象),若a没有引用新对象,即使对象的属性值变了,a也没有变化。除非a引用了新对象。
  • 如果其他子组件也用到这个数据,两个同时修改会发生不可预料的后果。
  • 前面的methods方法是从props中拿到id传到app然后在app中修改data数据的不是直接修改的props

    删除功能

    image.png

    底部统计功能

    数组函数 reduce() :

    reduce() 方法对数组中的每个元素执行一个由开发者自己提供的函数,将其结果汇总为单个返回值。
    可以理解为,reduce会遍历数组元素,将每个元素都作为参数,代入自定义函数执行并返回一个返回值。并在下一次执行时将返回值作为参数传入。
    array.reduce(()=>{}, 0) : 第一个参数是要执行的函数,第二个参数是初始值。
    数组的长度 == 被调用的次数
    image.png

    总结TodoList案例

  1. 组件化编码流程:
    (1).拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突。
    (2).实现动态组件:考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用:
    1).一个组件在用:放在组件自身即可。
    2). 一些组件在用:放在他们共同的父组件上(状态提升)。
    (3).实现交互:从绑定事件开始。
  2. props适用于:
    (1).父组件 ==> 子组件 通信
    (2).子组件 ==> 父组件 通信(要求父先给子一个函数)
  3. 使用v-model时要切记:v-model绑定的值不能是props传过来的值,因为props是不可以修改的!
  4. props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但不推荐这样做。