Vue2 第一弹 —— 声明式渲染

001 —— 初识 Vue

vue

查看 @vue/cli 版本,确保 @vue/cli 版本在 4.5.0 以上
vue --version
安装或升级你的 @vue/cli (全局覆盖安装)
npm install -g @vue/cli
创建
vue create xxxx
启动
cd xxxx
npm run serve

使用方法

  1. 准备好一个容器
  2. 创建 Vue 实例。
  3. el 用于指定当前 Vue 实例为哪个容器服务,值通常为 css 选择器字符串。
  4. data 用于存储数据,数据供 el 所指定的容器去使用,值我们暂时写成一个对象.

详细解答

1. 想让 Vue 工作,就必须创建一个 Vue 实例,且传入一个配置对象;
2. 容器里的代码依然符合 html 规范,只不过混入了一些特殊的 Vue 语法;
3. 容器里的代码被称为 [ Vue 模板 ];
4. Vue 实例和容器是一一对应的;
5. 真实开发中只有一个 Vue 实例,并且会配合着组件一起使用;
6. `{{xxx}}` 中的 xxx 要写 js 表达式,且 xxx 可以自动读取到 data 中的所有属性;
7. 一旦 data 中的数据发生改变,那么模板中用到该数据的地方会自动更新;

002 —— Vue 的模板语法

Vue 的模板语法有 2 大类

插值语法:

1. 功能:用于解析标签体内容
2. 写法:`{{xxx}}`, xxx 是 js 表达式,且可以直接读取 data 中的所有属性。

指令语法:

1. 功能:用于解析标签(包括:标签属性、标签体内容、绑定事件...)
2. 写法:v-bind:href="xxx" 或简写为 :href="xxx", xxx 同样要写 js 表达式,且可以直接读取到 data 中的所有属性。
备注:Vue 中有很多指令,且形式都是:v-????, 此处我们只是拿 v-bind 举个例子。

003 —— Vue 的数据绑定

Vue 中有2种数据绑定的方式

1. 单向绑定(v-bind): data 修改时,页面绑定了 data 的部分会跟着修改。
2. 双向绑定(v-model): data 修改时,绑定的输入域跟着修改;绑定的输入域被修改时,data 跟着修改。

备注:
双向绑定的本质:属性绑定 + 事件监听,可以理解成将这 2 个条件合二为一的语法糖。
双向绑定一般都应用在表单元素上(如:input、select等),后续也可以应用于组件。

对于 input[type=text]v-model:value="xxx" 可以简写为 v-model="xxx",因为 v-model 默认优先收集 value 的值。
对于 checkboxradio,在使用 v-model 后,还要显式指定 value 的值供 v-model 读取。

004 —— el 和 data 的两种写法

data 与 el 的 写法

el 有 2 种写法

 1. new Vue 时候配置 el 属性。
 2. 先创建 Vue 实例,随后再通过 vm.$mount('#root') 指定 el 的值。

el 的写法

vue3 出现以后,最新写法为:通过 Vue.createApp() 传入配置对象,创建 Vue 实例,然后使用 app.mount('#app') 指定 el 的值

data 有 2 种写法

1. 对象式
2. 函数式
    > 如何选择:目前哪种写法都可以,以后学习到组件时, data 必须使用函数式,否则会报错。

一个重要的原则:由 Vue 管理的的函数,一定不要写箭头函数,一旦写了箭头函数, this 就不再是 Vue 实例了。

005 —— MVVM 模型

MVVM 模型

M:模型(model):data 中的数据
V:视图(View):模板代码
VM:视图模型(ViewModel):Vue 实例

观察发现:
1. data 中所有的属性,最后都出现在 vm 身上。
2. vm 身上所有的属性及 Vue 原型上所有的属性,在 Vue 模板中都可以直接使用。

理论(响应式):

Vue 通过数据劫持,在数据原有的读写操作上附加了依赖绑定、依赖重放、模板渲染等操作,实现了 data 改变,页面模板也能跟着变化。
Vue 通过事件监听实现页面模板到 data 的响应式变化。

实践(声明式渲染):

我们不需要操作 dom 元素,只需要专注于操作数据,就能完成页面渲染。

006 —— Vue 中的数据代理

通过 vm 对象来代理 data 对象中属性的操作(读/写)

Vue 中数据代理的好处:

更加方便地操作 data 中的数据

基本原理:

1. 通过 Object.defineProperty() 把 data 对象中所有属性添加到 vm 上。
2. 为每一个添加到 vm 上的属性,都指定一个 getter/setter。
3. 在 getter/setter 内部去操作(读/写)data 中对应的属性。

007 —— 事件处理

事件的基本使用:

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

Vue 中的事件修饰符:

  1. prevent:阻止默认事件(常用);
  2. stop:阻止事件冒泡(常用);
  3. once:事件只触发一次(常用);
  4. capture:使用事件的捕获模式;
  5. self:只有 event.target 是当前操作的元素时才会触发事件;
  6. passive:事件的默认行为立即执行,无需等待事件回调执行完毕;

Vue 中的键盘事件:

