Vue 基础知识
一、初识 Vue
Vue 是一个渐进式的框架,什么是渐进式的呢?
- 渐进式意味着你可以将 Vue 作为你应用的一部分嵌入其中,带来更丰富的交互体验。
- 或者如果你希望将更多的业务逻辑使用 Vue 实现,那么 Vue 的核心库以及其生态系统。
- 比如 Core+Vue-router+Vuex,也可以满足你各种各样的需求。
Vue 有很多特点和 Web 开发中常见的高级功能
- 解耦视图和数据
- 可复用的组件
- 前端路由技术
- 状态管理
- 虚拟 DOM
1、Vue 中的 MVVM

View 层:
视图层
在我们前端开发中,通常就是 DOM 层。
主要的作用是给用户展示各种信息。
Model 层:
- 数据层
- 数据可能是我们固定的死数据,更多的是来自我们服务器,从网络上请求下来的数据。
- 在我们计数器的案例中,就是后面抽取出来的 obj,当然,里面的数据可能没有这么简单。
VueModel 层:
- 视图模型层
- 视图模型层是 View 和 Model 沟通的桥梁。
- 一方面它实现了 Data Binding,也就是数据绑定,将 Model 的改变实时的反应到 View 中
- 另一方面它实现了 DOM Listener,也就是 DOM 监听,当 DOM 发生一些事件(点击、滚动、touch 等)时,可以监听到,并在需要的情况下改变对应的 Data。
2、Vue 的生命周期


