学习地址:https://www.bilibili.com/video/BV1YE411A746
这是我在B站学习写的一些笔记,可能会有些乱,凑合看吧。
Vue
MVVM
Vue技术是MVVM开发模式的实现者
MVC——M(Model)、V(View)、C(Controller)
MVVM——M(model)、V(View)、VM (ViewModel),连接视图和数据的中间件
其他MVVM实现者:
- AngularJS
- ReactJS
- 微信小程序
快速上手
https://cn.vuejs.org/v2/guide/
安装
【概念:CDN:内容分发网络,这是一种加速策略,能够自动从离自己最近的服务器上快速获取所需要的资源】
尝试 Vue.js 最简单的方法是使用 Hello World 例子。你可以在浏览器新标签页中打开它,跟着例子学习一些基础用法。或者你也可以创建一个 .html
文件,然后通过如下方式引入 Vue:
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
或者:
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
安装教程给出了更多安装 Vue 的方式。请注意我们不推荐新手直接使用 vue-cli
,尤其是在你还不熟悉基于 Node.js 的构建工具时。
如果你喜欢交互式的东西,你也可以查阅这个 Scrimba 上的系列教程,它揉合了录屏和代码试验田,并允许你随时暂停和播放。
提示:也可以通过百度 cdn vue获取各种版本的地址:https://cdn.baomitu.com/vue
Hello World
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue</title>
<!-- <link rel="shortcut icon" href="" type="">-->
</head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js" type="text/javascript"></script>
<body>
<div id="app">
<span>
{{ title }}
</span>
<input type="text" v-model="title">
</div>
</body>
</html>
<script>
const app = new Vue({
el: "#app",
data: {
title: 'hello world'
}
});
</script>
运行效果展示:
当在输入框中输入内容时,左边的span标签内容也跟着改变
这就是MVVM架构中VM的妙处!(ViewModel能够观察到数据的变化,并对视图对应的内容进行更新)
总结:
- html中要有一个div,id为app(当然其他也行)
- js中要有一个Vue对象
讲解
<!DOCTYPE html>
<html lang="ch-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="shortcut icon" href="" type="">
</head>
<body>
<div id="app">
欢迎你,{{age}}岁的{{name}}! <!--{{ }}指的是插值表达式-->
</div>
</body>
</html>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
el:"#app", //el指的是element,里面放元素的解析器,#app就代表id值为app的元素
data:{ //html中通过差值表达式获取data中存放的数据
age:18, //以后,这里的数据都是通过发送ajax请求来获得
name:"小明"
}
});
</script>
插值表达式
插值表达式是用在html中被绑定的元素中的。目的是通过差值表达式来获取Vue对象的属性和方法。
属性通过data提供,方法通过methods提供。
例如运行下面的代码,会直接弹出一个框。
<!DOCTYPE html>
<html lang="ch-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="shortcut icon" href="" type="">
</head>
<body>
<div id="app">
{{sayHi()}} <!--可以要括号,可以不要括号-->
</div>
</body>
</html>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
el:"#app",
methods:{
sayHi:function (){
alert("Hello World!");
}
}
});
</script>
除此之外,还可以这么使用
<div id="app">
{{sayHi()}}<br>
{{[1,2,3,4,5][1]}}<br> <!--取数组元素-->
{{{name:"小明",age:18}.name}}<br> <!--取json元素-->
</div>
显示在页面中的内容是
2
小明
Vue中的关键字
这些关键字都是作为html页面中标签中的属性来使用
v-model
【MVVM双向数据绑定】将标签的value值与vue实例中的data
属性进行绑定。
这里的代码举例和Hello World 中的一样。
v-on
【事件绑定】通过配合具体的事件名,来绑定vue中定义的函数。
<input type="text" v-on:input="changeTitle" />
v-on
叫绑定事件,事件是input
,响应行为是changeTitle
。也就是说,当input元素发生输入事件时,就会调用vue里定义的changeTitle
方法
例子:
<!DOCTYPE html>
<html lang="ch-CN" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="shortcut icon" href="" type="">
</head>
<body>
<div id="app">
<button v-on:click="show()">Hello World</button>
</div>
</body>
</html>
<script src="vue.js"></script>
<script>
new Vue({
el:"#app",
methods:{
show:function (){
console.log("Hello World");
}
}
});
</script>
补充:
-
methods里面放的函数,可以加一个
event
参数,event就代表当前事件,然后可以用event.target
来获取当前事件的对象,然后再通过event.target.value
来获取当前事件的对象的value属性。用法举例:每改变输入框中的内容都将它打印到控制台
<!DOCTYPE html> <html lang="ch-CN" xmlns:v-on="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="shortcut icon" href="" type=""> </head> <body> <div id="app"> <input type="text" v-on:input="show"> <!--踩坑:不能加(),要不然无法传参--> </div> </body> </html> <script src="vue.js"></script> <script> new Vue({ el:"#app", methods:{ show:function (ev){ //不一定要是event,随便一个名字都行 console.log(ev.target.value); } } }); </script>
-
this的用法,主要在methods里面的函数,用
this.属性
可以直接访问和修改data里的数据。//下面2个方法都可以直接获取data里的属性 this.$data.属性名 this.属性名 //下面2种方法可以直接调用methods里的方法 this.方法名(); this.$options.methods.方法名();
-
v-on
还可以简写成@
,比如v-on:input
可以写成@input
。
v-bind
【属性绑定】内容才可以用差值表达式,属性不可以,比如下面这行是没有用的。
<a href="{{link}}"></a>
注意:差值表达式不能写在html的标签中,不能作为属性的一部分。
正确做法:v-bind:标签属性="值"
<a v-bind:href="link">链接</a>
扩展:v-bind可以简写成":"
<a :href="link">链接</a>
v-once
加上这个标签之后,里面的差值表达式只获取一次数据。之后的数据变化不影响此插值表达式的值。
v-html和v-text
v-html
会将vue中的属性的值作为html的元素来使用
v-text
会将vue中属性的值只作为纯文本来使用
例子:
<!DOCTYPE html>
<html lang="ch-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="shortcut icon" href="" type="">
</head>
<body>
<div id="app">
<span v-html="val"></span> <br>
<span v-text="val"></span>
</div>
</body>
</html>
<script src="vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
val:"<button>按钮</button>"
}
});
</script>
效果:
分支语句
v-if
v-else-if
v-else
示例代码如下:
<!DOCTYPE html>
<html lang="ch-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="shortcut icon" href="" type="">
</head>
<body>
<div id="app">
<div>
<input type="checkbox" id="temp1" v-model="temp1"> <label for="temp1">temp1</label>
<input type="checkbox" id="temp2" v-model="temp2"> <label for="temp2">temp2</label>
</div>
<div>
<div v-if="temp1">看到v-if的内容</div> <!--temp1=true时显示-->
<div v-else-if="temp2">看到v-else-if的内容</div> <!--当temp1=false且temp2=true时显示-->
<div v-else="">看到v-else的内容</div> <!--当temp1=false且temp2=false时显示-->
</div>
</div>
</body>
</html>
<script src="../vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
temp1:true,
temp2:false
}
});
</script>
v-show
实现的效果跟v-if
是一样的,都是当该属性的值是true
时,显示该标签的内容,为false
时不显示。
区别是,v-show
隐藏内容的原理是直接修改标签的css样式:display:none
,而v-if
则是直接删除掉那个标签,所以,在效率上,v-show
更好一点。
循环语句v-for
遍历普通的数组
举例:
<!DOCTYPE html>
<html lang="ch-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="shortcut icon" href="" type="">
</head>
<body>
<div id="app">
<ul>
<li v-for="v in nums">{{v}}</li>
</ul>
</div>
</body>
</html>
<script src="../vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
nums:[1,2,3,4,5,6]
}
});
</script>
显示效果:
-
<li v-for="v in nums">{{v}}</li>
,表示遍历数组nums
,取得数组里的每一个元素v
-
<li v-for="(v,i) in nums">{{v}}-->{{i}}</li>
,遍历出得到的v
是数组的每一个元素value
,而i
则是下标index
-
第二条,
(v,i)
得到的v
是值i
是下标是他自己规定的,第一个参数是值,第二个参数是下标,如果你就是想第一个参数是下标也是可以的,直接在语句后面指定:<li v-for="(i,v) in nums":key="i">{{i}}-->{{v}}</li>
遍历对象
举例子:
<!DOCTYPE html>
<html lang="ch-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="shortcut icon" href="" type="">
</head>
<body>
<div id="app">
<ul>
<li v-for="v in student">{{v}}</li>
</ul>
</div>
</body>
</html>
<script src="../vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
student:{
name:"张三",
age:18
}
}
});
</script>
<li v-for="v in student">{{v}}</li>
输出的是student
里的每一个value
<li v-for="(v,k) in student">{{v}}--{{k}}</li>
输出的时候,v
是value
,k
是key
<li v-for="(v,k,i) in student">{{v}}--{{k}}--{{i}}</li>
,输出的时候,v
是value
,k
是key
,i
是index
遍历对象数组
看例子:
<!DOCTYPE html>
<html lang="ch-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="shortcut icon" href="" type="">
</head>
<body>
<div id="app">
<ul>
<li v-for="student in students">
<div v-for="(v,k) in student">{{k}}--{{v}}</div>
</li>
</ul>
</div>
</body>
</html>
<script src="../vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
students:[{
name:"张三",
age:18
},{
name:"李四",
age:19
},{
name:"王五",
age:20
}
]
}
});
</script>
事件
范例1
点击按钮,数字加1
<!DOCTYPE html>
<html lang="ch-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="shortcut icon" href="" type="">
</head>
<body>
<div id="app">
<div>
当前数字:{{count}}
</div>
<button type="button" @click="increase()">增加</button>
</div>
</body>
</html>
<script src="vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
count:0
},
methods:{
increase:function (){
this.count+=1;
}
}
});
</script>
范例2
鼠标移动到那里,显示鼠标的X坐标和Y坐标
<!DOCTYPE html>
<html lang="ch-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="shortcut icon" href="" type="">
</head>
<body>
<div id="app">
<div style="width: 400px;height: 300px;background-color: blanchedalmond" @mousemove="move"></div>
X:{{px}}  Y:{{py}}
</div>
</body>
</html>
<script src="vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
px:0,
py:0
},
methods:{
move:function (event) {
this.px = event.clientX;
this.py = event.clientY;
}
}
});
</script>
参数绑定
范例1那里,可以传入一个步长,代表每点击一次都增加对应的数字。
<div id="app">
<div>
当前数字:{{count}}
</div>
<button type="button" @click="increase(2)">增加</button>
</div>
new Vue({
el:"#app",
data:{
count:0
},
methods:{
increase:function (step){
this.count+=step;
}
}
});
★ 如果想传入事件对象,可以在括号里面输入$event
例如范例2:
<div style="width: 400px;height: 300px;background-color: blanchedalmond" @mousemove="move($event)"></div>
停止鼠标事件
法一:在函数里加一行代码
<span v-on:mousemove="dummy">停止鼠标事件</span>
dummy:function (ev) {
ev.stopPropagation();
}
法二:直接在标签的参数里面加一个属性(这就叫事件修饰符)
<span v-on:mousemove.stop>停止鼠标事件</span>
事件修饰符
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>
按键修饰符
<input v-on:keyup="submit"> <!--这一行表示只要按下任意一个键,都会执行submit函数-->
<!-- 只有在按下回车键的时候才会执行submit -->
<input v-on:keyup.enter="submit">
vue改变内容
常规:使用差值表达式
比如上面的范例1,可以加上{{count>10?"大于10":"不大于10"}}
来显示“大于10”/“不大于10”,当count大于10时,将会显示"大于10"
计算属性:computed
例子:
<!DOCTYPE html>
<html lang="ch-CN" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="shortcut icon" href="" type="">
</head>
<body>
<div id="app">
{{getDate()}}<br>
{{getDate1}}
</div>
</body>
</html>
<script src="vue.js"></script>
<script>
new Vue({
el:"#app",
methods:{
getDate:function (){
return new Date();
}
},
computed:{
getDate1:function (){
return new Date();
}
}
});
</script>
首先,应该明确,getDate
是一个函数,而getDate1
只是一个属性而已!
所以差值表达式那里{{getDate1}}
不能加括号!!
可以理解为:每一次getDate()
都会重新执行那个函数,然后取返回值,而getDate1
只是第一次会执行那个函数取返回值,之后再执行的话就直接取缓存里的数据了!
使用计算属性可以提高vue的效率(一些常用的函数,可以缓存起来,下次调用时直接获取缓存里的返回值)!
监控属性:watch
通过watch里给data里的属性绑定一个函数,当属性的值发生变化时,该函数就会调用。
例如:当输入框的内容发生改变时,控制台输出一句话。
<div id="app">
{{title}}
<div>
<input v-model="title">
</div>
</div>
new Vue({
el:"#app",
data:{
title:"hello"
},
watch:{
title:function (){ //这里的key值需要和data里的key一样
console.log("改变了");
}
}
});
◆扩展:watch里放的函数可以绑定两个参数newValue
和 oldValue
title:function (newValue,oldValue){
console.log(oldValue + "-->" + newValue);
}
vue改变样式
通过修改class
属性
class
的动态绑定
最常规的方法就是通过改变class属性来改变样式。所以我们通过v-bind:class
属性来设置class。
奇怪的知识:v-bind:class
的值可以是json格式,需要key
值为class值
,value
为boolean
值的属性。
如v-bind:class="{red:true,green:false}"
就表示这个元素的class
属性包含red
而不包含green
通过前面数据绑定的方式,可以在data
里加一个temp
,然后标签内属性设置为v-bind:class="{red:temp}"
上代码:
<!DOCTYPE html>
<html lang="ch-CN" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="shortcut icon" href="" type="">
<style>
.mydiv {
margin: 20px;
width: 400px;
height: 300px;
background-color: darkgrey;
}
.red {
background-color: red;
}
.green {
background-color: green;
}
.blue {
background-color: blue;
}
</style>
</head>
<body>
<div id="app">
<div class="mydiv" v-bind:class="{red:r,green:g,blue:b}"></div>
<button @click="cr()">打开/关闭red</button>
<button @click="cg()">打开/关闭green</button>
<button @click="cb()">打开/关闭blue</button>
</div>
</body>
</html>
<script src="../vue.js"></script>
<script>
new Vue({
el: "#app",
data: {
r: false,
g: false,
b: false
},
methods: {
cr: function () {
this.r = !this.r;
}, cg: function () {
this.g = !this.g;
}, cb: function () {
this.b = !this.b;
}
}
});
</script>
使用computed
优化
前面说了,computed
里面其实都是属性,所以computed
可以直接返回一个json,然后被v-bind:class
里直接引用。
例子:(基于上面的代码修改)
<div class="mydiv" v-bind:class="myclass"></div>
computed:{
myclass:function (){
return {
red:this.r,
green:this.g,
blue:this.b
}
}
}
通过双向数据绑定
这就更有意思了,可以直接在一个input框里通过v-model
绑定一个color属性,然后再给div的v-bind:class
绑定那个color。
最终的效果是:输入框输入red时,div变红色,输入green时绿色
<!DOCTYPE html>
<html lang="ch-CN" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="shortcut icon" href="" type="">
<style>
.mydiv {
margin: 20px;
width: 400px;
height: 300px;
background-color: darkgrey;
}
.red {
background-color: red;
}
.green {
background-color: green;
}
.blue {
background-color: blue;
}
</style>
</head>
<body>
<div id="app">
<div class="mydiv" v-bind:class="color"></div>
<input type="text" v-model="color">
</div>
</body>
</html>
<script src="../vue.js"></script>
<script>
new Vue({
el: "#app",
data: {
color:""
},
});
</script>
v-bind:class
的一些细节
- 值可以是json格式的数据(正如上面演示的那样),其中
key
为要使用的class,value
为boolean
型数据,当为true时时使用这个class
- 值也可以是数组类型,如
<div class="mydiv" v-bind:class="[color,mywidth]"></div>
表示class
同时属性同时绑定data
里的color
和width
,注意:如果要绑定多个data
里的数据,不能写多个v-bind:class
,不起作用的。
不能这么写:<div class="mydiv" v-bind:class="color" v-bind:class="mywidth"></div>
通过修改style
属性
修改html的样式,除了外部引入(直接在外部定义了css的样式然后通过修改class
属性来改变样式),还有内嵌引入,就是直接在标签里面使用style
属性!
<!DOCTYPE html>
<html lang="ch-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="shortcut icon" href="" type="">
</head>
<body>
<div id="app">
<div style="background-color: aqua;width: 400px;height: 300px">普通的style</div>
<div v-bind:style="{backgroundColor:color,width:width,height:height}">Vue的style</div>
</div>
</body>
</html>
<script src="../vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
color:"gray",
width:"400px",
height:"300px"
}
});
</script>
注意:
-
v-bind:style
是json格式的键值对,其中value
值是绑定Vue中data
里的数据的 -
key
中所有的由-
拼接成的单词都改成驼峰式命名,比如style
中的background-color
,Vue中就写成backgroundColor
,这一点和我们DOM中的操作是一样的document.getElementById("aa").style.backgroundColor = "blue";
-
也可以使用
computed
属性,但computed
返回值必须要是json
-
可以使用数组将多个
json
或者computed
合并在一起
虚拟DOM和diff算法
Vue高效的核心。
Vue实例
var v1 = new Vue();
指的就是Vue的实例。
实例属性
属性是指在data
和computed
里定义的,而方法是在method
里定义的。实例属性是指Vue对象自己的属性,比如之前接触的el
、data
、computed
、watch
… 这些不能直接通过Vue对象.的方式获得的。***如果要访问,必须要加上$
***,如v1.$data
v1.$data.title
可以写成v1.title
$refs
给html的标签加上ref
属性,那么在Vue中可以直接根据ref
属性的值来获取这个标签,和id
的用法有点像。
<div id="app">
<div ref="div1">红红火火恍恍惚惚</div>
<button @click="change()">点我</button>
</div>
new Vue({
el:"#app",
methods:{
change:function (){
this.$refs.div1.innerHTML = "哈哈哈哈哈哈哈哈哈哈或或或或或或或或或或或或或或或或或";
}
}
});
总结:可以直接通过vue实例.$refs.标签的ref属性值
来操作这个标签体。
和id
的区别:当有多个标签的id
值相同时不会报错,而ref
会报错。
$mount
实现Vue对象与页面元素的动态绑定,之前都是通过el
。 官方文档
<div id="app">
</div>
<button onclick="bc()">点我</button>
var v1 = new Vue({
template:"<h1>Hello World</h1>"
});
function bc(){
v1.$mount("#app");
}
实现效果:点击按钮就显示Hello World,其实template
是干嘛用的我也不知道(在下面的组件那里可能会深有体会)
组件
Vue的一大特性:组件化,就是可以将一个Vue对象注册成一个组件,反复使用!
要想实现组件化,必须要注册组件,注册组件有2种方式:全局注册、本地注册
全局注册
注册组件时,使用Vue的静态方法:Vue.component("组件名称", 对象)
使用组件时,直接使用标签即可:<组件名称></组件名称>
,但是,必须注意:必须要在已经被Vue绑定的标签里面才能使用组件,要不然不起作用!
例子:
<div id="app">
<model1></model1>
</div>
Vue.component("model1",{
template: "<h1>Hello World</h1>"
});
new Vue({
el:"#app"
});
进阶版:既然组件也是一个Vue的实例,所以也可以加上data
属性和methods
属性。
Vue.component("model1",{
template: "<div><button @click='cbtn()'>点我</button></div>",
methods:{
cbtn:function (){
alert("哈哈哈哈哈哈哈");
}
}
});
在template属性里面用插值表达式来引用data里的内容有点不行,会报错
Vue.component("model1",{
template: "<div>{{title}}</div>",
data:{
title:"哈哈哈哈哈哈哈"
}
});
解决方案 是:
Vue.component("model1",{
template: "<div>{{title}}</div>",
data:function (){
return {
title:"哈哈哈哈哈哈哈"
}
}
});
这里需要稍微注意一下!!!!!!!!!
本地(局部)注册
就是直接加一个实例属性component
而已,和全局的区别,懂的都懂!
new Vue({
el: "#app",
components: {
model1: {
template: "<div><div>{{title}}</div><button @click='func()'>点我</button></div>",
data: function () {
return {
title: "哈哈哈哈哈哈哈"
}
},
methods: {
func: function () {
alert("红红火火恍恍惚惚");
}
}
}
}
});
Vue作为组件使用的注意事项
-
data
的写法:平时创建Vue实例时的data
属性直接是一个json
对象,而作为组件时,data
属性必须是一个函数,返回值才是json
对象。 -
template
是将内容展现在页面上的一个键,值是一个字符串。注意:template
里有且只有一个根标签,不能没有或者多个根标签并列!,就比如你不可以这样:<div>{{title}}</div><button @click='func()'>点我</button>
但是可以这样(加上了根标签)
<div><div>{{title}}</div><button @click='func()'>点我</button></div>
优化
注册组件的时候甚至可以这样,先把json
定义在外面,然后在里面再引用。
var model1 = {
template: "<div><div>{{title}}</div><button @click='func()'>点我</button></div>",
data: function () {
return {
title: "哈哈哈哈哈哈哈"
}
},
methods: {
func: function () {
alert("红红火火恍恍惚惚");
}
}
};
new Vue({
el: "#app",
components: {
model1: model1
}
});
生命周期
![Vue 实例生命周期](https://cn.vuejs.org/images/lifecycle.png)
new Vue({
el:"#app",
beforeCreate(){
console.log("beforeCreate")
},
created(){
console.log("created")
},
beforeMount(){
console.log("beforeMount")
},
mounted(){
console.log("mounted")
},
beforeUpdate(){
console.log("beforeUpdate")
},
updated(){
console.log("updated")
},
beforeDestroy(){
console.log("beforeDestory")
},
destroyed(){
console.log("destory")
}
});
也可以是这种形式
beforeCreate:function (){
console.log("beforeCreate")
}
vue-cli
vue-cli骨架
CLI(command line interfaces )
命令行接口。在进行Vue项目开发时,可以选择不同的Vue模板进行项目的搭建,比如simple
、webpack-simple
、webpack
、browserify/browserify-simple
等;vue-cli
是官方提供的一个脚手架(预先定义好的目录结构及基础代码,咱们在创建 Maven
项目时可以选择创建一个骨架项目,这个骨架项目就是脚手架),用于快速生成一个vue
的项目模板。
要想使用vue-cli
,得先安装node.js
node.js是一个快要让前端运行在node.js提供的服务器上的一个工具,换句话说,就是提供了一个服务器。
node.js
下载
官网:https://nodejs.org/zh-cn/download/
安装无脑下一步。
检查是否安装成功:cmd输入node -v
使用node.js安装vue-cli
npm install vue-cli -g
参数解释:
npm
:是指使用node.js的命令install
:安装vue-cli
:要安装的工具-g
:全局
如果安装比较慢,可以使用淘宝镜像
$ npm install -g cnpm --registry=https://registry.npm.taobao.org
然后安装
cnpm install vue-cli -g # 把npm替换成cnpm
使用vue-list下载项目骨架来搭建我们的项目
使用以下命令可以列出当前官方提供的骨架,然后就可以利用官方提供的这些骨架来创建我们的项目
vue list
搭建项目:
vue init webpack-simple myvuedemo
其中webpack-simple
是要使用的模板名称,myvuedemo
是要创建的项目名称,完成后,会自动在当前文件夹创建一个文件夹,名称为“项目名称”
项目生成后,输入cd 项目名称
,进入项目文件夹
然后npm install
,安装项目所需的依赖
最后npm run dev
,以开发的模式启动项目。
启动后就能在浏览器中输入http://localhost:8080/ 即可访问。
项目完成后,运行npm run build
来发布项目
webpack-simple
项目内结构
-
index.html
无论前端页面有多复杂,
index.html
都只有11行<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>myvuedemo</title> </head> <body> <div id="app"></div> <script src="/dist/build.js"></script> </body> </html>
实际的内容已经被打包进/dist/build.js里面
-
vue.js
整个vue项目的入口函数import Vue from 'vue' import App from './App.vue' //导入了App.vue组件 new Vue({ el: '#app', //让当前vue对象绑定页面上id是app的那个div render: h => h(App) //让App.vue的内容出现在该div中 })
-
App.vue
这种以.vue
为扩展名的文件,实际上就是一个Vue对象。在这里这种组件也称为Vue组件。
.vue文件的组成结构
idea里可以安装vue.js插件来添加对.vue文件的支持
一个Vue文件由<template>
,<script>
,<style>
组成。
注:<style>
可以加上scoped
属性,表示样式只作用在当前组件,否则,会作用在整个页面!
vue组件的全局注册
我在src目录下创建一个components/myvue.vue文件
<template>
<div>
我的组件
</div>
</template>
<style>
</style>
<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
})
</script>
现在我要全局注册这个组件,就要修改main.js
import myvue from './components/myvue.vue'
Vue.component("myvue",myvue); //和之前学的一样
本地注册
在组件的内部注册,比如我只在App.vue里注册一个组件
<script>
import myvue from "./components/myvue.vue";//导入
export default {
name: 'app',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
},
components:{ //和上面学过的一样
"mmvue":myvue
}
}
</script>
组件之间的参数传递
父传子
在组件内部的Vue对象里定义一个props
参数,值为一个数组对象,数组的每一个元素就是属性名。然后在使用这个组件的时候,在标签里加上这个属性就可以了!
比如,myvue.vue里,
<template>
<div>
{{myTitle}} <!--插值表达式使用myTitle属性-->
</div>
</template>
<style>
</style>
<script>
import Vue from 'vue'
export default Vue.extend({
props:["myTitle"] // 这里表示定义一个myTitle的属性
})
</script>
在App.vue里,这样子传入参数
<template>
<div id="app">
<myvue myTitle="你好"></myvue>
</div>
</template>
总结:Vue 的插值表达式获取vue对象的属性,可以通过3种方式:
- data
- computed
- props
props的写法:
-
数组:
和上面一样,props:["args1",args2]"
就表示接受2个参数 -
json对象,稍微复杂些:
props:{ myTitle:{ type:String, required:true, default:"hello" } }
子传父
原理就是父组件传入一个函数来作为参数,然后子组件调用这个函数,就可以传数据了!
<!--子组件-->
<template>
<div>
<button v-on:click="func(msg)">点我</button>
</div>
</template>
<style>
</style>
<script>
import Vue from 'vue'
export default Vue.extend({
props:{
func:{
type:Function,
required:true
}
},
data:function(){
return{
msg:"hello world!"
}
}
})
</script>
<!--App.vue-->
<template>
<div id="app">
{{msg}}
<myvue1 :func="func"></myvue1>
</div>
</template>
<script>
export default {
name: 'app',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
},methods:{
func:function(data){
this.msg = data;
}
}
}
</script>
<style lang="scss">
</style>
发送ajax请求
安装Axios模块
npm install --save axios vue-axios
使用Axios
在main.js
中加上
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios) //顺序不颠倒
发送ajax
this.axios({
method:'get',
url:'http://bit.ly/2mTM3nY',
data:{}
})
.then(function (response) {
console.log(response.data)
});
服务器端(springmvc)解决跨域问题
发送请求会发生下面的错误(不允许跨服务器访问):
在springmvc.xml中加入以下代码
<mvc:cors>
<mvc:mapping path="/**"
allowed-origins="*"
allowed-methods="POST, GET, OPTIONS, DELETE, PUT,PATCH"
allowed-headers="Content-Type, Access-Control-Allow-Headers, Authorization, X-RequestedWith"
allow-credentials="true" />
</mvc:cors>
其中,allowed-origins指的是允许的访问源的域名,"*"表示任何人都可以访问,也可以指明具体的域名 。
跨域问题解释:
跨域,指的是浏览器不能执行其他网站的脚本。他是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。所谓同源,是指:域名,协议,端口均相同!
比如:
http://www.qf.com/
->http://admin.qf.com/
http://www.qf.com/
->http://www.qf.com:8080/
http://www.qf.com/
->https://www.qf.com/
均是跨域!跨域的解决方案:CORS
路由(组件之间的跳转)
路由器:在数据通信时,帮你选择通信的路线
Vue中的路由,能够帮助我们在一个Vue组件中实现其他组件的相互切换。也就是说,可以通过路由模块,再创建路由表,将指定的组件显示在路由视图<router-view>
中。
安装路由模块
npm install vue-router -s
设计路由界面
在src下创建components文件夹,文件夹内创建user, Home组件
-
user.vue
<template> <div>user</div> </template>
-
Home.vue
<template> <div>Home</div> </template>
创建静态路由表
在src目录下创建routes.js
import Home from './components/Home.vue'
import User from './components/user.vue'
export const routes = [
{path:'/',component:Home},
{path:'/user',component:User}
]
引入路由模块并使用
在main.js中引入路由模块(当然这部分可以放在vue组件的<script>
里,类似组件的本地注册)
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router' //1.引入路由模块
import {routes} from './routes.js' //2.引入静态路由表,地址是第一步创建的那个文件的路径
Vue.use(VueRouter); //3.使用路由模块
//4.创建一个VueRouter模块的实例
const router = new VueRouter({
routes:routes
});
new Vue({
el: '#app',
router,//5.把router实例放入到vue实例中
render: h => h(App)
})
体验
App.vue:(不一定是App.vue,可以是一个组件,然后在App.vue里面引入就好了!)
<template>
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-8">
<h1>Routing</h1>
<router-view></router-view> <!--记得要加上这一行,要不然不显示-->
</div>
</div>
</div>
</template>
改变url,发现中的内容发生改变
- http://localhost:8080/#/ 显示home
- http://localhost:8080/#/user 显示user
向router实例中添加mode属性:
- 值"hash": url带# 适用于调试模式
- 值"history" url不带#
注意:一定要加上<router-view></router-view>
,要不然显示不了!
链接路由的实现
<template>
<div>
<span><router-link to="/">Home</router-link></span>
<span><router-link to="/user">user</router-link></span>
<router-view></router-view>
</div>
</template>
实现的是导航条的效果:当点击Home时,显示home.vue的内容,当点击user时,显示user.vue的内容。
另外也可以通过JS的方式实现跳转:
this.$router.push("/user")
路由之间的参数传递
设参
在routes.js中,修改路径表
{path:'/user/:id',component:User}
在路径后面加上:id
,表示接受一个id
参数。
传参
就是在地址后面加上/
再接上参数而已。
<span><router-link to="/user/10086">user</router-link></span>
接参
this.$route.params.参数名称
data:function(){
return {
id:this.$route.params.id
}
}
嵌套路由(子路由)
在路由显示的组件内部,又嵌套着路由,称为子路由。
嵌套路由的实现:
-
配置路由表,要称为哪个路由的子路由,就在哪个路由就上
children
export const routes = [ { path:'/home', component:Home, children:[{ path:"/productList", //使用嵌套路由,直接地址是/productList,而不是/path/productList component:productList },{ path:"/productInfo", component:productInfo }] }, {path:'/user',component:User} ]
静态资源打包问题
webpack-Vue 工程项目
创建工程
-
创建工程
# 使用 webpack 打包工具初始化一个名为 hello-vue 的工程 vue init webpack hello-vue
-
安装依赖
# 我们需要安装 vue-router 、 element-ui 、 sass-loader 和 node-sass 四个插件 # 进入工程目录 cd hello-vue # 安装 vue-router npm install vue-router --save-dev # 安装 element-ui npm i element-ui -S # 安装 SASS 加载器 npm install sass-loader node-sass --save-dev
安装完后安装依赖:
npm install
-
启动
npm run dev
附:npm命令
npm install moduleName # 安装模块到项目目录下
npm install -g moduleName # -g 的意思是将模块安装到全局,具体安装到磁盘哪个位置,要看 npm configprefix 的位置
npm install -save moduleName #--save 的意思是将模块安装到项目目录下,并在 package 文件的dependencies节点写入依赖, -S 为该命令的缩写
npm install -save-dev moduleName #--save-dev 的意思是将模块安装到项目目录下,并在 package 文件的devDependencies节点写入依赖,-D 为该命令的缩写
引入element-ui
main.js
// 导入 ElementUI
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
// 安装 ElementUI
Vue.use(ElementUI);
有关他的使用,详情见官网