Vue 中常见的键盘别名
回车 => enter
删除 => delete (捕获“删除”和“退格”键)
退出 => esc
空格 => space
换行 => tab (特殊,必须配合 keydown 去使用)
上 => up
下 => down
左 => left
右 => right

  1. Vue 未提供别名的按键,可以使用按键原始的 key 值去绑定,但注意要转为 kebab-case(短横线命名)

  2. 系统修饰键(用法特殊):ctrl、alt、shift、meta

       1. 配合 keyup 使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发
       2. 配合 keydown 使用:正常触发事件
    
  3. 也可以使用 keyCode 去指定具体的按键(不推荐)

  4. Vue.config.keyCodes.自定义别名 = 键码,可以去定制按键别名

008 —— 计算属性

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

原理: 底层借助了 Object.defineProperty() 方法提供的 getter 和 setter。

优势: 与 method 实现相比,内部有缓存机制(复用),效率更高,调试方便。

传入计算属性的 getter 函数什么时候执行?

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

备注:

  1. 计算属性最终会出现在 vm 上,直接读取使用即可。
  2. 如果对计算属性进行写入操作,那必须写 setter 函数去响应修改,且 setter 中要引起计算时依赖的数据发生更改。

009 —— 监视属性 watch

当被监视的属性变化时,回调函数自动调用,进行相关操作
监视的属性必须存在,才能进行监视!!!

监视的两种写法:

  1. new Vue 时传入 watch 配置
  2. 通过 vm.$watch 监视

深度监视

  1. Vue 中的 watch 默认不监视对象內部值的改变(一层)。
  2. 配置 deep:true 可以监视对象内部值的改变(多层)。

备注:
Vue 自身可以监视对象内部值的改变,但 Vue 提供的 watch 默认不可以!
使用 watch 时根据数据的具体结构,决定是否使用深度监视。

computed 和 watch 之间的区别
1. computed 能完成的功能,watch 都可以完成。
2. watch 能完成的功能,computed 不一定能完成,例如:watch 可以进行异步操作。

两个重要的小原则:
1. 被 Vue 所管理的函数,最好写成普通函数,这样 this 的指向才是 vm 或组件实例对象。
2. 所有不被 Vue 所管理的函数(setTimeout 定时器的回调函数,axios 的回调函数,promise 的回调函数等),最好写成箭头函数
这样 this 的指向才是 vm 或组件实例对象。

010 —— 绑定样式

class 样式

写法:class = “xxx” xxx 可以是字符串、对象、数组。

绑定 class 样式 —— 字符串写法,适用于:动态指定样式类名
绑定 class 样式 —— 数组写法,适用于:动态配置样式个数
绑定 class 样式 —— 对象写法,适用于:动态决定个别样式是否生效

style 样式

:style = "{fontSize:xxx}" 其中 xxx 是动态值。
:style = "[a,b]" 其中 a、b 是样式对象。 

011 —— 条件渲染

v-if

适用于:切换频率 的场景。
特点:不展示的 DOM 元素直接被移除出 DOM 树。

v-if = "表达式"
v-else-if = "表达式"
v-else

注意:v-if 可以和 :v-else-if、v-else 一起使用,但要求结构不能被“打断”。

v-show

适用于:切换频率 的场景。
特点:不展示的 DOM 元素是使用 display:none 隐藏掉。

v-show = "表达式"

备注:使用 v-if 的时候,元素可能无法捕获到,而使用 v-show 一定能捕获到。

012 —— 列表渲染

v-for 指令

  1. 用于展示列表数据

  2. 语法 v-for = “(item,index) in xxx” :key=“yyy”

  3. 可遍历:数组、对象、字符串、按数字遍历指定次数

     数组:(item,index)
     对象:(value,key,index)
     字符串:(char,index)
     数字:(number,index)
    

013 —— 收集表单数据

text

1
<input type="text" v-model="input"/>

v-model 关联输入框,等于同时绑定了 value 属性,监听 input 事件。数据为每次输入后的文本框内容。


radio

1
2
<input type="radio" v-model="radio" value="已婚"/>
<input type="radio" v-model="radio" value="未婚"/>

将同一组 radio 关联同一个 v-model,则数据为选中 radio 的 value 值。


checkbox

1
2
3
<input type="checkbox" v-model="checkbox" value="喜欢足球"/>
<input type="checkbox" v-model="checkbox" value="喜欢篮球"/>
<input type="checkbox" v-model="checkbox" value="喜欢羽毛球"/>

将同一组 checkbox 关联同一个 v-model,则数据为选中的 value 值组成的数组(v-model 初始值必须是数组类型)

如果你忘记了配置 value 属性,以下 bug 就会出现:

  1. 不配置 value 属性,收集的就是 checked(勾选 or 未勾选,是布尔值)

  2. 配置 value 属性:

      1. v-model 的初始值是非数组,那你的 value 废了,收集的还是 checked(勾选 or 未勾选,是布尔值)
      2. v-model 的初始值是数组,收集的是被选中元素的 value 组成的数组
    

存在相同值的 radio 时,会被同时选中

备注:v-model 的三个修饰符
lazy:失去焦点再收集数据(本质是将默认监听的 input 事件改成 change 事件)
number:输入的字符串转为有效的数字
trim:输入的首尾空格过滤

Vue2 第二弹 —— 数据劫持、生命周期、组件、props