3、Vue 的基本语法
3.1、Mustache
如何将 data 中的文本数据,插入到 HTML 中呢?
我们已经学习过了,可以通过 Mustache(插值)语法(也就是双大括号)。
Mustache: 胡子/胡须.
我们可以像下面这样来使用,并且数据是响应式的
<div id="app">
<h2>{{message}}</h2>
<h1>{{name}}</h1>
</div>
<div>{{message}}</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app", // 用于挂载要管理的元素
data: {
// 定义数据
message: "你好啊,李银河!",
name: "coderwhy",
},
});
</script>3.2、常见的基本指令
1、v-once
该指令后面不需要跟任何表达式(比如之前的 v-for 后面是由跟表达式的)
该指令表示元素和组件只渲染一次,不会随着数据的改变而改变
<div id="app">
<h2>{{message}}</h2>
<h2 v-once>{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
message: "你好啊",
},
});
</script>2、v-html
某些情况下,我们从服务器请求到的数据本身就是一个 HTML 代码
如果我们直接通过插值语法来输出,会将 HTML 代码也一起输出。
但是我们可能希望的是按照 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: "你好啊",
url: '<a href="http://www.baidu.com">百度一下</a>',
},
});
</script>3.3、属性绑定
3.3.1、动态绑定 classs 属性
很多时候,我们希望动态的来切换 class,比如:当数据为某个状态时,字体显示红色。当数据另一个状态时,字体显示黑色。
绑定 class 有两种方式:对象语法 数组语法
1、对象语法有下面这些用法:
用法一:直接通过{}绑定一个类
<h2 :class="{'active': isActive}">Hello World</h2>
用法二:也可以通过判断,传入多个值
<h2 :class="{'active': isActive, 'line': isLine}">Hello World</h2>
用法三:和普通的类同时存在,并不冲突
注:如果isActive和isLine都为true,那么会有title/active/line三个类
<h2 class="title" :class="{'active': isActive, 'line': isLine}">Hello World</h2>
用法四:如果过于复杂,可以放在一个methods或者computed中
注:classes是一个计算属性
<h2 class="title" :class="classes">Hello World</h2>
具体示例代码:
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.active {
color: red;
}
</style>
</head>
<body>
<div id="app">
<h2 class="title" v-bind:class="{active: isActive, line: isLine}">{{message}}</h2>
<h2 class="title" v-bind:class="getClasses()">{{message}}</h2>
<button v-on:click="btnClick">按钮</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
isActive: true,
isLine: true
},
methods: {
btnClick: function () {
this.isActive = !this.isActive
},
getClasses: function () {
return {active: this.isActive, line: this.isLine}
}
}
})
</script>2、数组语法有下面这些用法:
用法一:直接通过{}绑定一个类
<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="classes">Hello World</h2>
具体示例代码:
<div id="app">
<h2 class="title" :class="[active, line]">{{message}}</h2>
<h2 class="title" :class="getClasses()">{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
active: 'aaaaaa',
line: 'bbbbbbb'
},
methods: {
getClasses: function () {
return [this.active, this.line]
}
}
})
</script>3.3.2、动态绑定 style 属性
我们可以利用 v-bind:style 来绑定一些 CSS 内联样式。
在写 CSS 属性名的时候,比如 font-size,我们可以使用驼峰式 (camelCase) fontSize 或短横线分隔 (kebab-case,记得用单引号括起来) ‘font-size’
绑定 class 有两种方式:对象语法 数组语法
1、绑定方式一:对象语法
:style="{color: currentColor, fontSize: fontSize + 'px'}"
style后面跟的是一个对象类型 对象的key是CSS属性名称
对象的value是具体赋的值,值可以来自于data中的属性
<head>
<meta charset="UTF-8" />
<title>Title</title>
<style>
.title {
font-size: 50px;
color: red;
}
</style>
</head>
<body>
<div id="app">
<!--<h2 :style="{key(属性名): value(属性值)}">{{message}}</h2>-->
<!--'50px'必须加上单引号, 否则是当做一个变量去解析-->
<!--<h2 :style="{fontSize: '50px'}">{{message}}</h2>-->
<!--finalSize当成一个变量使用-->
<!--<h2 :style="{fontSize: finalSize}">{{message}}</h2>-->
<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: "你好啊",
finalSize: 100,
finalColor: "red",
},
methods: {
getStyles: function () {
return {
fontSize: this.finalSize + "px",
backgroundColor: this.finalColor,
};
},
},
});
</script>
</body>2、绑定方式二:数组语法
<div v-bind:style="[baseStyles, overridingStyles]"></div>
style后面跟的是一个数组类型 多个值以,分割即可
<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: "你好啊",
baseStyle: { backgroundColor: "red" },
baseStyle1: { fontSize: "100px" },
},
});
</script>3.4、计算属性
我们知道,在模板中可以直接通过插值语法显示一些 data 中的数据。
但是在某些情况,我们可能需要对数据进行一些转化后再显示,或者需要将多个数据结合起来进行显示
比如我们有 firstName 和 lastName 两个变量,我们需要显示完整的名称。
但是如果多个地方都需要显示完整的名称,我们就需要写多个
示例1
<div id="app">
<h2>{{firstName + ' ' + lastName}}</h2>
<h2>{{firstName}} {{lastName}}</h2>
<h2>{{getFullName()}}</h2>
<h2>{{fullName}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
firstName: "Lebron",
lastName: "James",
},
// computed: 计算属性()
computed: {
fullName: function () {
return this.firstName + " " + this.lastName;
},
},
methods: {
getFullName() {
return this.firstName + " " + this.lastName;
},
},
});
</script>
示例2
<div id="app">
<h2>总价格: {{totalPrice}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
books: [
{ id: 110, name: "Unix编程艺术", price: 119 },
{ id: 111, name: "代码大全", price: 105 },
{ id: 112, name: "深入理解计算机原理", price: 98 },
{ id: 113, name: "现代操作系统", price: 87 },
],
},
computed: {
totalPrice: function () {
let result = 0;
for (let i = 0; i < this.books.length; i++) {
result += this.books[i].price;
}
return result;
},
},
});
</script>3.4.1、计算属性的 setter 和 getter
每个计算属性都包含一个 getter 和一个 setter
在上面的例子中,我们只是使用 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: 'Lebron',
lastName: 'James'
},
// computed: 计算属性()
computed: {
fullName: {
set(newValue){
const names=newValue.split(" ")
this.firstName=names[0];
this.lastName=name[1];
},
get(){return this.firstName + ' ' + this.lastName}
}
},
}
})
</script>3.5、事件监听
3.5.1、v-on 修饰符
在某些情况下,我们拿到 event 的目的可能是进行一些事件处理。
Vue 提供了修饰符来帮助我们方便的处理一些事件:
- .stop - 调用 event.stopPropagation()。
- .prevent - 调用 event.preventDefault()。
- .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
- .native - 监听组件根元素的原生事件。
- .once - 只触发一次回调。
<div id="app">
<div @click="divClick">
<button @click.stop="btnClick">按钮</button>
</div>
<a href="http://www.baidu.com" @click.prevent="aClick">百度一下</a>
<!--<input type="text" @keyup.enter="onEnter">-->
<input type="text" @keyup.13="onEnter">
<button @click.once="btnClick"></button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
},
methods: {
divClick() {
console.log('divClick');
},
btnClick() {
console.log('btnClick');
},
aClick() {
console.log('aClick');
},
onEnter() {
console.log('enter被点击');
}
}
})
</script>3.6、v-model 双向绑定
3.6.1、v-model 修饰符
lazy修饰符:默认情况下,v-model 默认是在 input 事件中同步输入框的数据的。也就是说,一旦有数据发生改变对应的 data 中的数据就会自动发生改变。
lazy 修饰符可以让数据在失去焦点或者回车时才会更新number修饰符:默认情况下,在输入框中无论我们输入的是字母还是数字,都会被当做字符串类型进行处理。但是如果我们希望处理的是数字类型,那么最好直接将内容当做数字处理。number 修饰符可以让在输入框中输入的内容自动转成数字类型trim修饰符:如果输入的内容首尾有很多空格,通常我们希望将其去除 trim 修饰符可以过滤内容左右两边的空格
<div id="app">
<input type="text" v-model.lazy="message1">
<h2>{{message1}}</h2>
<input type="number" v-model="message2">
<h2>{{message2}}-{{typeof message2}}</h2>
<input type="text" v-model.trim="message3">
<h2>{{message3}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
message1: "",
message2: 0,
message3: "",
},
});
</script>
