Vue
特点
- 一个轻量级的mvvm框架,双向绑定,数据动态更新,gzip后大小只有20k+
- 是一个渐进式框架,其核心思想是数据驱动、组件化的前端开发
- 原生html页面是通过js 操作的是dom,而vue.js操作的是数据。
- 和传统前端开发开发的关注点完全不同,传统方式关注的是都像的document结构的api,而vue关注的是数据。
- 优点显而易见,从而屏蔽了使用复杂晦涩难记的dom结构api。
Vue的使用
导入Vue.js,准备数据渲染区,创建vue对象
创建vue对象的两种方式:
1、先定义变量,在创建对象
var a = {
msg: "Hello World!"
// 此处为Moudel
}
var com = {
el: "#app1",
data: a
}
// 此处用于连接View和Moudel为VM
var v = new Vue(com)
2.直接创建对象
new Vue({
//el属性用于描述元素(挂载点),data属性是具体要展示的数据
el : "#app",//使用id选择器将data中的数据渲染在挂载点
data : {
msg:"Hello Vue!"
}
})
示例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>入门案例</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 插入值表达式 -->
{{msg}}
<!-- 挂载点 -->
</div>
<div id="app1">
{{msg}}
</div>
<!-- 此处为view -->
</body>
<script>
var a = {
msg: "Hello World!"
// 此处为Moudel
}
var com = {
el: "#app1",
data: a
}
// 此处用于连接View和Moudel为VM
var v = new Vue(com)
new Vue({
//el属性用于描述元素(挂载点),data属性是具体要展示的数据
el : "#app",//使用id选择器将data中的数据渲染在挂载点
data : {
msg:"Hello Vue!"
}
})
/*
MVVM
M--Model---数据
V--View ---页面
VM--ViewMoudle---vue中的对象
*/
</script>
</html>
MVVM框架
M--Model
—-数据
V--View
—-页面
VM--ViewMoudle
—-vue中的对象
基础语法
运算符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue运算符</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="operation">
<p>a = {{a}}</p>
<p>b = {{b}}</p>
<p>加法:{{a + b}}</p>
<p>减法:{{a - b}}</p>
<p>乘法:{{a * b}}</p>
<p>除法:{{a / b}}</p>
<p>取余:{{a % b}}</p>
<p>自增a++:{{a++}}</p>
<p>自减a--:{{a--}}</p>
<p>自增++a:{{++a}}</p>
<p>自减--a:{{--a}}</p>
<p>三元运算符:{{a > b ? a : b}}</p>
<p>字符串操作:</p>
<p>str = {{str}}</p>
<p>字符串长度为:{{str.length}}</p>
<p>字符串拼接---李白:{{str.concat("---李白")}}</p>
<p>字符串剪切8:{{str.substr(8)}}</p>
<h1>{{name}}</h1>
<h2>{{overview}}</h2>
<p>{{json}}</p>
</div>
</body>
<script>
new Vue({
el: "#operation",
data: {
a: 22,
b: 24,
str: "仰天大笑出门去,我辈岂是蓬蒿人。",
name : "我是老马钊",
overview : "我有十年脑血栓",
json : '"name" : "马钊"'
}
})
</script>
</html>
方法
- 方法必须写在methods代码段中
- 方法体中访问数据代码段中声 明的变量,前面加this
- 方法和属性声明方式的差异在于 function(){}
- 方法和属性调用的差异是 {{msg}} {{sayHello()}},名称后加小括号
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue方法</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="fun">
<button onclick="alert('你被发现了')">点点看</button>
<!-- vue的事件,使用v-on调用指定函数 -->
<button v-on:click = "show">你是谁</button>
<p>
调用无参函数{{show()}}
</p>
<p>
调用有参函数{{output("马钊")}}
</p>
<!-- v-for 动态渲染列表或数组中的数据 -->
<p v-for="i in activity">{{i}}</p>
</div>
</body>
<script>
new Vue({
el : "#fun",
data :{
name:"马钊",
age : 22,
address : "淄博",
person:{
name : "余来",
age : 24,
address : "淄博"
},
activity:["吃","喝","睡"],
},
//vue中的函数必须写在methods中
methods : {
show:function(){
console.log("我是" + this.person.name)
},
output:function(name){
console.log(name)
},
geturl:function(){
return this.url
}
}
})
</script>
</html>
获取对象和数组中的信息
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue方法</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="fun">
<!-- 解析对象中的信息 -->
<p>person = {{person}}</p>
<p>person中的name值 = {{person.name}}</p>
<p>person中的age值 = {{person.age}}</p>
<p>person中的address值 = {{person.address}}</p>
<!-- 渲染数组中的信息 -->
<p v-for = "i in activity">{{i}}</p>
<!-- 直接使用数组下标和key来进行数据渲染 -->
<p>{{ json[0].name }}</p>
<!-- 使用 v-for 来进行动态渲染 -->
<ul v-for = "i in json" :key = "i.name">
<li>{{ i.name }}</li>
</ul>
</div>
</body>
<script>
new Vue({
el : "#fun",
data :{
//对象名:对象信息
person:{
name : "余来",
age : 24,
address : "淄博"
},
activity:["吃","喝","睡"],
json : [
{"name" : "马钊" , "age" : "22"},
{"name" : "赵彪" , "age" : "22"},
{"name" : "余来" , "age" : "24"}
]
}
})
</script>
</html>
Vue中三种data值的写法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>三种data值的写法</title>
<script src="./js/vue.js"></script>
</head>
<body>
<p id="p1">{{ msg }}</p>
<p id="p2">{{ msg }}</p>
<p id="p3">{{ msg }}</p>
</body>
<script>
// 1.标准写法
new Vue({
el: "#p1",
data: {
msg: "我是赵彪"
}
})
// 2.定义函数,返回对象
new Vue({
el: "#p2",
data: function () {
return {
msg: "我是马钊"
}
}
})
// 3.定义函数,es6的简写法
new Vue({
el: "#p3",
data() {
return {
msg: "我是余来"
}
}
})
</script>
</html>
高级语法 v-命令
概述:
指令是带有 v- 前缀的特殊属性,以表示它们是 Vue 提供的特殊特性。
指令用于在表达式的值改变时,将某些行为应用到 DOM 上。
常见的Vue指令:v-if v-for v-on v-bind v-model v-cloak等
v-model——双向绑定
v-model,实现双向绑定,修改一方同时修改相同的另一方,达到数据同时更新。
MVVM是将”数据模型双向绑定”的思想作为核心,在View和Model之间没有联系,通过ViewModel进行交互,而且Model和ViewModel之间的交互是双向的,因此View视图的数据的变化会同时修改Model数据源,而Model数据源数据的变化也会立即反应到View视图上。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-model 双向绑定</title>
<script src="./js/vue.js"></script>
</head>
<body>
<!-- v-model 双向绑定 -->
<div id="testModel">
<p>{{ msg }}</p>
<p>{{ msg }}</p>
<p>{{ msg }}</p>
<p>{{ msg }}</p>
<p>{{ msg }}</p>
<input v-model="msg" type="text" />
<input v-model="msg" type="text" />
<input v-model="msg" type="text" />
</div>
</body>
<script>
new Vue({
el: "#testModel",
data: {
msg: "李白乘舟将欲行"
}
})
</script>
</html>
v-cloak—-与css组合可以隐藏标签
闪现:浏览器上有时会显示插值表达式,使用v-cloak属性+css可以隐藏标签
- 在标签中增加指令:v-cloak
- 增加style标签,[v-cloak]属性选择器,设置不展示
display:none
;
<style>
/* 不展示闪现的效果 */
[v-cloak]{
display: none;
}
</style>
</head>
<body>
<!-- 闪现:浏览器上有时会显示插值表达式,使用v-cloak属性+css可以隐藏标签
v-cloak 使用css来隐藏插值表达式 -->
<div id="testModel" v-cloak>
<p>{{ msg }}</p>
<p>{{ msg }}</p>
<p>{{ msg }}</p>
<p>{{ msg }}</p>
<p>{{ msg }}</p>
<!-- v-model 双向绑定 -->
<input v-model="msg" type="text" />
<input v-model="msg" type="text" />
<input v-model="msg" type="text" />
</div>
</body>
v-if—-判断
v-if指令将根据表达式 seen 的值( true 或 false )来决定是否插入元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-if</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="test" v-cloak>
<!-- v-if 不满足条件不会被网页加载 -->
<p v-if="age >= 18">成年人</p>
<p v-if="age<18">未成年人</p>
<!-- v-show 不满足条件也会被网页加载,只是不显示 -->
<p v-show="age < 18">未成年人</p>
<!-- v-if v-else-if v-else 组合判断条件 -->
<p v-if="age < 18">少年</p>
<p v-else-if="age >= 18 && age < 35 ">青年</p>
<p v-else-if="age >= 35 && age < 50 ">青年</p>
<p v-else>老年</p>
</div>
</body>
<script>
new Vue({
el: "#test",
data: {
age: 18,
msg: "李白乘舟将欲行"
}
})
</script>
</html>
v-for—-循环
当 v-if
与 v-for
一起使用时,v-for
具有比 v-if
更高的优先级。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="fun">
<h3>{{name}}的业余活动</h3>
<ol>
<li v-for="arr in activate">
{{arr}}
</li>
</ol>
<ul>
<li v-for="(item, index) in activate" :key="index">
{{index}}:{{item}}
</li>
</ul>
<ul>
<li v-for="(item, index) in json" :key="item.name">
姓名:{{item.name}},
年龄:{{item.age}}
</li>
</ul>
</div>
</body>
<script>
new Vue({
el: "#fun",
data: {
activate: ["吃了喝", "喝了睡", "睡了吃"],
name: "马钊",
json: [{
"name": "马钊",
"age": "22"
},
{
"name": "赵彪",
"age": "22"
},
{
"name": "余来",
"age": "24"
}
]
}
})
</script>
</html>
事件 v-on
@click
为v-on:click
的缩写,单击事件
@dblclick
为v-on:dblclick
的简写,双击事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="fun">
<button v-on:click="out()">点点看</button>
<button v-on:dblclick="out1()">双击试试看</button>
<button @click="out()">点点看</button>
<button @dblclick="out1()">双击试试看</button>
</div>
</body>
<script>
new Vue({
el: "#fun",
data: {
name: "马钊",
json: [{
"name": "马钊",
"age": "22"
},
{
"name": "赵彪",
"age": "22"
},
{
"name": "余来",
"age": "24"
}
],
},
methods: {
out: function () {
console.log(this.json[0].name)
},
out1: function () {
console.log(this.json[1].name)
}
},
})
</script>
</html>
绑定 v-bind
当属性的值是变量而不是字符串时,通过v-bind进行标识,vue会自动处理
- 全称: v-bind:href
- 简称: :href 冒号开头就说明后面跟的是变量
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>测试v-bind</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="test">
<p>
<a v-bind:href="url" target="_blank">{{ uname }}</a>
</p>
<p>
<!-- 无法跳转至正常网址 -->
<a href="url">{{ uname }}</a>
</p>
</div>
</body>
<script>
new Vue({
el: "#test",
data: {
url: "https://www.baidu.com",
uname: "百度一下,你就知道"
}
})
</script>
</html>
vue双向绑定常用属性
@click.prevent
vue点击事件中的一个方法,可以取消标签的默认行为
应用场景:
1.form表单,阻止action提交
2.a标签,阻止href跳转 ```java <!DOCTYPE html>
2. v-model.number
数据转换,将输入内容转换为数值类型
3. v-model.trim
去除多余的空格
4. v-model.lazy
懒加载,失去焦点触发
```java
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>数据双向绑定属性</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<!--
数据转换,将输入内容转换为数值类型
v-model.number
-->
年龄:<input v-model.number="ageTest" type="text" />
<button @click="addNum">加法</button>
<!--
去除多余的空格
v-model.trim
-->
<p>
用户名:<input type="text" v-model.trim="username">
{{username.length}}
</p>
<!--
懒加载,失去焦点触发
v-model.lazy
-->
信息:<input v-model.lazy="msg" type="text" />
{{msg}}
</div>
</body>
<script>
const app = new Vue({
el: "#app",
data: {
ageTest: '',
username: '',
msg: '',
},
methods: {
addNum() {
this.ageTest = this.ageTest + 1
}
},
})
</script>
</html>
Vue生命周期
Vue生命周期共有八个方法:[beforeCreate](https://cn.vuejs.org/v2/api/#beforeCreate)、[created](https://cn.vuejs.org/v2/api/#created)、[beforeMount](https://cn.vuejs.org/v2/api/#beforeMount)、[mounted](https://cn.vuejs.org/v2/api/#mounted)、[beforeUpdate](https://cn.vuejs.org/v2/api/#beforeUpdate)、[updated](https://cn.vuejs.org/v2/api/#updated)、``[beforeDestro](https://cn.vuejs.org/v2/api/#beforeDestroy)、[destroyed](https://cn.vuejs.org/v2/api/#destroyed)
- 生命周期函数的方法名称必须固定
- 生命周期函数是Vue对象特有的函数,应在根目录
当页面渲染成功后,共执行了4个生命周期方法
第一类:Vue对象的创建
1.beforeCreate,创建前,在实例初始化之后,数据观测 (data observer) 和 event/watcher事件配置之前被调用。
2.created,Vue对象创建完成后立即调用
第二类:Vue对象的挂载(创建)
1.beforeMount,在挂载开始之前被调用:相关的 render 函数首次被调用,在服务器端渲染期间不被调用。
2.mounted,挂载完成(渲染完成),用户看到页面数据之后调用该函数
数据更新:
第三类:
1.beforeUpdate,用户修改数据时,确认修改数据后调用该函数。数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。
该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行。
过渡阶段:数据被修改
2.updated,数据被修改完成后调用该函数
销毁阶段:
第四类:销毁函数,Vue默认不会调用,可以用户手动调用
1.beforeDestroy:销毁之前调用,在此时实例仍然完全可用。
2.destroyed:标志Vue对象已经被销毁
组件
概述
组件是将HTML与CSS以及JS进行整合的一个标签,使得引入js与css不在会引起结构混乱,便于开发,并且组件可以复用,简化了代码编写。组件采用树形结构,可以将功能小型化单独维护。
组件分为全局组件和局部组件,全局组件可以在任何div中引入,局部组件只可以在该组件做所在的vue对象绑定的div中使用。
组件体定义:
组件体使用
template
标签进行标记,template
中可以写入与该组件所要实现的功能与信息,id为组件的唯一标识。
<template id="testCom">
<div>
<h1 align="center">{{msg}}</h1>
</div>
</template>
组件定义:
全局组件定义使用
Vue.component(args1,args2)
定义,args1为组件名,args2为组件实体内容,可以写入方法,属性。 局部组件在vue对象中使用components
定义,使用key-value结构进行定义,若key-value相同可以简化只写key。局部组件只可以在该对象挂载点中使用。
//全局组件
Vue.component("addNumCom", {
data() {
return {
//自定义属性
num: 100,
}
},
//页面标记
template: "#numTem",
//方法
methods: {}
})
//局部组件
const app = new Vue({
el: "#app",
components: {
testCom: testCom
}
})
let testCom = {
data() {
return {
msg: "Hello World!",
}
},
template: "#testCom"//与组件体进行绑定
};
组件使用:
组件使用只需要在vue对象挂载的div中使用组件名称即key-value即可。 vue中组件标签名称默认全小写,若需要引入驼峰规则,需要使用“-“连接
<div id="app">
<test-com></test-com>
<test-com></test-com>
<test-com></test-com>
</div>
示例代码:
局部组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>局部组件</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app">
<test-com></test-com>
<test-com></test-com>
<test-com></test-com>
</div>
<template id="testCom">
<div>
<h1 align="center">{{msg}}</h1>
</div>
</template>
</body>
<script>
let testCom = {
data() {
return {
msg: "Hello World!",
}
},
template: "#testCom"
};
const app = new Vue({
el: "#app",
components: {
testCom: testCom
}
})
</script>
</html>
全局组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>全局组件</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
<!--定义模板标签-->
<template id="numTem">
<div>
<h1>Hello World!</h1>
<p>获取组件数据:{{num}}</p>
</div>
</template>
<div id="app">
<!-- vue中组件标签名称默认全小写,若需要引入驼峰规则,需要使用"-"连接 -->
<add-num-com></add-num-com>
<add-num-com></add-num-com>
</div>
</body>
<script>
/*参数
1.组件名
2.组件实体内容
*/
Vue.component("addNumCom", {
//属性
data() {
return {
//自定义属性
num: 100,
}
},
//页面标记
template: "#numTem",
//方法
methods: {}
})
const app = new Vue({
el: "#app"
})
</script>
</html>
路由
路由可以根据用户的请求URL地址,展现特定的组件(页面)信息. (控制用户程序跳转过程)
vue中路由跳转链接使用 router-link
标签,而HTML中链接跳转标签使用a标签。
1.a标签:超链接标签 href:请求跳转的地址 2.router-link标签,解析为a标签 to:解析之后为href
vue路由创建:
创建路由跳转链接
<router-link to="/home">主页</router-link>
<router-link to="/test">测试</router-link>
指定路由填充位
<router-view></router-view>
封装路由对象
let HomeCom = {
template: "#homeTem"
}
let TestCom = {
template: "#testTem"
}
<template id="homeTem">
<div>
<h1>马钊一号</h1>
</div>
</template>
<template id="testTem">
<div>
<h1>马钊二号</h1>
</div>
</template>
定义请求与组件的映射关系
const router = new VueRouter({
//routes:定义请求与组件的映射关系
routes: [{
path: "/home",
component: HomeCom
}, {
path: "/test",
component: TestCom
}]
})
vue对象绑定路由
//实现路由对象绑定
const app = new Vue({
el: "#app",
router
})
详细代码实现:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>路由入门</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app">
<div>
<!--
1.a标签:超链接标签
href:请求跳转的地址
2.router-link标签,解析为a标签
to:解析之后为href
-->
<router-link to="/home">主页</router-link>
<router-link to="/test">测试</router-link>
<!--
指定路由填充位(占位符),需要给组件一个展现的位置,需要提前定义
-->
<router-view>
</router-view>
</div>
</div>
<template id="homeTem">
<div>
<h1>马钊一号</h1>
</div>
</template>
<template id="testTem">
<div>
<h1>马钊二号</h1>
</div>
</template>
</body>
<script>
//封装路由对象
let HomeCom = {
template: "#homeTem"
}
let TestCom = {
template: "#testTem"
}
const router = new VueRouter({
//routes:定义请求与组件的映射关系
routes: [{
path: "/home",
component: HomeCom
}, {
path: "/test",
component: TestCom
}]
})
//实现路由对象绑定
const app = new Vue({
el: "#app",
router
})
</script>
</html>
嵌套路由
嵌套路由需在进行路由与组件绑定时需要使用childen
来声明子级路由
const router = new VueRouter({
//routes:定义请求与组件的映射关系
routes: [{
path: "/tiger",
component: tigerCom,
children: [{
path: "/tiger/tigerSon",
component: tigerSonCom
},
{
path: "/tiger/tigerDau",
component: tigerDauCom
},
]
}]
})
其组件需要在template标签中定义为子级路由
<template id="lionTem">
<div>
<h1>欢迎观赏马钊二号</h1>
<img src="https://gravatar.cat.net/avatar/14da87633624e835fd718e0fa3936be8?s=96&d=mp&r=g">
<p>
<router-link to="/lion/lionSon">赵彪一号</router-link>
<router-link to="/lion/lionDau">赵彪二号</router-link>
<router-view></router-view>
</p>
</div>
</template>
重定向与转发
重定向:重定向是指当浏览器请求一个URL时,服务器返回一个重定向指令,浏览器接受这个指令后,会知道所请求的已发生改变,将会自动使用新的URL再重新发送新请求。
vue中重定向需要使用redirect关键字。
const router = new VueRouter({
//routes:定义请求与组件的映射关系
routes: [{
path: "/",
redirect: "/tiger"
}, {
path: "/tiger",
component: tigerCom,
children: [{
path: "/tiger/tigerSon",
component: tigerSonCom
},
{
path: "/tiger/tigerDau",
component: tigerDauCom
},
]
}]
})
特点:
1.请求多次,对象多个
2.由于是多个请求,所以不可以传递参数
3.浏览器的地址会变化
4.重i定向也是服务器端行为
转发:
转发是指当一个服务器接受请求后无法处理,但知道哪个服务器可以处理此请求,会将请求转发给另一个服务器处理,另一个服务器处理完毕请求后将会返回响应到页面。
特点:
1请求一次同一个对象
2转发时,参数可以携带。
3.转发时,浏览器的地址不变
4.转发是服务器行为
路由导航守卫
路由导航守卫用于当用户访问没有权限的页面时进行拦截,在访问有权限的页面时进行放行的控制。
vue中路由导航守卫使用beforeEach((to,from,next) => {})
来定义,to表示路由跳转网址,from表示请求的路由来处,next表示路由被重定向或者放行。
/*
路由导航守卫
to:路由跳转网址
from:路由从哪来
next:函数,可以重定向或者放行
next()表示放行
next('路由地址'),表示要重定向指定网址
*/
router.beforeEach((to, from, next) => {
if (to.path === '/login') {
return next();
}
let token = window.sessionStorage.getItem('token');
// if (token !== null && token.length > 0) 等同于 if (token) 表示token不为null为true反之为false
if (token) {
return next();
} else {
alert("请登陆后访问该页面。")
return next('/login');
}
})
过滤器
定义语法
动作函数的参数为”|”号左侧的数据
过滤器必须有返回值。
js定义语法:
Vue.filter("过滤器名称",过滤器动作函数(参数){
return 返回值.
})
ui使用过滤器语法:
<template slot-scope="scope">
{{scope.row.price | priceFormat}}
</template>