一、Vue.js是什么?
目前典型的前端三大框架:Angular.js、React.js、Vue.js。其中,Vue.js框架更容易上手,灵活度更高,在企业级开发中受到前端开发人员的青睐。
Vue.js的官方文档中是这样介绍的:简单小巧的核心,渐进式的技术栈,足以应付任何规模的应用。
Vue.js的官方文档介绍详情:介绍 — Vue.js (vuejs.org)https://cn.vuejs.org/v2/guide/index.html
1.1 创建一个 Vue 应用(HelloWorld 例子)
官方文档创建HelloWorld例子:介绍 — Vue.js (vuejs.org)https://cn.vuejs.org/v2/guide/
创建一个HelloWorld.html文件,然后通过如下方式引入 Vue:
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统:
<div id="app">
{{ message }}
</div>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
</script>
运行结果:
1.2 MVVM模式
与知名的前端框架Angular.js等一样,Vue.js在设计上也是使用的MVVM(Mode-View-ViewModel)模式。
- M:模型(Model) :负责数据存储,对应data 中的数据。
- V:视图(View) :负责页面展示,对应DOM元素。
- VM:视图模型(ViewModel) :负责业务逻辑处理,对数据进行加工后交给视图展示,对应 Vue 实例对象。
1.3 单文件组件
Vue.js自定义了一种xxx.vue文件,可以把HTML、CSS、JS代码写到一个文件中,从而实现对一个组件的封装,一个xxx.vue文件就是一个单独的组件。
使用脚手架Vue-cli创建的一个大觅项目,项目模板自带的单文件组件HelloWorld.vue。
HelloWorld.vue示例代码:
<!--template中都是HTML,定义了页面中显示的内容,template不会被页面解析,分隔代码的作用-->
<template>
<div class="hello">
<h1>{{ msg }}</h1>
</div>
</template>
<!-- 定义了组件中需要的数据和操作-->
<script>
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
}
}
</script>
<!-- CSS样式,scoped表明这里的css样式只适用于该组件 -->
<style scoped>
h1{
font-weight: normal;
}
</style>
在单文件组件中,data必须是一个函数,它返回一个对象,返回的对象的数据供组件实现。
二、Vue实例与数据绑定
Vue实例是Vue框架的入口,也是前端的ViewModel,它包含了页面中的业务逻辑处理、数据模型等。使用脚手架Vue-cli创建的一个大觅项目中的main.js就是项目的入口文件。
main.js部分示例代码:
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
- el:提供一个在页面上已存在的DOM元素作为Vue实例的挂载目标。大觅项目中是将vue实例挂载到index.html中id=app的div中。
- router:这里是省略写法,正常写法是router:router。代表传入路由的实例对象,把配置的路由功能运用到整个项目中,大觅项目中配置的路由组件是HelloWorld组件。
- components:包含Vue实例可用组件的哈希表。
- template:一个字符串模板,作为Vue实例的标识使用。模板会替换挂载元素,在大觅项目中会将app.vue的内容替换“<div id="app"></div>”进行页面显示。
2.1 插值表达式
语法:{{ ... }}
插值表达式可以理解为使用双大括号来包裹JS代码,作用是将双大括号中的数据替换成对应属性值进行展示。
插值表达式中可以写入以下内容:
- JSON数据
- 数字
- 字符串
- 插值表达式
示例代码(HelloWorld.vue):
<!-- template中都是HTML,定义了页面中显示的内容,template不会被页面解析,分隔代码的作用-->
<template>
<div class="hello">
<!-- json数据变量 -->
<h1>{{ msg }}</h1>
<!-- 数字 -->
<p>{{10}}</p>
<!-- 字符串 -->
<h1>{{"string"}}</h1>
<!-- 表达式 -->
<h1>{{1+1}}</h1>
<h1>{{'hello'+name}}</h1>
<h1>{{2>3?'true':'false'}}</h1>
</div>
</template>
<!-- 定义了组件中需要的数据和操作-->
<script>
export default {
name: 'HelloWorld',
data () {
return {
name:'张三',
msg: 'Welcome to Your Vue.js App'
}
}
}
</script>
<!-- CSS样式,scoped表明这里的css样式只适用于该组件 -->
<style scoped>
</style>
在插值表达式中需要注意区分变量和字符串,使用引号包裹的为字符串,没有使用引号包裹的都会被系统解析成变量名和方法名。
2.2 生命周期
所谓“生命周期”,是指示例对象从构造函数开始执行(被创建)到GC(GarbageCollection,垃圾回收)回收销毁的整个存在时期,在生命周期中被自动调用的函数叫做生命周期函数,也被形象地称为生命周期钩子函数。
生命周期函数的作用:
在Vue实例对象从创建到被回收的整个过程中,不同的时期会有不同的钩子函数,可以利用不同时期的钩子函数完成不同的操作。例如需要在某个时期去获取后台数据、在某个时期去更新数据等。
表2.2 生命周期函数
生命周期函数 | 含义 |
beforeCreate(创建前) | 组件实例刚刚被创建,组件属性计算之前,比如data属性等 |
Created(创建后) | 组件实例刚刚被创建完成,属性已经绑定,此时DOM还未生成, $el属性还不存在 |
beforeMount(载入前) | 模板编译、挂载之前 |
mounted(载入后) | 模板编译、挂载之后 |
beforeUpdate(更新前) | 组件更新之前 |
updated(更新后) | 组件更新之后 |
beforeDestroy(销毁前) | 组件销毁前调用 |
destroyed(销毁后) | 组件销毁后调用 |
几个常用的生命周期函数,以及在这些函数中可以完成的事情:
beforeCreate生命周期函数在组件实例刚被创建的时候增加一些loading事件。
created生命周期函数可以结束loading事件,完成一些初始化,实现函数自执行。
mounted是比较重要的生命周期函数,可以发起后端请求,取回数据,接收页面之间传递的参数、由子组件向父组件传递参数等。
代码示例(HelloWorld.vue):
<template>
<div class="hello">
<!-- json数据变量 -->
<h1>{{ msg }}</h1>
</div>
</template>
<!-- 定义了组件中需要的数据和操作-->
<script>
export default {
name: 'HelloWorld',
data () {
return {
name:'张三',
msg: 'Welcome to Your Vue.js App'
};
},
beforeMount:function(){
console.group("---beforeMount挂载前状态---");
console.log("el:"+this.$el); //已被初始化
console.log("data:"+this.$data); //已被初始化
console.log("msg:"+this.msg); //已被初始化
// 到这个时期,data和el都被初始化
},
mounted:function(){
console.group("---Mounted挂载后状态---");
console.log("el:"+this.$el); //已被赋值
console.log("data:"+this.$data); //已被初始化
console.log("msg:"+this.msg); //已被初始化
},
}
</script>
<!-- CSS样式,scoped表明这里的css样式只适用于该组件 -->
<style scoped>
</style>
三、class与style绑定
3.1 v-bind指令
语法 在HTML元素的开始标签 v-bind:属性名="常量||变量名"
简写 :属性名="常量||变量名"
<div v-bind:原属性名="变量"> </div>
<!-- 简写 -->
<div :属性名="变量"> </div>
示例代码:
<template>
<div class="hello">
<!-- json数据变量 -->
<h1>{{ msg }}</h1>
<a v-bind:href="url">链接1</a><br/><br/>
<!-- v-bind可以省略,简写为 -->
<a :href="url">链接2</a>
</div>
</template>
<!-- 定义了组件中需要的数据和操作-->
<script>
export default {
name: 'HelloWorld',
data () {
return {
msg:'Welcome to Your Vue.js App',
url:'http://www.baidu.com'
};
},
}
</script>
<!-- CSS样式,scoped表明这里的css样式只适用于该组件 -->
<style scoped>
</style>
3.2 v-bind绑定class
很多时候,我们希望动态的来切换class,比如:
- 当数据为某个状态时,div有边框。
- 当数据另一个状态时,div没有边框。
绑定class有两种方式:
- 对象语法
- 对象语法的含义是 :class后面跟的是一个对象{ }
- 数组语法
- 数组语法的含义是 :class后面跟的是一个数组[ ]
3.2.1 对象语法
单个属性的对象语法示例代码:
<template>
<div class="hello">
<!-- json数据变量 -->
<h1>{{ msg }}</h1>
<a v-bind:href="url">链接1</a><br/><br/>
<!-- v-bind可以省略,简写为 -->
<a :href="url">链接2</a><br/><br/>
<div :class="{active:isActive}">对象语法: 我是可以动态改变样式的div </div>
</div>
</template>
<!-- 定义了组件中需要的数据和操作-->
<script>
export default {
name: 'HelloWorld',
data () {
return {
msg:'Welcome to Your Vue.js App',
url:'http://www.baidu.com',
isActive:true
};
},
}
</script>
<!-- CSS样式,scoped表明这里的css样式只适用于该组件 -->
<style scoped>
.active{
height: 35px;
line-height: 35px;
border: 2px solid black;
}
</style>
对象语法中也可以传入多个属性来动态切换class。而且动态绑定的class可以与普通的class共存。
多个属性的对象语法示例代码:
<template>
<div class="hello">
<!-- json数据变量 -->
<h1>{{ msg }}</h1>
<a v-bind:href="url">链接1</a><br/><br/>
<!-- v-bind可以省略,简写为 -->
<a :href="url">链接2</a><br/><br/>
<div :class="{active:isActive}">对象语法: 我是可以动态改变样式的div </div>
<div class="static" :class="{active:isActive,danger:hasError}">多个属性的对象语法 </div>
</div>
</template>
<!-- 定义了组件中需要的数据和操作-->
<script>
export default {
name: 'HelloWorld',
data () {
return {
msg:'Welcome to Your Vue.js App',
url:'http://www.baidu.com',
isActive:true,
hasError:false
};
},
}
</script>
<!-- CSS样式,scoped表明这里的css样式只适用于该组件 -->
<style scoped>
.active{
height: 35px;
line-height: 35px;
border: 2px solid black;
}
.static{
margin:50px auto;
}
.danger{
background:#ff0;
}
</style>
3.2.2 数组语法
当需要应用多个class时,可以使用数组语法,给 :class 绑定一个数组,应用一个class列表。
示例代码:
<template>
<div class="hello">
<!-- json数据变量 -->
<h1>{{ msg }}</h1>
<a v-bind:href="url">链接1</a><br/><br/>
<!-- v-bind可以省略,简写为 -->
<a :href="url">链接2</a><br/><br/>
<!-- 绑定class方式:对象语法 -->
<div :class="{active:isActive}">对象语法: 我是可以动态改变样式的div </div>
<div class="static" :class="{active:isActive,danger:hasError}">多个属性的对象语法 </div>
<!-- 绑定class方式:数组语法 -->
<div :class="[activeClass,errClass]">数组语法</div>
</div>
</template>
<!-- 定义了组件中需要的数据和操作-->
<script>
export default {
name: 'HelloWorld',
data () {
return {
msg:'Welcome to Your Vue.js App',
url:'http://www.baidu.com',
isActive:true,
hasError:false,
activeClass:"active",
errorClass:"static"
};
},
}
</script>
<!-- CSS样式,scoped表明这里的css样式只适用于该组件 -->
<style scoped>
.active{
height: 35px;
line-height: 35px;
border: 2px solid black;
}
.static{
margin:50px auto;
}
.danger{
background:#ff0;
}
</style>
使用三元表达式来根据条件切换class,示例代码:
<div class="hello">
<!-- json数据变量 -->
<h1>{{ msg }}</h1>
<a v-bind:href="url">链接1</a><br/><br/>
<!-- v-bind可以省略,简写为 -->
<a :href="url">链接2</a><br/><br/>
<!-- 绑定class方式:数组语法 -->
<div :class="[activeClass,errorClass]">数组语法</div>
<!--三元表达式来根据条件切换class-->
<div :class="[isActive?activeClass:'',errorClass]">三元表达式的数组语法</div>
</div>
</template>
<!-- 定义了组件中需要的数据和操作-->
<script>
export default {
name: 'HelloWorld',
data () {
return {
msg:'Welcome to Your Vue.js App',
url:'http://www.baidu.com',
isActive:true,
activeClass:"active",
errorClass:"static"
};
},
}
</script>
<!-- CSS样式,scoped表明这里的css样式只适用于该组件 -->
<style scoped>
.active{
height: 35px;
line-height: 35px;
border: 2px solid black;
}
.static{
margin:50px auto;
}
.danger{
background:#ff0;
}
</style>
3.3 v-bind绑定内联样式
使用v-bind:style(即 :style )可以给元素绑定内联样式,方法与 :class 类似。
第一种写法:
<template>
<div class="hello">
<!-- json数据变量 -->
<h1>{{ msg }}</h1>
<div :style="{border:activeColor,fontSize:fs+'px'}">绑定内联样式</div>
</div>
</template>
<!-- 定义了组件中需要的数据和操作-->
<script>
export default {
name: 'HelloWorld',
data () {
return {
msg:'Welcome to Your Vue.js App',
activeColor:"1px solid #000",
fs:40
};
},
}
</script>
<!-- CSS样式,scoped表明这里的css样式只适用于该组件 -->
<style scoped>
</style>
第二种写法:
<template>
<div class="hello">
<!-- json数据变量 -->
<h1>{{ msg }}</h1>
<div :style="style">绑定内联样式</div>
</div>
</template>
<!-- 定义了组件中需要的数据和操作-->
<script>
export default {
name: 'HelloWorld',
data () {
return {
msg:'Welcome to Your Vue.js App',
style:{
border:'1px solid #000', //border属性名不能乱写
fontSize:40+'px' //fontSize属性名不能乱写
}
};
},
}
</script>
<!-- CSS样式,scoped表明这里的css样式只适用于该组件 -->
<style scoped>
</style>