前言
自学coderwhy的vue视频,仅做笔记用于自己复习
文章目录
1-初识Vuejs
1.1什么是MVVM
1.2 Vue的MVVM
-
View层:
- 视图层
- 在我们前端开发中,通常就是DOM层。
- 主要的作用是给用户展示各种信息。
-
Model层:
- 数据层
- 数据可能是我们固定的死数据,更多的是来自我们服务器,从网络上请求下来的数据。
- 在我们计数器的案例中,就是后面抽取出来的obj,当然,里面的数据可能没有这么简单。
-
VueModel层:
- 视图模型层
- 视图模型层是View和Model沟通的桥梁。
- 一方面它实现了Data Binding,也就是数据绑定,将Model的改变实时的反应到View中
- 另一方面它实现了DOM Listener,也就是DOM监听,当DOM发生一些事件(点击、滚动、touch等)时,可以监听到,并在需要的情况下改变对应的Data。
1.3 创建Vue示例传入的options
以上为例,options中包含以下选项
- el:
- 类型:string | HTMLElement
- 作用:决定之后Vue实例会管理哪一个DOM。
- data:
- 类型:Object | Function (组件当中data必须是一个函数)
- 作用:Vue实例对应的数据对象。
- methods:
- 类型:{ [key: string]: Function }
- 作用:定义属于Vue的一些方法,可以在其他地方调用,也可以在指令中使用。
开发中什么时候称之为方法,什么时候称之为函数
方法:定义在类里的,和实例挂钩
1.4 Vue的生命周期
2-模板语法
2.1 插值操作
-
Mustache ( {{ }} )
Mustache语法中,不仅可以直接写变量,也可以写简单的表达式
<div id="app"> <h2>{{message}}</h2> <h2>{{message}},李银河!</h2> <h2>{{firstName + lastName}}</h2> <h2>{{firstName + ' ' + lastName}}</h2> <h2>{{firstName}} {{lastName}}</h2> <h2>{{counter * 2}}</h2> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { message: 'Hello', firstName: '德文', lastName: '布莱特', counter: 100 } }) </script>
-
v-once
只渲染元素和组件一次,不会随着数据的改变而改变。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。
<h2 v-once>{{message}}</h2>
<!--第一次渲染完成,显示 Hello-->
<!--当使用app.message = '你好',h2不会改变内容-->
- v-html
更新元素的 innerHTML
。注意:内容按普通 HTML 插入 - 不会作为 Vue 模板进行编译。你的站点上动态渲染的任意 HTML 可能会非常危险,因为它很容易导致 XSS 攻击。请只对可信内容使用 HTML 插值,绝不要对用户提供的内容使用插值。
<div id="app">
<h2>{{url}}</h2>
<h2 v-html="url"></h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'Hello',
url: '<a href="http://www.baidu.com">百度一下</a>'
}
})
</script>
- v-text
更新元素的 textContent
。不灵活,不推荐使用。如果要更新部分的 textContent
,需要使用 {{ Mustache }}
插值。
<span v-text="msg"></span>
<!-- 和下面的一样 -->
<span>{{msg}}</span>
- v-pre
跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译。
<div id="app" v-pre>{{message}}</div>
<!-- 显示{{message}} -->
- v-cloak
这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none }
一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。
当网站卡住,会导致闪动:数据没有拿到显示{{message}},等待数据拿到之后再显示数据Hello
[v-cloak] {
display: none;
}
<div id="app" v-cloak>{{message}}</div>
2.2 绑定属性
除了内容需要动态来决定外,某些属性我们也希望动态来绑定。
v-bind:动态绑定一个或多个属性值,或者向另一个组件传递props值
<img v-bind:src="imgURL" alt="">
<a v-bind:href="aHref">百度一下</a>
- 简写(语法糖的写法) :
<img :src="imgURL" alt="">
<a :href="aHref">百度一下</a>
-
绑定class
<script> const app = new Vue({ el: '#app', data: { message: 'Hello', isActive: true, isLine: true, active: 'aaa', line: 'bbbb' }, methods: { btnClick: function() { this.isActive = !this.isActive }, getClasses: function() { return { active: this.isActive, line: this.isLine } } } }) </script>
-
绑定方式:对象语法(:class后面跟的是一个对象)
- 直接通过{}绑定一个类
<h2 :class="{'active': isActive}">Hello World</h2>
- 用法二:也可以通过判断,传入多个值
<h2 :class="{'active': isActive, 'line': isLine}">Hello World</h2> <!-- isActive为true时,类名active生效;line同理 -->
- 用法三:和普通的类同时存在,并不冲突
注:如果isActive和isLine都为true,那么会有title/active/line三个类共存
<h2 class="title" :class="{'active': isActive, 'line': isLine}">Hello World</h2>
- 用法四:如果过于复杂,可以放在一个methods或者computed中
注:classes是一个计算属性
<h2 class="title" :class="getClasses()">Hello World</h2>
-
绑定方式:数组语法(:class后面跟的是一个数组)
<div id="app"> <!-- 数组中的内容不加引号,表示变量 --> <h2 :class="[active, line]">{{message}}</h2> <h2 :class="getClasses()">{{message}}</h2> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { message: 'Hello', active: 'aaaa', line: 'bbbb' }, methods: { getClasses: function() { return [this.active, this.line] } } }) </script>
- 用法一:直接通过{}绑定一个类
<h2 :class="[active]">Hello World</h2>
- 用法二:也可以传入多个值
<h2 :class="[active, line]">Hello World</h2>
- 用法三:和普通的类同时存在,并不冲突
注:会有title/active/line三个类
<h2 class="title" :class="[active, line]">Hello World</h2>
- 用法四:如果过于复杂,可以放在一个methods或者computed中
注:classes是一个计算属性
<h2 class="title" :class="getClasses()">Hello World</h2>
-
-
绑定style
在写CSS属性名的时候,比如font-size:我们可以使用驼峰式 (camelCase) fontSize 或 短横线分隔 (kebab-case,记得用单引号括起来) ‘font-size’
- 绑定方式:对象语法(:class后面跟的是一个对象)
<div id="app"> <!-- <h2 :style="{key(属性名): value(属性值)}"></h2> --> <h2 :style="{fontSize: '50px'}">{{message}}</h2> <!-- 不加单引号,会当成变量报错 --> <h2 :style="{fontSize: finalSize+ 'px'}">{{message}}</h2> <!-- finalSize当成变量使用 --> <h2 :style="{fontSize: finalSize + 'px', backgroundColor: finalColor}">{{message}}</h2> <h2 :style="getStyles()">{{message}}</h2> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { message: 'Hello', finalSize: 100, finalColor: 'red' }, methods: { getStyles: function() { return { fontSize: this.finalSize + 'px', backgroundColor: this.finalColor } } } }) </script>
- 绑定方式:数组语法(:class后面跟的是一个数组)
<div id="app"> <!-- 其中存储的是变量 --> <h2 :style="[baseStyle, baseStyle1]">{{message}}</h2> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { message: 'Hello', baseStyle: { fontSize: '100px' }, baseStyle1: { backgroundColor: 'red' } } }) </script>
2.3 计算属性
- 计算属性基本使用
<div id="app">
<!-- 1.直接拼接:语法过于繁琐 -->
<h2>{{firstName}} {{lastName}}</h2>
<!-- 2.通过定义methods -->
<h2>{{getFullName()}}</h2>
<!-- 3.通过computed -->
<h2>{{fullName}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'Hello',
firstName: 'Leborn',
lastName: 'James'
},
// 最好用名词命名
computed: {
fullName: function() {
return this.firstName + ' ' + this.lastName
}
},
methods: {
getFullName() {
return this.firstName + ' ' + this.lastName
}
}
})
</script>
- 计算属性的复杂操作
<div id="app">
<h2>总价格:{{totalPrice}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'Hello',
books: [{
id: 110,
name: 'Unix编程艺术',
price: 100
}, {
id: 111,
name: '代码大全',
price: 120
}, {
id: 112,
name: '深入理解计算机原理',
price: 98
}, {
id: 113,
name: '现代操作系统',
price: 60
}]
},
computed: {
totalPrice: function() {
let sum = 0;
for (let i = 0; i < this.books.length; i++) {
sum += this.books[i].price
}
// 其他for写法
// forin
for (let i in this.books) {
sum += this.books[i].price
}
// forof
for (let item of this.books) {
sum += item.price
}
return sum
}
}
})
</script>
- 计算属性的setter和getter
每个计算属性都包含一个getter和一个setter,但setter不常用
<div id="app">
<h2>{{fullName}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
firstName: '德文',
lastName: '布莱特'
},
computed: {
//
// fullName: function() {
// return this.firstName + ' ' + this.lastName
// }
// 计算属性一般是没有set方法,只读属性
fullName: {
// fullName发生改变时会自动回调该方法
// 当 app.fullName = 'Lebron James',会调用set函数把值传给newValue
set: function(newValue) {
// 一般不需要设置
// console.log(newValue);
let names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[1]
},
get: function() {
return this.firstName + ' ' + this.lastName
}
}
}
})
</script>
- computed和methods的对比
- 通过定义methods
- 每当触发重新渲染时,调用方法将总会再次执行函数
- 通过computed
- 计算属性会进行缓存,如果多次使用时,计算属性只会调用一次。
- 除非依赖的响应式 property 变化才会重新计算
所以计算属性computed性能更高
2.4 事件监听
绑定事件监听器:v-on,缩写:@
- 基本使用
<div id="app">
<h2>当前计数: {{counter}}</h2>
<!-- 简单操作 -->
<button @click="counter++">+</button>
<button @click="counter--">-</button>
<!-- ---------------------------- -->
<button @click="add">+</button>
<button @click="sub">-</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app', // 挂载要管理的元素
// 或者 document.querySelector('#app')
data: {
counter: 0
},
methods: {
add: function() {
console.log('add被执行');
this.counter++;
},
sub: function() {
console.log('sub被执行');
this.counter--;
}
}
})
</script>
- 事件监听参数问题
当通过methods中定义方法,以供@click调用时,需要注意参数问题:
- 情况一:如果该方法不需要额外参数,那么方法后的()可以不添加。
- 但是注意:如果方法本身中有一个参数,那么会默认将原生事件event参数传递进去
- 情况二:如果需要同时传入某个参数,同时需要event时,可以通过$event传入事件。