笔记视频:https://www.bilibili.com/video/BV15741177Eh?p=1

MVVM

image.png

  • View 层:
    • 视图层
    • 在我们前端开发中,通常就是 DOM 层
    • 主要的作用是给用户展示各种信息
  • Model 层:
    • 数据层
    • 数据可能是我们固定的死数据,更多的是来自我们服务器,从网络上请求下来的数据
  • ViewModel 层:
    • 视图模型层
    • 视图模型层是 View 和 Model 沟通的桥梁
    • 一方面它实现了 Data Binding,也就是数据绑定,将 Model 的改变实时的反应到 View 中
    • 一方面它实现了 DOM Listener,也就是 DOM 监听,当 DOM 发生一些事件(点击、滚动、touch 等)时,可以监听到,并在需要的情况下改变对应的 Data

      生命周期

每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
20200419120024713.png

vscode 模版

设置——用户代码片段——输入html(获得一个josn文件)——把代码片段放入 body
image.png
此时输入 vue 就可以快速输入模版内容

Mustache 语法

文档链接:http://wiki.jeeplus.org/docs/show/69

插值操作

v-once

内容只渲染一次,不会根据数据的改变而改变

  1. <h2 v-once>{{message}}</h2>


v-html
以前 html 的形式插入_

<h2 v-html="url"></h2>
<!-- 渲染后 -->
<h2><a href="http://www.badu.com">百度一下</a></h2>

<script>
var app = new Vue({
  el: '#app',
  data: {
  message: '你好',
  url: '<a href="http://www.badu.com">百度一下</a>'
  }
})
</script>

v-text

更新元素的 textContent(会覆盖原内容)

<span v-text="msg"></span>
<!-- 和下面的一样 -->
<span>{{msg}}</span>

v-pre

跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签

/* 页面将显示 {{message}} */
<h2 v-pre>{{message}}</h2>

v-cloak

这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。

[v-cloak] {
  display: none;
}
<div v-cloak>
  {{ message }}
</div>

动态绑定属性

使用 v-bind 动态绑定属性

在 vue 语法中不能使用 Mustache 方式绑定属性

// 错误
<img src="{{imageSrc}}" alt="">

示 例

<!-- 绑定一个 attribute -->
<img v-bind:src="imageSrc">

<!-- 缩写 -->
<img :src="imageSrc">

<!-- class 绑定,原生的 class 会与 :class 合并 -->
<div :class="{ red: isRed }"></div>
<div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]">

<!-- style 绑定 -->
<div :style="{ fontSize: size + 'px', color: fontColor }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>

计算属性

类型{ [key: string]: Function | { get: Function, set: Function } }

可以直接使用函数名当做属性引用

示 例

<div id="app">
  <h2>{{ fullName }}</h2>
</div>
var app = new Vue({
  el: '#app',
  data: {
    firstName: 'Lebron',
    lastName: 'James'
  },
  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  },
})

computed 是一个简写属性(完整有 set 和 get 两个方法)

var vm = new Vue({
  data: { a: 1 },
  computed: {
    // 仅读取
    aDouble: function () {
      return this.a * 2
    },
    // 读取和设置
    aPlus: {
      get: function () {
        return this.a + 1
      },
      set: function (v) {
        this.a = v - 1
      }
    }
  }
})
vm.aPlus   // => 2
vm.aPlus = 3
vm.a       // => 2
vm.aDouble // => 4

想比于 methods 计算属性拥有数据缓存机制

var app = new Vue({
  el: '#app',
  data: { a: 1 },
  methods: {
    getA: function () {
      console.log('methods 调用多少次就会输出多少次');
      return this.a
    }
  },
  computed: {
    aPlus: function () {
      console.log('不管调用多少次 computeds 只会输出一次');
      return this.a + 1
    }
  }
})

事件监听

修饰符

  • .stop - 调用 event.stopPropagation()
  • .prevent - 调用 event.preventDefault()
  • .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
  • .once - 只触发一次回调。
  • native - 监听组件的原生事件
<!-- 方法处理器 -->
<button v-on:click="doThis"></button>

<!-- 缩写 -->
<button @click="doThis"></button>

<!-- 需要 event 对象,同时又需要传入其他参数时,使用 $event -->
<button v-on:click="doThat('hello', $event)"></button>

<!-- 停止冒泡 -->
<button @click.stop="doThis"></button>

<!-- 阻止默认行为 -->
<form @submit.prevent></form>


<!-- 键修饰符,键代码 -->
<input @keyup.enter="onEnter">

<!-- 点击回调只会触发一次 -->
<button v-on:click.once="doThis"></button>

<!-- 监听组件的原生事件,当监听组件的时候需要用到 -->
<back-top @click.native="backClick" />

条件判断

v-if 根据表达式的布尔值来有条件地渲染元素

示 例

<h1 v-if="true">Vue is awesome!</h1>

使用 v-else 表示 v-if 的“else 块”,必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。

示 例

<div v-if="Math.random() > 0.5">
  Now you see me
</div>
<div v-else>
  Now you don't
</div>

v-ifv-show 的区别在于 v-if 会直接把 dom 删除,而 _v-show_ 会给 dom 添加行内样式 _display: none;_

循环遍历

示 例

value-key-index

