🎾 Vue基本概念

Vue介绍

什么是渐进式?

渐进式: 逐渐进行 逐渐增强。
vue不会强制要求项目中完全都有vue来实现。
image.png

什么是框架?

  • jquery: jquery是一个js库(Library)
    • js库:一系列方法的集合。js库不会提供逻辑,逻辑由程序员自己控制。
  • vue: vue是要给js框架(framework)
    • js框架: 一整套完整解决方案, 大部分的逻辑框架已经确定好了,我们只需要在框架中填充自己的代码,完形填空

库和框架的概念

image.png

Library

库,本质上是一些函数的集合。每次调用函数,实现一个特定的功能

  • 代表:jQuery
  • 使用库的时候,把库当成工具使用,需要自己控制代码的执行逻辑。

Framework

框架,是一套完整的解决方案,使用框架的时候,需要把你的代码放到框架合适的地方,框架会在合适的时机调用你的代码

  • 框架规定了自己的编程方式,是一套完整的解决方案
  • 使用框架的时候,由框架控制一切,我们只需要按照规则写代码

库和框架的区别

  • 使用库的时候,很自由,只要调用库提供的各种各样的方法就行,也可以不用其他的一些方法
  • 使用框架的时候,需要按照框架的规则写代码,限制会非常多,但同时框架的功能也很强大,可以极大的提升开发的效率。

image.png

MVVM的概念

参考资料:从Script到Code Blocks、Code Behind到MVC、MVP、MVVM

MVC

  • MVC是一种软件架构模式,也有人叫做设计模式,最早出现在后端
  • M: Model 数据模型(专门用来操作数据,数据的CRUD)
  • V:View 视图(对于前端来说,就是页面)
  • C:Controller 控制器(是视图和数据模型沟通的桥梁,用于处理业务逻辑)

image.png
image.png

MVVM

MVVM,一种更好的UI模式解决方案

  • M:model数据模型(ajax获取到的数据)
  • V:view视图(页面)
  • VM:ViewModel 视图模型

image.png

MVC vs MVVM

  • MVC模式,将应用程序划分为三大部分,实现了职责分离,需要自己实现controller的代码,需要操作DOM
  • MVVM通过数据双向绑定让数据自动地双向同步
    • V(修改视图) -> M(数据自动同步)
    • M(修改数据) -> V(视图自动徒步)

image.png

Vue中的MVVM

虽然没有完全遵循 MVVM 模型,Vue 的设计无疑受到了它的启发。因此在文档中经常会使用 vm (ViewModel 的简称) 这个变量名表示 Vue 实例

注意:
1. 在vue中,不推荐直接手动操作DOM!!!
2. 在vue中,通过数据驱动视图,不要在想着怎么操作DOM,而是想着如何操作数据!!

🏀 Vue初体验

基本使用步骤

  1. 安装 下载vue

    1. npm install vue

    注意:开发期间使用未压缩版vue.js!!!重说三

  2. 引入一个vue文件

引入了vue.js文件后,vue.js文件会暴漏一个全局的Vue构造函数

  1. 创建vue实例
    1. 初始化一个vue实例, 需要指定 视图 数据
    2. 使用vue的时候,我们需要关注两个东西
      1. el: element: 缩写 指定vue管理的视图, 某个盒子的选择器
      2. data 指定vue中使用的数据
  1. <div id="app">
  2. <!-- 3.可以通过{{}}显示vue中的数据 -->
  3. <h1>{{msg}}</h1>
  4. </div>
  5. <!-- 1. 引入vue.js -->
  6. <script src="./node_modules/vue/dist/vue.js"></script>
  7. <script>
  8. // 2. 创建vue实例,需要指定el和data属性
  9. const vm = new Vue({
  10. // 指定vue监管的视图区域,只要id为app的div内部才会受vue的管理
  11. el: '#app',
  12. // 提供了vue中使用的数据
  13. data: {
  14. msg: 'hello vue'
  15. }
  16. })
  17. </script>

问题1:把{{msg}}写到div#app外能生效么?
问题2:el能否写成ele, data能否写成datas? 框架的限制很多,但是习惯就好了!

使用Vue的注意事项

  1. new vue() Vue是一个构造函数首字母大写
  2. el不能指定为body或者html, 应该是一个div
  3. 如果想要修改页面中的内容,应该怎么办, data中所有的数据都添加给了vm对象

可以通过vm.xxx 进行修改

