目录
一、Vue.js 简介
什么是Vue
什么是 Vue?
首先让我们考虑这个需求: 我们要把一个 json对象的数据,显示到一个元素上去。
如果不使用 Vue, 那么就会用到 JS 或者 JQuery,通过操作 HTML DOM 的方式,把数据显示上去。如果使用Vue, 那么仅仅需要提供数据,以及数据要绑定到的元素的id,就行了,不需要显式地操作HTML DOM。
以下就用代码来表示这两种方式,通过比较,就知道Vue 是做什么的了。
使用js的方式
首先需要准备一个视图,就是div元素,然后创建一个json数据,对json 不了解的同学,请学习json教程。接着通过js 获取 div 对应的 HTML DOM,最后将json数据赋给HTML DOM,对html dom 不了解的同学,请学习 HTML DOM,进而使div里显示了json对象的数据。
<div id="div1">
</div>
<script>
//准备数据
var one = {"name":"hh豪","age":18};
//获取 html dom
var div1 = document.getElementById("div1");
//显示数据
div1.innerHTML= one.name;
</script>
js的方式没问题,但html dom只是手段,我们想要的就是数据,而vue.js就是来解决这个问题的。
Vue的方式
首先要导入vue.js要用到的库,可以去官网下载
<script src="xxx"></script>//导入
<div id="div1">
{{one.name}}//用取值符{{}}来渲染数据
</div>
<script>
//准备数据
var one = {"name":"hh豪","age":18};
//通过vue.js 把数据和对应的视图关联起来
new Vue({
el: '#div1',
data: {
message: one
}
})
</script>
以下的内容我就将导入步骤省略了
二、Vue.js监听事件
v-on 监听事件
<div id="div1">
<div>点击了 {{clickNumber}}次</div>
<button v-on:click="count">点击</button>
</div>
<script>
new Vue({
el: '#div1',
data: {
clickNumber:0
},
methods:{
count: function(){
this.clickNumber++;
}
}
})
</script>
通过v-on:click来监听button并绑定count方法,用通俗一点的话来讲就是你每点击一下button按钮,就会执行一次count方法,这就是所谓的触发器,这个是及其常用的,你可以用它来首先许多功能。
v-on 也可以缩写为 @
<button @click="count">点击</button>
vue.js 还提供了各种事件修饰符
.stop .prevent .capture .self .once
下面一一讲解
为了方便解释,我们先来写一个冒泡
<div id="content">
<div id="grandFather" v-on:click="doc">
grandFather
<div id="father" v-on:click="doc">
father
<div id="me" v-on:click="doc">
me
<div id="son" v-on:click="doc">
son
</div>
</div>
</div>
</div>
</div>
<script>
var content = new Vue({
el: "#content",
data: {
id: ''
},
methods: {
doc: function () {
this.id= event.currentTarget.id;
alert(this.id)
}
}
})
</script>
<style type="text/css">
* {
margin: 0 auto;
text-align:center;
line-height: 40px;
}
div {
width: 100px;
cursor:pointer;
}
#grandFather {
background: green;
}
#father {
background: blue;
}
#me {
background: red;
}#son {
background: gray;
}
</style>
效果
该组件的效果就是当你点击了任一个模块,会依次向上弹窗
实现思路
先创建四个层层包含的div,然后都绑定方法doc,再创建个Vue绑定整个div:content,再定义doc方法将div的id弹出来
下面我们就在该组件上来讲解事件修饰符
阻止冒泡 .stop
在me上的click后面加一个 .stop, 那么冒泡到了这里就结束了,就不会冒到father上面去了。
<div id="content">
<div id="grandFather" v-on:click="doc">
grandFather
<div id="father" v-on:click="doc">
father
<div id="me" v-on:click.stop="doc">
me
<div id="son" v-on:click="doc">
son
</div>
</div>
</div>
</div>
</div>
<script>
var content = new Vue({
el: "#content",
data: {
id: ''
},
methods: {
doc: function () {
this.id= event.currentTarget.id;
alert(this.id)
}
}
})
</script>
<style type="text/css">
* {
margin: 0 auto;
text-align:center;
line-height: 40px;
}
div {
width: 100px;
cursor:pointer;
}
#grandFather {
background: green;
}
#father {
background: blue;
}
#me {
background: red;
}#son {
background: gray;
}
</style>
优先触发 .capture
在father 上增加一个.capture,那么当冒泡发生的时候,就会优先让father捕捉事件,点击son或者me的时候,都会优先触发它。
<div id="content">
<div id="grandFather" v-on:click="doc">
grandFather
<div id="father" v-on:click.capture="doc">
father
<div id="me" v-on:click="doc">
me
<div id="son" v-on:click="doc">
son
</div>
</div>
</div>
</div>
</div>
<script>
var content = new Vue({
el: "#content",
data: {
id: ''
},
methods: {
doc: function () {
this.id= event.currentTarget.id;
alert(this.id)
}
}
})
</script>
<style type="text/css">
* {
margin: 0 auto;
text-align:center;
line-height: 40px;
}
div {
width: 100px;
cursor:pointer;
}
#grandFather {
background: green;
}
#father {
background: blue;
}
#me {
background: red;
}#son {
background: gray;
}
</style>
只有自己能触发,子元素无法触发.self
修改father,增加 .self,这样点击son 和 me都不会导致其触发click事件,只有点击father自己,才会导致事件发生。
<div id="content">
<div id="grandFather" v-on:click="doc">
grandFather
<div id="father" v-on:click.self="doc">
father
<div id="me" v-on:click="doc">
me
<div id="son" v-on:click="doc">
son
</div>
</div>
</div>
</div>
</div>
<script>
var content = new Vue({
el: "#content",
data: {
id: ''
},
methods: {
doc: function () {
this.id= event.currentTarget.id;
alert(this.id)
}
}
})
</script>
<style type="text/css">
* {
margin: 0 auto;
text-align:center;
line-height: 40px;
}
div {
width: 100px;
cursor:pointer;
}
#grandFather {
background: green;
}
#father {
background: blue;
}
#me {
background: red;
}#son {
background: gray;
}
</style>
只能触发一次 .once
修改father,增加 .once,这样father点击一次之后,就不会再监听到click了,等于是father只会执行一次
<div id="content">
<div id="grandFather" v-on:click="doc">
grandFather
<div id="father" v-on:click.once="doc">
father
<div id="me" v-on:click="doc">
me
<div id="son" v-on:click="doc">
son
</div>
</div>
</div>
</div>
</div>
<script>
var content = new Vue({
el: "#content",
data: {
id: ''
},
methods: {
doc: function () {
this.id= event.currentTarget.id;
alert(this.id)
}
}
})
</script>
<style type="text/css">
* {
margin: 0 auto;
text-align:center;
line-height: 40px;
}
div {
width: 100px;
cursor:pointer;
}
#grandFather {
background: green;
}
#father {
background: blue;
}
#me {
background: red;
}#son {
background: gray;
}
</style>
阻止提交 .prevent
只有超链和form这种会导致页面刷新的操作,.prevent 才有用。 普通的不导致页面刷新的按钮,加上这个没有任何变化。
通过在 click 后面添加 .prevent 可以阻止页面刷新。
三、Vue.js 条件语句
v-if
通过toggle函数切换show的值。 通过v-if 语句,当show 是true的时候,显示当前元素
<div id="div1">
<button v-on:click="toggle">隐藏/显示</button>
<div v-if="show"> 我是数据</div>
</div>
<script>
new Vue({
el: '#div1',
data: {
show:true
},
methods:{
toggle: function(){
this.show=!this.show;
}
}
})
</script>
v-else
<div id="div1">
<button v-on:click="moyiba"> 红绿灯切换 </button>
<div v-if="show"> 红灯 </div>
<div v-else>绿灯</div>
</div>
<script>
new Vue({
el: '#div1',
data: {
show:false
},
methods:{
moyiba: function(){
this.show=!this.show
}
}
})
</script>
v-else-if
<div id="div1">
<button v-on:click="toutai"> 看看下辈子投胎是做什么的 </button>
<div v-if="number>98"> 神仙</div>
<div v-else-if="number>95"> 国家领导人</div>
<div v-else-if="number>90"> 大富商</div>
<div v-else-if="number>80"> 大企业主</div>
<div v-else-if="number>70"> 演艺明星</div>
<div v-else-if="number>60"> 小企业主</div>
<div v-else-if="number>50"> 普通公务员</div>
<div v-else-if="number>40"> 小个体户</div>
<div v-else-if="number>30"> 血汗工厂工人</div>
<div v-else-if="number>20"> 偏远山区农民</div>
<div v-else> 流浪汉</div>
</div>
<script>
new Vue({
el: '#div1',
data: {
number:0
},
methods:{
toutai: function(){
this.number=Math.random()*100
}
}
})
</script>
四、Vue.js 循环语句
v-for 循环语句
先准备一个数组,然后作为数据构建成Vue,再在视图上用v-for便利数组
<div id="div1">
<table align="center" >
<tr class="firstLine">
<td>name</td>
<td>age</td>
</tr>
<tr v-for="people in peoples">
<td>{{people.name}}</td>
<td>{{people.age}}</td>
</tr>
</table>
</div>
<script>
var data = [
{name:"张三",age:41},
{name:"李四",age:25},
{name:"王五",age:27}
];
new Vue({
el: '#div1',
data: {
peoples:data
}
})
</script>
<style>
table tr td{
border:1px solid gray;
}
table{
border-collapse:collapse;
width:300px;
}
tr.firstLine{
background-color: lightGray;
}
</style>
Vue.js 属性绑定
通过v-bind进行属性绑定
<div id="div1">
演示:<input v-bind:value="value" id="in1">
<button v-on:click="clickupcc">按一下加一点</button>
</div>
<script>
var v = 10;
new Vue({
el:'#div1',
data:{
value:v
},
methods:{
clickupcc:function(){
v++;
this.value=v
}
}
})
</script>
五、Vue.js 双向绑定
v-model 双向绑定
前面的例子都是把Vue对象上的数据显示在视图上 ,那么怎么把视图上的数据放到Vue对象上去呢?
这时就需要用到v-model进行双向绑定。
像这样,当input里的值发生变化的时候,就会自动把变化后的值绑定到 Vue对象上去了,然后就可以对用户输入的数据进行处理。
<div id="div1">
请输入: <input v-model="name" >
<button @click="doClick" >提交</button>
</div>
<script>
new Vue({
el: '#div1',
data:{
name:"XXX"
},
methods:{
doClick:function(){
alert(this.name);
}
}
})
</script>
这种双向绑定就可以实现登陆注册等功能,用户在页面上输入账号密码,将其传输给Vue对象,然后稍作逻辑处理,将其传给后端,进行数据库比对就能实现了;
各种风格的数据绑定
<div id="div1">
<table align="center" >
<tr class="firstLine">
<td>视图类型</td>
<td>输入数据</td>
<td>绑定到Vue上的数值</td>
</tr>
<tr>
<td>
单行文本
</td>
<td>
<input v-model="input" placeholder="输入数据">
</td>
<td>
<p>{{ input }}</p>
</td>
</tr>
<tr>
<td>
多行文本
</td>
<td>
<textarea v-model="textarea" placeholder="输入数据"></textarea>
</td>
<td>
<p>{{ textarea }}</p>
</td>
</tr>
<tr>
<td>
单个复选框
</td>
<td>
<input type="checkbox" id="checkbox" v-model="checked">
</td>
<td>
<p>{{ checked }}</p>
</td>
</tr>
<tr>
<td>
多个复选框
</td>
<td>
<input type="checkbox" id="张三" value="张三" v-model="checkedes">
<label for="张三">张三</label>
<input type="checkbox" id="李四" value="李四" v-model="checkedes">
<label for="李四">李四</label>
<input type="checkbox" id="王五" value="王五" v-model="checkedes">
<label for="王五">王五</label>
</td>
<td>
<p>{{ checkedes }}</p>
</td>
</tr>
<tr>
<td>
单选按钮
</td>
<td>
<input type="radio" id="one" value="One" v-model="radio">
<label for="one">One</label>
<br>
<input type="radio" id="two" value="Two" v-model="radio">
<label for="two">Two</label>
</td>
<td>
<p>{{ radio }}</p>
</td>
</tr>
<tr>
<td>
单选选择框
</td>
<td>
<select v-model="selected" size="5">
<option disabled value="">请选择</option>
<option>AD</option>
<option>AC</option>
<option>ADC</option>
</select>
</td>
<td>
<p>{{ selected }}</p>
</td>
</tr>
<tr>
<td>
多选选择框
</td>
<td>
(通过ctrl或者shift进行多选)<br>
<select v-model="selecteds" multiple size="5">
<option disabled value="">请选择</option>
<option>AD</option>
<option>AC</option>
<option>ADC</option>
</select>
</td>
<td>
<p>{{ selecteds }}</p>
</td>
</tr>
<tr>
<td>
单个复选框
</td>
<td>
默认值是true或者false,也可以修改为自定义的值<br>
<input type="checkbox" id="toggle" true-value="yes" false-value="no" v-model="toggle">
</td>
<td>
<p>{{ toggle }}</p>
</td>
</tr>
</table>
</div>
<script>
new Vue({
el: '#div1',
data: {
input:'',
textarea:'',
checked:'',
checkedes:[],
radio:'',
selected:'',
selecteds:[],
toggle:'',
}
})
</script>
<style>
table tr td{
border:1px solid gray;
padding:10px;
}
table{
border-collapse:collapse;
width:800px;
table-layout:fixed;
}
tr.firstLine{
background-color: lightGray;
}
</style>
可以自己玩玩
六、Vue.js 计算属性
computed
<div id="div1">
<table align="center" >
<tr class="firstLine">
<td>人民币</td>
<td>美元</td>
</tr>
<tr>
<td align="center" colspan="2">
汇率: <input type="number" v-model.number="exchange" />
</td>
</tr>
<tr>
<td align="center">
¥: <input type="number" v-model.number = "rmb" />
</td>
<td align="center">
$: {{ dollar }}
</td>
</tr>
</table>
</div>
<script>
new Vue({
el: '#div1',
data: {
exchange:6.4,
rmb:0
},
computed:{
dollar:function() {
return this.rmb / this.exchange;
}
}
})
</script>
<style>
table tr td{
border:1px solid gray;
padding:10px;
}
table{
border-collapse:collapse;
width:800px;
table-layout:fixed;
}
tr.firstLine{
background-color: lightGray;
}
</style>
computed 和 methods 的区别
computed 是有缓存的,只要rmb没有变化,dollar 会直接返回以前计算出来的值,而不会再次计算。 这样如果是复杂计算,就会节约不少时间。
而methods每次都会调用
七、Vue.js 监听属性
watch
vue可以通过watch来监听属性值的变化。
这是一个计算人民币对美元汇率的例子
<table align="center" >
<tr class="firstLine">
<td>人民币</td>
<td>美元</td>
</tr>
<tr>
<td align="center" colspan="2">
汇率: <input type="number" v-model.number="exchange" />
</td>
</tr>
<tr>
<td align="center">
¥: <input type="number" v-model.number = "rmb" />
</td>
<td align="center">
$: <input type="number" v-model.number = "dollar" />
</td>
</tr>
</table>
</div>
<script>
new Vue({
el: '#div1',
data: {
exchange:6.4,
rmb:0,
dollar:0
},
watch:{
rmb:function(val) {
this.rmb = val;
this.dollar = this.rmb / this.exchange;
},
dollar:function(val) {
this.dollar = val;
this.rmb = this.dollar * this.exchange;
},
}
})
</script>
<style>
table tr td{
border:1px solid gray;
padding:10px;
}
table{
border-collapse:collapse;
width:800px;
table-layout:fixed;
}
tr.firstLine{
background-color: lightGray;
}
</style>
八、Vue.js 过滤器
一个过滤器
定义一个 首字母大写 过滤器
filters:{
capitalize:function(value) {
if (!value) return '' //如果为空,则返回空字符串
value = value.toString()
return value.charAt(0).toUpperCase() + value.substring(1)
}
}
它会将你的输入转为第一个字母大写
<div id="div1">
<table align="center" >
<tr class="firstLine">
<td>输入数据</td>
<td>过滤后的结果</td>
</tr>
<tr>
<td align="center">
<input v-model= "data" />
</td>
<td align="center">
{{ data|capitalize }}
</td>
</tr>
</table>
</div>
<script>
new Vue({
el: '#div1',
data: {
data:''
},
filters:{
capitalize:function(value) {
if (!value) return '' //如果为空,则返回空字符串
value = value.toString()
return value.charAt(0).toUpperCase() + value.substring(1)
}
}
})
</script>
<style>
table tr td{
border:1px solid gray;
padding:10px;
}
table{
border-collapse:collapse;
width:800px;
table-layout:fixed;
}
tr.firstLine{
background-color: lightGray;
}
</style>
多个过滤器
定义两个过滤器,分别是首字母大写和尾字母大写
<div id="div1">
<table align="center" >
<tr class="firstLine">
<td>输入数据</td>
<td>过滤后的结果</td>
</tr>
<tr>
<td align="center">
<input v-model= "data" />
</td>
<td align="center">
{{ data|capitalize|capitalizeLastLetter }}
</td>
</tr>
</table>
</div>
<script>
new Vue({
el: '#div1',
data: {
data:''
},
filters:{
capitalize:function(value) {
if (!value) return '' //如果为空,则返回空字符串
value = value.toString()
return value.charAt(0).toUpperCase() + value.substring(1)
},
capitalizeLastLetter:function(value) {
if (!value) return '' //如果为空,则返回空字符串
value = value.toString()
return value.substring(0,value.length-1)+ value.charAt(value.length-1).toUpperCase()
}
}
})
</script>
<style>
table tr td{
border:1px solid gray;
padding:10px;
}
table{
border-collapse:collapse;
width:800px;
table-layout:fixed;
}
tr.firstLine{
background-color: lightGray;
}
</style>
全局过滤器
在上面的例子里可以看到,过滤器是定义在Vue对象里的。 但是有时候,很多不同的页面都会用到相同的过滤器,如果每个Vue对象里都重复开发相同的过滤器,不仅开发量增加,维护负担也增加了。
所以就可以通过全局过滤器的方式,只定义一次过滤器,然后就可以在不同的Vue对象里使用了。
注册全局过滤器:
Vue.filter('capitalize', function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
})
Vue.filter('capitalizeLastLetter', function (value) {
if (!value) return '' //如果为空,则返回空字符串
value = value.toString()
return value.substring(0,value.length-1)+ value.charAt(value.length-1).toUpperCase()
})
然后就可以像前面的例子那样使用了
<div id="div1">
<table align="center" >
<tr class="firstLine">
<td>输入数据</td>
<td>过滤后的结果</td>
</tr>
<tr>
<td align="center">
<input v-model= "data" />
</td>
<td align="center">
{{ data|capitalize|capitalizeLastLetter }}
</td>
</tr>
</table>
</div>
<script>
Vue.filter('capitalize', function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
})
Vue.filter('capitalizeLastLetter', function (value) {
if (!value) return '' //如果为空,则返回空字符串
value = value.toString()
return value.substring(0,value.length-1)+ value.charAt(value.length-1).toUpperCase()
})
new Vue({
el: '#div1',
data: {
data:''
}
})
</script>
<style>
table tr td{
border:1px solid gray;
padding:10px;
}
table{
border-collapse:collapse;
width:800px;
table-layout:fixed;
}
tr.firstLine{
background-color: lightGray;
}
</style>