// 遍历数组
<div v-for="item in array">{{ item }}</div>
<div v-for="(item, index) in array">{{ index }}</div>
// 遍历对象
<div v-for="value in object">{{ value }}</div>
<div v-for="(value, key) in object">{{ key }}</div>
<div v-for="(value, key, index) in object">{{ index }}</div>

当一个数据已经渲染后,往其中插入一个新元素时,如果没有 _:key_ 属性,vue 将不会进行复用而会一一替换,这样效率会非常低

<!-- :key 必须保证是唯一固定性的(例如下标) -->
<div v-for="item in items" :key="item.id">
  {{ item.text }}
</div>

响应式数组方法

当数组发生变化时,页面也会响应式地发生变化

有以下方法:

// 1.push 方法(在末尾插入元素)
this.letters.push('aaaaa')

// 2.pop 方法(从末尾开始删除元素)
this.letters.pop()

// 3.shift 方法(从开头删除元素)
this.letters.shift()

// 4.unshift 方法(在开头添加元素)
this.letters.unshift('aaa')

// 5.splice 方法(删除元素/插入元素/替换元素)
// 参数1;表示从当前位置开始(包括当前),如果只传入一个参数,则从当前元素之后全部删除
// 参数2:删除几个元素
// 参数3:插入的元素(可以插入多个)
// 当第二个参数不为零时,则参数3相当于替换
this.letters.splice(1, 4, 'm', 'l', 'n', 'j')
this.letters.splice(0, 1)

// 6.sort 方法(排序)
this.letters.sort()

// 7.reverse 方法(反转数组)
this.letters.reverse()

// 8.set 方法(要修改的对象,索引值,修改后的值),该方法是 vue 中的方法
Vue.set(this.letters, 0, 'bbbbb')

注意通过索引值修改数组中的元素不是响应式的

this.letters[0] = 'bbbbbb'

高阶函数

filter

  • filter 中的回调函数有一个要求:必须返回一个 boolean 值
  • true:函数内部会自动将这次回调的 n 加入到新的数组中
  • false:函数内部会过滤掉这次的 n

    示 例

    // 1.需求:取出所有小于 100 的数字
    let newNums = nums.filter(function (n) {
    return n < 100
    });
    

**map

示 例

// 2.需求:将所有数字进行转化:全部 *2
let new2Nums = nums.map(function (n) {
  return n * 2
})

reduce

示 例

参数1:一个回调函数
参数2:传递给函数的初始值(preValue)

// 3.需求:将所有 new2Nums 数字相加,得到最终的结果
// 每次返回的结果都会赋给 preVaule
let tatal = new2Nums.reduce(function (preVaule, currentValue) {
  return preVaule + currentValue
}, 0)

for 遍历

// 1.普通的 for 循环
// 需要通过下标拿值和设置遍历次数
for (let i = 0; i < this.books.length; i++) {
    totalPrices += (this.books[i].price) * (this.books[i].count)
}

// 2.for (let i in this.books)
// 不需要设置遍历次数,依然需要通过下标拿值
for (let i in this.books) {
  totalPrices += (this.books[i].price) * (this.books[i].count)
}

// 3.for (let i of this.books)
// 直接可以拿到值,并且不需要设置遍历次数
for (let item of this.books) {
  totalPrices += item.price * item.count
}

v-model 使用

在表单控件或者组件上创建双向绑定

<!-- 1.文本 -->
<!-- 当 input 的 value 发生改变时,message 也会发生改变 -->
<input type="text" v-model="message">
<p>{{ message }}</p>

<!-- 2.单选按钮 -->
<!-- 当绑定了相同的 v-model 时,就算不加 name 也能互斥 -->
<input type="radio" id="one" value="One" v-model="picked">
<input type="radio" id="two" value="Two" v-model="picked">
<span>Picked: {{ picked }}</span>

<!-- 3.复选框 -->
<!-- 单个复选框,绑定到布尔值: -->
<input type="checkbox" id="checkbox" v-model="isChecked">
<label for="checkbox">{{ isChecked }}</label>
<!-- 多个复选框,绑定到同一个数组: -->
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>

<!-- 4.选择框 -->
<!-- 单选时 -->
<select v-model="selected">
  <option disabled value="">请选择</option>
  <option>A</option>
  <option>B</option>
  <option>C</option>
</select>
<!-- 多选时绑定到数组 -->
<select v-model="selects" multiple style="width: 50px;">
  <option>A</option>
  <option>B</option>
  <option>C</option>
</select>

原 理

<!-- 动态绑定 message,监听 input 事件(oninput) -->
<input type="text" :value="message" v-on:input="valueChange">
<h2>{{message}}</h2>

<script>
  const app = new Vue({
      el: '#app',
    data: {
      message: '你好'
    },
    methods: {
      valueChange(event) {
       // 获取 input 的 value 赋给 message
          this.message = event.target.value
      }
    }
  })
  </script>

修饰符

<!-- 1.修饰符:lazy(回车或失去焦点之后才会渲染)-->
<input type="text" v-model.lazy="message">
<h2>{{message}}</h2>

<!-- 2.修饰符:number(将 value 转换为 number,v-model 的值默认为 string) -->
<input type="number" v-model.number="age">
<h2>{{typeof age}}</h2>

<!-- 3.修饰符:trim(去除空格,虽然浏览器展示时会自动去除空格,但实际上还是包含空格的) -->
<input type="text" v-model.trim="name">
<h2>您输入的名字:{{name}}</h2>