插值表达式

  1. 插值表达式:{{}},也叫Mustache语法,小胡子语法,因为长得像胡子

    1. 作用:可以在视图中显示data中的数据,也就是从data中获取数据,并展示在模板中
    2. 说明:{{}}中只能出现JavaScript表达式
    3. 说明:数据对象的属性值发生了改变,插值处的内容都会更新
  2. vue中插值表达式的语法

    1. {{msg}}
    2. {{car.brand}}
    3. {{car.price + 100}}
    4. {{三元运算符}}
  3. vue中插值表达式的注意点

    1. {{}}中使用的数据必须在data中存在
    2. {{}} 虽然能够使用表达式,不能出现js的语句,不能在{{}}中写if for等关键字
    3. {{}} 不能在属性中使用 ```html

Hello, {{ msg }}.

{{ isOk ? ‘yes’: ‘no’ }}

{{ 1 + 2 }}

<a name="e6fe3c9b"></a> # 🏐 Vue指令 > 指令 (Directives) 是带有 `v-` 前缀的特殊属性,可以在html标签中使用,可以看成特殊的html属性 - 作用:指令提供了一些特殊的功能,当指向绑定到标签上时,可以给标签增加一些特殊的行为 - vue总共提供了14个指令 也可以自定义指令 <a name="3f860172"></a> ## v-bind指令 > v-bind指令 用于访问data中的数据,在标签的属性中使用 1. 为什么要用v-bind指令 插值表达式不能用在html的属性上,如果想要动态的设置html元素的属性,需要使用v-bind指令 2. v-bind如何使用html title=”title” v-bind:属性名=”属性的值” :title :src 3. 注意事项 bind访问的值必须在data中存在的 <a name="c7e42502"></a> ## v-model指令 > 在表单元素上创建双向数据绑定,用于监听用户的输入事件以更新数据 1. v-model的作用是 1. 给表单元素使用 1. 创建双向数据绑定 2. v-model的语法是什么html v-model=”值” 3. v-model的注意事项 1. **只能表单元素使用** 1. 必须在data中存在 1. v-model会忽略掉原本的value值 checked <a name="Fs7gG"></a> ### 使用场景html

Message is: {{ message }}

```html <p>{{desc}}</p> <textarea cols="30" rows="10" v-model="desc"></textarea> html <p>{{city}}</p> <select v-model="city"> <option value="1">北京</option> <option value="2">上海</option> <option value="3">广州</option> <option value="4">深圳</option> </select> html <p>{{isCheck}}</p> <input type="checkbox" v-model="isCheck"> ### 双向数据绑定 1. 简单的说:当数据变了——-=> 视图会跟着变 视图变了 =======> 数据跟着变 2. 一般说:双向数据绑定将DOM与Vue实例的data数据绑定到一起,彼此之间相互影响 1. 数据的改变会引起DOM的改变 1. DOM的改变也会引起数据的变化 3. 怎么知道对象的某个数据发生了改变? 1. angularjs 1:脏数据检查机制 轮询 缺点: 性能比较低 兼容ie8 1. vue用的是数据劫持: 劫持data的msg属性 使用了ES5中的语法: Object.defineProperty(参数1:对象名, 参数2:属性名, 参数3:修饰一个对象) 注意:Object.defineProperty()方法是ES5中提供的,IE8浏览器不支持这个方法。因此,Vue支持IE8及其以下版本浏览器

