本笔记是看b站codewhy老师的视频做的笔记,大家可以一起学习,个人觉得他讲课很好,不光可以听到新知识,还可以复习旧知识,简直美滋滋。视频地址是
option
- el
- 类型string | HTMLElement
- 作用:决定之后Vue实例会管理哪个DOM
- data
- 类型:Object | Function(组件中的dat啊必须是一个函数)
- 作用:Vue实力对应的数据对像。
- methods
- 类型:{[key:string]:function}
- 作用: 定义属于Vue的一些方法,可以在其他地方调用,也可以在指令中使用。
vue生命周期
vue的template
代码规范 大型前端项目要缩进2个空格,神奇。
插值语法
Mustache语法 {{}}
- 可以写变量,也可写简单表达式
v-once指令(后边不用接表达式)
- 只是执行一次。第一次展示,后来再改变的时候,不会再改变。
v-html指令
v-text
- 和Mustache语法一样。
- 一般不用,不够灵活。会覆盖之前的内容。
v-pre指令
让vue不解析,原封不动的展示,显示如下:
v-cloak (斗篷)
当js运行完之后,再展示到界面中。防止页面闪过{{}},给用户体验不好。
动态绑定属性
v-bind指令
:例如:
v-bind 动态绑定class
两种方式:
- 对象语法:
也可以这样写👇 - 数组语法:(用的少)
v-for 和v-bind的结合
v-bind 动态绑定style
- 对象语法:
- 数组语法:
计算属性 computed
- 对数据进行某种变化再进行显示。
- 计算属性的一些功能用methods可以实现为什么要用计算属性?
-
- 计算属性调用的时候不用加括号。
-
- 计算属性有缓存,用起来比methods节省空间。
<h2>{{ab}}</h2>
data:{
a:'aaaa',
b:'bbbb'
},
computed: {
ab : function(){
return this.a+this.b
}
例子:
<body>
<div id="app">
<h2> {{totalPrice}} </h2>
</div>
<script>
const app = new Vue({
el:'#app',
data:{
books:[
{id:1,name:'html+css',price:100},
{id:1,name:'javascript',price:110},
{id:1,name:'vue',price:120},
{id:1,name:'reacte',price:100}
]
},
computed: {
totalPrice : function(){
let result = 0
for(let i = 0; i < this.books.length;i++){
result += this.books[i].price
}
return result
}
}
})
</script>
</body>
es6语法补充
computed: {
totalPrice : function(){
let result = 0
// for(let i = 0; i < this.books.length;i++){
// result += this.books[i].price
// }
// return result
// es6语法
// for(let i in this.books){
// result += this.books[i].price
// }
// return result
for(let book of this.books){
result += book.price
}
return result
}
}
})
- let vs const let 是变量需要改变的时候用,const是变量不需要改变的。
- let vs var let块级作用域 var全局作用域
- const
- 尽量多用const,这个不能被改变。
- 定义标识符的时候必须赋值
- 常量的含义指的是对象不能修改,但是对象内部的属性可以改
- 对象字面量的增强写法
- 属性的增强写法:
es5写法:
es6写法: 红框部分就会直接把value补全,很方便。 - 函数的增强写法,简洁很多
- 属性的增强写法:
es5写法:
补充知识--闭包
在要写的东西外边套一层括号,后面的括号中写上参数。
第一天回顾
完整的计算属性
computed:{
Name:{
set:function(newValue){
},
get:function(){
}
}
}
一般计算属性没有set方法,是只读属性。
set写上的也不多,一般都是直接写return。
计算属性的缓存
因为计算属性用的时候只会调用一次,而methods用几次就会调用几次,性能低。vue内部缓存机制给计算属性,很强。
事件监听 v-on @
- 基本语法
<button @click="increment">+</buton> - 参数传递
- 函数如果没有参数,调用的时候可以不写小括号,
- 函数有参数,但是调用的时候没有写小括号,则会默认加上 浏览器自己生成的event事件对象作为参数传递。
- 同时需要两个参数(一个自定义,一个event),如果需要调用event对象,需要写
$event
- v-on修饰符
.stop
divC(){ console.log('divC'); }divC(){ console.log('divC'); }, butC(){ console.log('butC'); }
加上.stop
.stop
-
.prevent阻止默认事件
- .{keyCoe | keyAlias} <input type="text" @keyup.a="keyUp">
- .ntive组件监听
- .once
条件判断
v-if
-
如果是ture就显示,false就是不显示,当是false的时候,显示v-else的内容。 还有v-else-if,但是不建议这么写,这样复杂的东西要写在计算属性中比较好。
-
小案例:点击'切换登录方式'来切换用户名或者邮箱登录
<div v-if="isUser">
<label for="userLogin">用户名</label>
<input type="text" name="" id="userLogin">
</div>
<div v-else>
<label for="userLogin">邮箱</label>
<input type="text" name="" id="userLogin">
</div>
<button @click="swich">切换登录方式</button>
swich(){
this.isUser = !this.isUser
}
- 小案例的问题: 为什么我输入完之后,点击切换,切换到邮箱登录,我之前的内容还在?(按照写的代码,如果显示的邮箱的话,他是完全全新的input,按理来说什么也不显示才对)
- 因为,vue内部有虚拟dom,把要渲染的东西,先保存在虚拟dom中,你切换的时候,先把dom中的删除,然后发现新的和之前在虚拟dom中的一样,也是一个lable一个input,他就会看看改了啥,不会创建新的lable和input,只是做了相应的修改,所以之前输入的东西还在。
- 如果不想让你输入的东西复用,那就给input加一个key,input中的key值不一样就不会复用。
v-show
基本功能和v-if一样,但是当为false v-show在dom中写上display:none,而v-if是直接删除 何时用哪个? 切换频率多用v-show,只切换一次用v-if
v-for遍历数组、对象
<body>
<div id="app">
<div v-for="(item,index) in a">{{item}}-{{index+1}}</div>
<div v-for="(value,key,index) in b">{{value}}-{{key}}-{{index}}</div>
</div>
<script>
const app = new Vue({
el:'#app',
data:{
a:['a','b','c'],
b:{
name:'xiaolu',
age:18,
height:180
}
}
})
</script>
</body>
- 数组 一个参数是数组的值,两个参数是数组的值和下标。
- 对象 一个参数是value两个参数是value和key,三个参数是value、key和下标。
v-for使用过程添加key
diff算法:计算虚拟dom和真实dom的差别
如果给几个li中插入一个值。
- 不加key:就会先把f的下标改成2,然后c改成3,d改成4,e改成5,操作了很多步骤。
- 加了key的话,就直接把f的下标设置成5,插入到b的后面,节省了很多内存。
<li v-for="(item,index) in letters" v-bind:key="item">{{index}}-{{item}}</li> - 注意,key要取唯一值,如果key值重复会报错。
内部操作流程:
哪些数组的方法是响应式的
- push
- pop() 删除最后的元素 可以传入多个值
- shift 删除最前边元素 可以传入多个值
- unsift 在最前边增加元素
- splice()
- reverse()
哪些数组的方法不是响应式的
- 通过索引值,修改数组元素 不能响应
- 可以用splice代替
- 可以用vue的set方式改
Vue.set(this.letters,0,'bbbbb')
补充- 可变参数
function sum(...nums){
console.log(nums);
}
sum(1,2,3,4,5);
作业:页面显示三个电影,点击哪个哪个就变成红色
操作步骤: 当点击的时候,把curenIndex和获取到的index做比较,如果一样的话,就给他将让一个变红的class 默认cruuentIdex是0,就达到了默认是第一个变红。
<style>
.red{
color: red;
}
</style>
<div id="app">
<ul>
<li v-for="(m,index) in movies"
v-bind:class="{red:index===curentIndex}"
v-on:click="liClick(index)"
>
{{index}}-{{m}}</li>
</ul>
</div>
<script>
const app = new Vue({
el:'#app',
data:{
curentIndex:0,
movies:['少年的你','中年的你','老年的你'],
},
methods:{
liClick(index){
this.curentIndex = index
}
}
})
</script>
案例
实现如下界面和功能,并且当列表中没有商品的时候,页面显示购物车无商品。
思路
- 分为index和js两部分,css暂时不写
- index
<body>
<div id="app">
<div v-if="books.length">
<table>
<thead>
<tr>
<th>序号</th>
<th>书籍名称</th>
<th>出版日期</th>
<th>价格</th>
<th>购买数量</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(book,index) in books">
<!-- 可以这样写但是不建议,这样不能很好的操作他们 -->
<!-- <td v-for="value in book">{{value}}</td> -->
<td>{{book.id}}</td>
<td>{{book.name}}</td>
<td>{{book.date}}</td>
<td>{{book.price | showPrice}}</td>
<td>
<button v-on:click="decrement(index)" v-bind:disabled="book.count <= 1">-</button>
{{book.count}}
<button v-on:click="increment(index)">+</button>
</td>
<td> <button v-on:click="remove(index)">移除</button></td>
</tr>
</tbody>
</table>
<h2>总价格 {{totalPrice | showPrice}}</h2>
</div>
<div v-else>
购物车为空
</div>
</div>
<script src="../js/vue.js"></script>
<script src="./main.js"></script>
</body>
- js
const app = new Vue({
el:'#app',
data:{
books:[
{
id:1,
name:'《JavaScript基础》',
date:'2019-02',
price:85.00,
count:1
},
{
id:2,
name:'《JavaScript基础2》',
date:'2019-03',
price:86.00,
count:2
},
{
id:3,
name:'《JavaScript基础3》',
date:'2019-05',
price:89.00,
count:14
}
]
},
methods:{
increment(index){
this.books[index].count++
// console.log(this.books[index].count)
},
decrement(index){
this.books[index].count--
},
remove(index){
this.books.splice(index,1)
}
},
// 过滤器
filters:{
showPrice(price){
return '¥' + price.toFixed(2)
}
},
computed:{
totalPrice(){
let totalPrice = 0
for (let i = 0; i < this.books.length; i++) {
totalPrice += this.books[i].price * this.books[i].count
}
return totalPrice
}
}
})
- 在table外边套一个div的目的就是,写v-if和v-else达到当列表中没有商品的时候,页面显示购物车无商品的功能。
- table的整体思路是先写固定的表头,用vue动态补充内容。
- 点击+实现商品数量增加:写点击事件,获取当前的下标(index),然后在函数中写books[index].count++,减少商品同理。
- 点击移除:给移除绑定点击事件,获取index,然后点击一下,直接用books[index].splice(index,1)达到删除一行的操作。
- 价格显示的时候怎么显示 ¥和小数点后两位: 写一个过滤器(filters),toFixed(2)是保留两位小数(四舍五入)
filters:{
showPrice(price){
return '¥' + price.toFixed(2)
}
- 计算总价格:用计算属性(computed),显示的时候加上 过滤器 展示。
- 考虑到商品不能有负数,并且后边有移除按钮所以设置为最少是1,在 - 处写个当小于等于1的时候disabled为ture。实现无法点击的效果。
补充 保留两位小数
.toFixedtoFixed() 方法可把 Number 四舍五入为指定小数位数的数字。
例如:a=12.34,a.toFixed(2)
补充 for循环
for(let i in this.books)
编程范式:命令式/声明式编程
面向对象/面向函数编程
高阶函数
- filter:找出数组中小于5的数----判断
<script>
let a=[1,2,3,4,5,6,7,8,9];
let newA = a.filter(function(n){
return n<5;
})
console.log(newA);
</script>
- filter函数必须有一个返回值,boolean类型的
- 当返回ture的时候,就将回调的n放到新数组中,
- false的时候,就不管这次的n
- map函数:给数组每个数乘以2返回-----操作数组中的值
let newB = a.map(function(n){
return n*2
})
- reduce函数:对数组内所有数据进行汇总
箭头函数
v-model
表单元素和数据的双向绑定。
基本使用
就是 上边改会导致下边改 下边改上边也会改。
原理
包含了两个代码 v-bind、v-on
<input type="text" v-model="message">
相当于
<input type="text" v-bind:value="message" v-on:input="message = "$event.target.value">
v-model和radio
v-model 可以达到name的作用
v-model和checkbox
- 只有一个按钮 一般是boolean值
- 多选框 用数组存
<body>
<div id="app">
<input type="radio" value="男" v-model="sex">男
<input type="radio" value="女" v-model="sex">女
{{sex}}
<div>
<input type="checkbox" name="" id="" value="1" v-model="nums">1
<input type="checkbox" name="" id="" value="2" v-model="nums">2
<input type="checkbox" name="" id="" value="3" v-model="nums">3
<input type="checkbox" name="" id="" value="4" v-model="nums">4
</div>
{{nums}}
</div>
<script>
const app = new Vue({
el:'#app',
data:{
message:'niaho',
sex:'',
nums:[]
}
})
</script>
</body>
v-model和select
值绑定
就是开发中 值是后台获取的,不是写死的。
修饰符 .
- lazy 敲回车或者失去焦点才进行变量更新
- number 就是在输入框输入文字的时候默认是string类型,写上
.number的时候,就会转换成number类型。 - trim 去除开头和结尾的空格。
组件化
什么是组件化
vue的组件化
如何使用组件化
- 创建组件构造器 :调用
Vue.extend()方法创建构造器
es6补充
引号可以换成`,这样定义的变量可以换行。
const a= `aa
bb`
全剧组件 和 局部组件
以上就是全局组件的注册 以下是局部组件的注册👇
父组件和子组件的区分
vue实例也可以当做组件,一般叫做root组件。
- 子组件在父组件注册的时候,不能在全局使用。只能在父组件中使用,想要使用必须注册。
语法糖
组件模板抽离
- 第一种写法,在上边写个script标签,类型是x-tempate,然后注册的时候关联他的id。
- 第二种写法:直接写tempalate标签,然后关联id就行了
组件访问vue实例中的数据
- 组件不能访问组件中的数据
- 要在组件注册的时候,放在data函数中,这是一个函数,和vue实例中的不同,
组件中data为什么必须是个函数?
因为函数的每次调用都会在内存中新增一个,这样这个组件每次调用的时候都是一个新的相互独立的, 例如一个计数器,你在主页调用的时候是计数到2了,如果data不是函数的话,子页面也都是2,就起不到单独计数的功能了。
父子组件之间的通讯
父组件向子组件传递 props
在注册组件的时候写一个props,然后在调用的时候写v-bind绑定一下,之后就可以取到数据了。
props 驼峰命名的坑
驼峰命名要改成-
子组件传给父组件
常用的方法是,子组件传递一个事件给父组件,这时候就需要一个自定义事件来完成,
之前学的v-on只学了监听dom事件,其实他还可以监听自定义事件,
自定义事件的流程,
- 子组件中,通过
$emit()来触发事件, - 父组件中,通过v-on来监听子组件事件。