MVVM
- View 层:
- 视图层
- 在我们前端开发中,通常就是 DOM 层
- 主要的作用是给用户展示各种信息
- Model 层:
- 数据层
- 数据可能是我们固定的死数据,更多的是来自我们服务器,从网络上请求下来的数据
- ViewModel 层:
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
vscode 模版
设置——用户代码片段——输入html(获得一个josn文件)——把代码片段放入 body
此时输入 vue 就可以快速输入模版内容
Mustache 语法
插值操作
v-once
内容只渲染一次,不会根据数据的改变而改变
<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-if
与 v-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>