4. 数据劫持的原理:监听文本框的事件,知道数据发生了改变,劫持这个数据,再更改数据,让视图跟着改变 html <script> const data = { msg: '哈哈' } const input = document.querySelector('input') input.value = data.msg // 核心原理:监听文本框的事件 input.addEventListener('input', function() { data.msg = input.value }) // 核心原理: 知道数据发生了改变,,,劫持这个数据 let temp = data.msg //设置了Object.defineProperty中的get和set方法 //作用:指定读取或设置对象属性值的时候,执行的操作 Object.defineProperty(data, 'msg', { get(){ //get方法会劫持 msg这个属性的获取操作 console.log('获取了值') return temp }, set(value) { // set方法会劫持到这个属性msg的设置操作 console.log('设置了值') temp = value // 应该让视图跟着改变 input.value = temp } }) </script> 相关 ### Vue双向绑定的极简实现 html <!-- 示例 --> <input type="text" id="txt" /> <span id="msgBox"></span> <script> const txt = document.getElementById('txt') const msgBox = document.getElementById('msgBox') const obj = {} // 给对象obj添加msg属性,并设置setter访问器 Object.defineProperty(obj, 'msg', { // 设置 obj.msg 执行的操作 set: function (curVal) { txt.value = curVal msgBox.innerText = curVal } }) // 监听文本框的改变 txt.addEventListener('input', function (event) { obj.msg = this.value }) </script> ## v-on指令 > v-on是用来给元素注册绑定事件,绑定的事件从methods中获取 ### v-on的语法 html v-on:事件名 = "事件函数" v-on:click 可以简写成 @click <!-- 完整语法 --> <a v-on:click="doSomething"></a> <!-- 缩写 --> <a @click="doSomething"></a> ### v-on的注意点 注册事件需要一个事件的函数
创建vue实例的时候 ,data是用来给vue实例提供的属性(数据),不应该提供方法 html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"> <!-- 1. 给翻转案例注册点击事件 --> <button @click="reverse">翻转</button> <p>{{msg}}</p> </div> <script src="vue.js"></script> <script> const vm = new Vue({ el: '#app', data: { msg: 'hello vue!' }, methods: { // methods中的所有的方法内部的this都指向vm // vue源码内部 reverse.bind(vm) reverse() { // 翻转msg // js基础 // 1. 字符串没有reverse方法 // 2. 数组有reverse方法 // 3. 字符串有一个方法 split() 切割一个字符串变成数组 // 4. 数组有个reverse方法,可以翻转 // 5. 数组有个join方法,可以拼成字符串 // console.log(this.msg) this.msg = this.msg.split('').reverse().join('') } } }) </script> </body> </html> html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"> <!-- 注册事件 --> <button @click="start">跑</button> <button @click="stop">停</button> <h1>{{msg}}</h1> </div> <script src="vue.js"></script> <script> const vm = new Vue({ el: '#app', data: { msg: '小龙虾29.8一斤,买3斤送1斤!', timeId: '' }, methods: { start() { // clearInterval(this.timeId) // 如果有定时器在跑,直接结束 if (this.timeId) { return } // 开一个定时器, 每次都截取字符串的第一个字符串,放到最后一个字符 // 用了箭头函数后将不能指向this this.timeId = setInterval(() => { // console.log(this.msg) this.msg = this.msg.slice(1) + this.msg.slice(0, 1) }, 300) }, stop() { clearInterval(this.timeId) // 把定时器的id清空 this.timeId = '' } } }) </script> </body> </html> html () [] // + - : 前面的语句必须结束 var num= 11 ;(function(){ console.log(22) })() console.log('哈哈') console.log('呵呵') html "快速生成vue模版": { // 配置简写 "prefix": "vue", // 如果有一行,可以是字符串 // 如果是多行,需要是数组 "body": [ "<!DOCTYPE html>", "<html lang=\"en\">", " <head>", " <meta charset=\"UTF-8\" />", " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />", " <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />", " <title>Document</title>", " </head>", " <body>", " <div id=\"app\">", " <h1>{{ msg }}</h1>", " </div>", "", " <script src=\"vue.js\"></script>", " <script>", " const vm = new Vue({", " el: '#app',", " data: {", " msg: 'hello vue'", " }", " })", " </script>", " </body>", "</html>" ] } ### 事件修饰符 注册事件经常需要阻止冒泡 阻止浏览器默认行为 html @事件名.事件修饰符 = "事件函数" - prevent 阻止默认行为 a标签 表单的提交 - stop 阻止冒泡 - capture 捕获阶段执行 - self 只有点击自己才执行,点击子元素不执行 - once 只会执行一次 ### 按键修饰符 在监听键盘事件时,我们经常需要检查常见的键值。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符: - enter - tab - esc - delete (捕获“删除”和“退格”键) - space - up - down - left - right javascript @keyup.enter="fn" ## v-text指令 > 更新元素的 textContent属性。如果要更新部分的 textContent ,需要使用 {{ Mustache }} 插值。 html <h1 v-text="msg"></h1> ## v-html指令 > 更新DOM对象的 innerHTML,html标签会生效 html <h1 v-html="msg"></h1> 注意:在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 XSS 攻击。只在可信内容上使用 **v-html**,永不用在用户提交的内容上。 ## v-show和v-if
1. v-show:用于控制元素显示或者隐藏 1. v-show=”值” 如果这个值是true,表示显示 如果是false隐藏 1. v-show:通过样式 display属性控制显示和隐藏 2. v-if: 用于控制元素的显示和隐藏 1. v-if=”值” 如果这个值是true,表示显示 如果是false隐藏 1. v-if通过删除或者创建一个元素来控制显示和隐藏的 以后用哪个?????
如果一个盒子需要频繁的显示和隐藏,应该用 v-show
如果一个盒子要么显示要么隐藏,频率低 应该用 v-if 共同点:都能控制显示和隐藏
区别: v-show适合频繁切换 v-if适合要么显示要么隐藏 html <p v-show="isShow">这个元素展示出来了吗???</p> <p v-if="isShow">这个元素,在HTML结构中吗???</p> ## v-else与v-else-if指令 ```html

欢迎你,尊贵的v7用户

你好,请登录

  1. <h3 v-if="age >= 18">去酒吧</h3>
  2. <h3 v-else-if="age >= 12">去网吧</h3>
  3. <h3 v-else>去幼儿园</h3>

  1. <a name="u15LK"></a>
  2. ## v-for
  3. > v-for用于遍历一个数组或者一个对象,v-for是一个属性, v-for指令谁需要重复的渲染,就给谁加
  4. <a name="lMNxW"></a>
  5. ### 两种用法
  6. <br />
  7. - 遍历数组
  8. v-for="item in 数组" item表示每次遍历出来的值,item的名字是可以随意起<br /> v-for="(item,index) in 数组" item表示值 index:下标
  9. - 遍历对象
  10. v-for="value in 对象"<br /> v-for="(对象属性, 对象名) in 对象"
  11. ```html
  12. <div id="app">
  13. <h1>pp的爱好</h1>
  14. <ul>
  15. <li v-for="item in hobby">{{item}}</li>
  16. </ul>
  17. <ul>
  18. <li v-for="(item,index) in hobby">{{index}}-----{{item}}</li>
  19. </ul>
  20. <ul>
  21. <li v-for="index in hobby">{{index}}</li>
  22. </ul>
  23. <ul>
  24. <li v-for="(v, k) in girlFriend">{{k}}------{{v}}</li>
  25. </ul>
  26. </div>

key属性

使用 key,VUE会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。为了让渲染更加高效。

  1. 推荐使用 **v-for** 的时候提供 **key** 属性,能够根据“就地更新”策略提升列表渲染的性能

    使用v-for的时候一定要加key值 如果不加,默认采用就地更新原则,正常情况没有问题。

  1. <div v-for="item in items" :key="item.id">
  2. <!-- 内容 -->
  3. </div>

image.png

  1. 但是有时可以更加优化“就地更新”策略,加key
    1. <ul>
    2. <li v-for="item in list" :key="item">
    3. <input type="checkbox">
    4. {{item}}
    5. </li>
    6. </ul>

提升性能:v-pre

  • 说明:跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译。
  1. <span v-pre>{{ this will not be compiled }}</span>

提升性能:v-once

  • 说明:只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。
  1. <span v-once>This will never change: {{msg}}</span>

样式处理-class和style

  • 使用方式:v-bind:class="expression" or :class="expression"
  • 表达式的类型:字符串、数组、对象(重点)
  • 语法:
  1. <!-- 1 -->
  2. <!-- 重点 -->
  3. <div v-bind:class="{ active: true }"></div> ===>
  4. <div class="active"></div>
  5. <!-- 2 -->
  6. <div :class="['active', 'text-danger']"></div> ===>
  7. <div class="active text-danger"></div>
  8. <!-- 3 -->
  9. <div v-bind:class="[{ active: true }, errorClass]"></div> ===>
  10. <div class="active text-danger"></div>
  11. --- style ---
  12. <!-- 1 -->
  13. <div v-bind:style="{ color: activeColor, 'font-size': fontSize + 'px' }"></div>
  14. <!-- 2 将多个 样式对象 应用到一个元素上-->
  15. <!-- baseStyles 和 overridingStyles 都是对象 -->
  16. <div v-bind:style="[baseStyles, overridingStyles]"></div>

案例:todomvc

计算属性

计算属性:当计算属性依赖的数据发生改变的时候,计算属性会重新计算一次,如果计算属性依赖的属性没有发生改变,那么计算属性就不会重新计算。

基本使用

  1. var vm = new Vue({
  2. el: '#app',
  3. data: {
  4. n1:'',
  5. n2:''
  6. },
  7. //n3依赖与n1和n2的值,当n1 和 n2发生改变的时候,这个函数就会执行。
  8. //返回值就是n3的值
  9. computed: {
  10. n3(){
  11. return +this.n1 + +this.n2;
  12. }
  13. }
  14. });

计算属性是基于它们的依赖项进行缓存的

如果页面中需要使用多次计算属性的值,只会计算一次,计算属性只有在它的相关依赖发生改变时才会重新求值。

计算属性不能与data中的属性同名,因为无论是data中的属性还是计算属性,最终都是挂载到vm上的