邂逅Vue.js
安装Vue
Vue的CDN引入:
<script src="https://unpkg.com/vue@next"></script>
通过本地进行安装
- 下载Vue的源码,可以直接打开CDN的链接:打开链接,复制其中所有的代码;
- 创建一个新的文件,比如vue.js,将代码复制到其中;
- 通过script标签,引入刚才的文件:
<script src="../js/vue.js"></script>
声明式和命令式开发
-
原生开发和Vue开发的模式和特点,我们会发现是完全不同的,这里其实涉及到两种不同的编程范式:
- 命令式编程和声明式编程:
- 命令式编程关注的是“how to do”自己完成整个how的过程;
- 声明式编程关注的是"what to do”,由框架(机器)完成“how”的过程
-
在原生的实现过程中,我们是如何操作的呢?
- 我们每完成一个操作,都需要通过)avaScript编写一条代码,来给览器一个指令:
- 这样的编写代码的过程,我们称之为命令式编程;
- 在早期的原生)avaScript和jQuery开发的过程中,我们都是通过这种命令式的方式在编写代码的:
-
在Vue的实现过程中,我们是如何操作的呢?
- 我们会在createApp传入的对象中声明需要的内容,模板template、数据data、方法methods;.
- 这样的编写代码的过程,我们称之为是声明式编程:
- 目前vue、React、Angular、.小程序的编程模式,我们称之为声明式编程;
MVVM模型
回顾MVC
MVC 模式代表 Model-View-Controller(模型-视图-控制器)模式。
这种模式用于应用程序的分层开发。
- Model(模型) - 模型代表一个存取数据的对象或 JAVA POJO。它也可以带有逻辑,在数据变化时更新控制器。
- View(视图) - 视图代表模型包含的数据的可视化。
- Controller(控制器) - 控制器作用于模型和视图上。它控制数据流向模型对象,并在数据变化时更新视图。它使视图与模型分离开。
什么是MVVM?
MVVM (Model-View-ViewModel) 是一种软件架构设计模式,由微软WPF (用于替代WinForm,以前就是用这个技术开发桌面应用程序的)和Silverlight (类似于Java Applet,简单点说就是在浏览器上运行的WPF)的架构师Ken Cooper和Ted Peters 开发,是一种简化用户界面的事件驱动编程方式。由John Gossman (同样也是WPF和Silverlight的架构师)于2005年在他的博客上发表。
MVVM 源自于经典的MVC (ModI-View-Controller) 模式。
MVVM的核心是ViewModel层,负责转换Model中的数据对象来让数据变得更容易管理和使用,其作用如下:
- 该层向上与
View层进行双向数据绑定 - 向下与
Model层通过接口请求进行数据交互。
Vue基本属性
data属性
-
data属性是传入一个函数,井目该函数需要返回一个对象:
- 在ue2.x的时候,也可以传入一个对象(虽然官方推荐是一个函数);
- 在Vu3x的时候,必须传入一个函数,否则就会直接在浏览器中报错:
-
data中返回的对象会被Vue的响应式系统劫持,之后对该对象的修改或者访问都会在劫特中被处理:
- 所以我们在template或者app中通过{{counter)}访问counter,可以从对象中获取到数据:
- 所以我们修改counter的值时,app中的{{counter)}也会发生改变;
methods属性
-
methods属性是一个对象,通常我们会在这个对象中定义很多的方法:
- 这些方法可以被绑定到模板中:
- 在该方法中,我们可以使用this关键字来直接方问到data中返回的对象的属性:
-
对于有经验的同学,在这里我提一个问题,官方文档有这么一段描述:
- 问题一:为什么不能使用箭头函数(官方文档有给出解释)
- 问题二:不使用箭头函数的情况下,this到底指向的是什么?(可以作为一道面试题)
注意 注意,不应该使用箭头函数来定义method函数(例如plus:0→this.a++)。理由是箭头函数绑定了父级作用域的上下文所以this将不会按照期里指向组件实例,this.a将是undefined.
computed 计算属性
- 注意:计算属性看起来像是一个函数,但是我们在使用的时候不需要加(),这个后面讲setter和getter时会讲到;
- 我们会发现无论是直观上,还是效果上计算属性都是更好的选择;
- 并且计算属性是有缓存的;
<div id="app">
<h2>{{fullName}}</h2>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
firstName: 'Guo'
lastName: 'shuaige'
},
//计算属性在此处添加
computed: {
fullName() {
return this.firstName + this.lastName
}
}
})
</script>
-
computed / methods区别
-
多次使用的时候
- methods: 每次都会调用
- computed: 计算机会缓存, 不变的情况下只调用一次
-
监听器的定义与使用(自查文档)
Vue提供了一种更通用的方式来观察和响应Vue实例上的数据变动:监听属性。当有一些数据需要随着其他数据变化而变动时,就可以使用监听器。 听起来监听器和计算属性差不多,从功能描述来看,确实是,不过在实际应用中二者还是有很大差别。
Vue基础
Vue代码片段
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<h3>{{ }}</h3>
</div>
<script src="../lib/vue.js"></script>
<script>
const app =Vue.createApp({
// template:``,
data: function(){ //数据
return {
}
},
methods: { //方法
}
})
app.mount("#app")
</script>
</body>
</html>
基础语法(值插入模板内容)
Mustache双大括号语法
-
如果我们希望把数据显示到模板( template )中,使用最多的语法是 “ Mustache”语法 ( 双大括号) 的文本插值。
- 并且我们前端提到过,data返回的对象是有添加到Vue的响应式系统中;
- 当data中的数据发生改变时,对应的内容也会发生更新。
- 当然,Mustache中不仅仅可以是data中的属性,也可以是一个JavaScript的表达式。
<template id="my-app">
<div>
<!--mustache基本使用:-->
<h2>{{message}}</h2>
<!--JovaScript表达式-->
<h2>{{counter 2}}</h2>
<h2>{{message.split("").reverse()join("")}}</h2>
<!--·调用一个nethods中的函数:-->
<h2>{{reverse(message)}}</h2>
</div>
</template>
v-once指令(了解)
-
v-once用于指定元素或者组件只渲染一次:
- 当数据发生变化时,元素或者组件以及其所有的子元素将视为静态内容并且跳过;
- 该指令可以用于性能优化;
-
如果是子节点,也是只会渲染一次:
v-text指令(了解)
- 用于更新元素的 textContent:
<span v-text="msg"></span>
<!--等价于-->
<span>{{ msg }}</span>
v-html指令(了解)
-
默认情况下,如果我们展示的内容本身是html的,那么vue井不会对其进行特殊的解析。
- 如果我们希望这个内容被vue可以解析出来,那么可以使用v-html来展示:
<template id="my-app">
<div v-html='info'></div>
</template>
<script src="./js/vue.js"></script>
<script>
const App={
template:'#my-app',
data() {
return{
info:`<span style='color:red;font-size:30px'>哈哈哈</span>`
}
}
}
v-pre(了解)
-
V-pre用于跳过元素和它的子元素的编译过程,显示原始的Mustache标签:
- 跳过不需要编译的节点,加快编译的速度
v-cloak
-
这个指铃保持在元素上直到关联组件实例结束编译。
- 和CSS规则如[v-cloak]{display:none}一起用时,这个指令可以隐未编译的Mustache标签直到组件实例准备完毕。
基础属性
v-bind属性
-
v-bind用于绑定一个或多个属性值,或者向另一个组件传递props值(这个学到组件时再介绍)
- 在开发中,有哪些属性需要动态进行绑定呢?
- 还是有很多的,比如图片的链接src网站的链接href 动态绑定一些类、样式等等
<template id="my-app">
<!--·完整的写法·-->
<img v-bind:src="src"alt="">
<!--·语法糖写法·-->
<img :src="src"alt="">
<!--·注意和上面的区别--
··<!--·绑定元素·-->
<a :href="href"></a>
</template>
绑定class-对象语法
- 对象语法:我们可以传给:(class-bind:class的简写)一个对象,以动态地切换class。
<template id="my-app">
<!--·1,普通的绑定方式-->
<div class="className">{{message}}</div>
<!--·2.对象绑定-->
<!--·动态切换class是否加入:·f类(变量):boolean(true/false)}·-->
<div class="why":class="{nba:true,'james':true}"></div>
</template>
- 数组语法:我们可以把一个数组传给:class,以应用一个class列表:
<template id="my-app">
<!--·1.直接传入一个数组-->
<div :class="['why','nba']">哈哈哈</div>
<!--·2.数组中也可以使用三元运算符或者绑定变量-->
<div :class="['why',nba, isActive?'active':'']">呵呵呵</div>
<!--·3.数组中也可以使用对象语法·-->
<div :class="['why',nba,{'actvie' : 'isActive'}]">嘻嘻嘻</div>
</template>
绑定style
-
我们可以利用v-bind:stlyle来绑定一些CSS内联样式:
- 这次因为某些样式我们需要根据数据动态来决定:
- 比如某段文字的颜色,大小等等:
-
CSS property名可以用驼峰式(camelCase)或短横线分隔(kebab-case,记得用引号括起来)来命名;
-
绑定cass有两种方式:
- 对象语法
<template id="my-app"> <!--·1.基本使用:·传入一个对像,·并且对像内容都是确定的:--> <div :style="{color:'red',fontsize:'30px','background-color':'blue']">{{message}}</div> <!--2.变量数据:传入一个对像,·值会来自于data--> <div :style="{color:'red',fontsize:size+'px','background-color':'blue']">{{message}}</div> <!--·3.对象数据:直接在data中定义好对像在这里使用--> <div :style="styleObj">{{message}} </div> </template>- 数组语法
<!--stye的数组语法可以将多个样式对象应用到同一个元素上:--> <template id="my-app"> <div :style="[styleobj1,styleobj2]">{{message}}</div> </template>
动态绑定属性
-
在某些情况下,我们属性的名称可能也不是固定的:
- 前端我们无论绑定src,class、style,属性名称都是固定的:
- 如果属性名称不是固定的,我们可以使用:[属性名]=“值”的格式来定义:
- 这种绑定的方式,我们称之为动态绑定属性:
<template id="my-app">
<!--·属性的名称是动态的-->
<div :[name]="value">{{message}}</div>
</template>
-
如果我们希望将一个对象的所有属性,绑定到元素上的所有属性,应该怎么做呢?
- 非常简单,我们可以直接使用v-bind绑定一个对象:
- 案例:info对象会被拆解成div的各个属性
<!-- 在data选项中 info: { name: 'Klaus', age: 24 } -->
<!-- 直接使用v-bind 即可 不需要加上对应属性名 因为这里是绑定多个属性 -->
<div v-bind="info">foo</div>
<!-- 简写形式 - 不推荐,可读性较差 -->
<div :="info">foo</div>
<!-- 上述的写法等价于 -->
<div :name="info.name" :age="info.age">foo</div>
v-on绑定事件
-
前面我们绑定了元素的内容和属性,在前端开发中另外一个非常重要的特性就是交互。
-
在前端开发中,我们需要经常和用户进行各种各样的交互:
- 这个时候,我们就必须监听用户发生的事件,比如点击、拖拽、键盘事件等等
- 在Vue中如何监听事件呢?使用v-on指令。
基本使用
<1--1.基本使用-->
<!--·绑定一个表达式-->
<button v-on:click="counter++"></button>
<!--·绑定到一个nethods方法中·-->
<button v-on:click="btnclick">1</button>
<!--v-on的语法糖-->
<button @click="btnclick">按钮2</button>
<!--·绑定鼠标移动事件:-->
<div @mousemove="mouseMove">div的区域</div>
<!--·2.绑定对象-->
<button v-on="{click : btnclick, mousemove : mouseMove}">特殊按钮3</button>
参数传递
- 没有参数的情况下, 可以不写( ); 如果方法本身有一个参数, 会默认将原生事件event参数传递进去
- 如果传入某个参数, 同时需要event时, 可以通过$event传入时间
<!--情况一: 方法没有参数-->
<button @click="btnClick1">按钮1</button>
<button @click="btnClick1()">按钮1</button>
<!--情况二: 如果方法有参数-->
<!--1.调用时不传入参数,会默认将event作为第一个参数传入-->
<button @click="btnClick2">按钮2</button>
<!--2.调用时不传入参数,那么参数为undefined-->
<button @click="btnClick2()">按钮2</button>
<!--情况三: 如果方法有参数,并且希望传入event-->
<button @click="btnClick3(10, $event)">按钮3</button>
v-on的修饰符
| 修饰符 | 作用 | 实际调用 |
|---|---|---|
| .stop | 阻止事件冒泡 | event.stopPropagation() |
| .prevent | 阻止默认事件 | event.preventDefault() |
| {keyCode I keyAlias} | 监听某个键盘的键帽 | – |
| .native | 监听组件根元素的原生事件 | – |
| .once | 只触发一次回调 | – |
| .left | 只当点击鼠标左键时触发 |
条件渲染
-
v-if、v-else、v-else-if用于根据条件来渲染某一块的内容:
- 这些内容只有在条件为true时,才会被渲染出来;
- 这三个指令与JavaScript的条件语句if、else、else if类似;
<template id="my-app">
<input type="text"v-model.number="score">
<h2 v-if="score>90">优秀</h2>
<h2 v-else-if="score>80">良好</h2>
<h2 v-else-1f="score>60">普通</h2>
<h2 v-else>不及格</h2>
</template>
-
v-if 的渲染原理:
- v-if是惰性的;
- 当条件为false时,其判断的内容完全不会被渲染或者会被销毁掉;
- 当条件为true时,才会真正渲染条件块中的内容;
v-if和v-show的区别
| 特点 | 性能 | |
|---|---|---|
| v-for | 每次都会重新删除或创建元素 | 切换性能高 |
| v-show | 每次不会重新进行DOM的删除和创建操作(不支持template),通过css的display属性来进行切换。 | 初始渲染消耗高 |
总结: 如果元素可能永远不会显示出来被用户看到,则推荐v-if;如果元素涉及到频繁切换,则推荐v-show
v-for基本使用
-
迭代数组
<ul> <li v-for = "(item , i) in sites">{{item.name}}</li> </ul> <script> const app = new Vue({ el: '#app', data: { sites:[ { name: 'Runnoob'}, { name:'Google'}, { name:'Taobao'} ] } }); </script> -
迭代对象的属性
<div v-for = "(value ,key,index) in user">值是:{{value}} 键是:{{key}} 索引是:{{index}}</div> <script> const app = new Vue({ el: '#app', data: { user:{ id:1, name:'guo', gender:'nan' } } }); </script> -
迭代数字
<p v-for = "i in 10">这是第{{i}}个p标签</p>- v-for 迭代数字时,i 值从1开始
- key在使用的时候,必须使用
v-bind属性绑定的形式,指定key的值
-
key的作用
key的作用是为了高效的更新虚拟DOM key要具有唯一性, 不然就没意义
-
在使用v-for进行列表渲染时,我们通常会给元素或者组件绑定一个key属性。
-
这个key属性有什么作用呢?我们先来看一下官方的解释:
- key属性主要用在Vue的虚拟DOM算法,在新旧nodes对比时辨识VNodes;
- 如果不使用key,Vue会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法;
- 而使用key时,它会基于key的变化重新排列元素顺序,并且会移除/销毁key不存在的元素;
<li v-for="(item, index) in names" :key="item">{{index + 1}} - {{item}}</li>
v-model 实现双向绑定
-
基本原理
- v-bind绑定value属性的值;
- v-on绑定input事件监听到函数中,函数会获取最新的值赋值到绑定的属性中;
<body> <div id="app"> <input type="text" :value="datas" @input="inputClick"> <!-- 等价于 <input type="text" v-model="datas"> --> <h2>{{datas}}</h2> <h2>{{datas}}</h2> </div> <script src="../lib/vue.js"></script> <script> const app =Vue.createApp({ // template:``, data: function(){ return { datas: 12345 } }, methods: { inputClick(event){ this.datas = event.target.value } } }) app.mount("#app") </script> </body> -
结合radio类型
<label for="male"> <input type="radio" id="male" name="sex" value="男" v-model="sex">男 </label> <label for="female"> <input type="radio" id="female" name="sex" value="女" v-model="sex">女 </label> <h2>{{sex}}</h2> <script> const app = new Vue({ el: '#app', data: { sex: '男' } }) </script>
- sex里面写上数据时,由于双向绑定,对应的按钮处也会有选中效果,这样可以解决单选按钮的默认问题
-
结合chechbox类型
//单选框 <label for="agree"> <input type="checkbox" id="agree" v-model="isAgree">同意协议 </label> <h2>{{isAgree}}</h2> <button :disabled="!isAgree">下一步</button> <script> const app = new Vue({ el: '#app', data: { isAgree: false //单选框对应的是boolean值 } }) </script> //多选框 <input type="checkbox" value="篮球" v-model="hobbies">篮球 <input type="checkbox" value="乒乓球" v-model="hobbies">乒乓球 <input type="checkbox" value="足球" v-model="hobbies">足球 <h2>爱好是{{hobbies}}</h2> <script> const app = new Vue({ el: '#app', data: { hobbies: [ ] //多选框对应的是数组 } }) </script> -
结合select类型
<select name="abc" v-model="fruit"> <option value="苹果">苹果</option> <option value="香蕉">香蕉</option> <option value="葡萄">葡萄</option> </select> <h2>选择的是:{{fruit}}</h2> <script> const app = new Vue({ el: '#app', data: { fruit: '香蕉' } }) </script>- 注意:select的v-model是写在select中的!
-
值绑定
我们前面的value中的值,都是定义在input时直接给定,但是在实际开发中,这些input的值可能是定义在data中的,所以需要通过 v-bind:value动态地给value绑定值
<label v-for="item in allHobbies" :for="item"> <input type="checkbox" :id="item" :value="item" v-model="hobbies">{{item}} </label> <h2>选择的是:{{hobbies}}</h2> <script> const app = new Vue({ el: '#app', data: { hobbies: [ ], allHobbies: ['篮球', '足球', '乒乓球', '羽毛球'] } }) </script> -
使用修饰符
-
lazy修饰符
- 默认情况下v-model是实时同步输入框的数据的 (容易同步的过于频繁 )
- lazy修饰符可以让数据在失去焦点或回车时才更新
<input type="text" v-model.lazy="输入"> -
number修饰符
- 默认情况下,在输入框中无论输入的是字母还是数字,都会被当做String类型处理
- 但是如果我们希望处理的是数组类型,那么最好直接将内容当做数字处理
-
trim修饰符
- 如果输入的内容首尾有很多
空格,可以使用它去除
- 如果输入的内容首尾有很多
-