Vue
Vue是一个渐进式JavaScript框架
vue指令
<!doctype html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>测试vue</title>
<style rel="stylesheet">
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<div id="app">
<!-- v-cloak:防止数据编译产生的闪烁-->
<div v-cloak>
<!-- {{name}}:插值,用于替换数据-->
{{name}}
</div>
<!-- v-pre:禁止元素中插值编译-->
<div v-pre>
{{name}}
</div>
<!-- v-text:给元素绑定数据-->
<div v-text="name"></div>
<!-- v-html:给元素绑定HTML代码-->
<div v-html='html'></div>
<!-- v-once:禁止元素内的数据响应编译,可以提高性能 -->
<div v-once v-text="num"></div>
<div v-text="num"></div>
<!-- v-model:双向数据绑定,当input 值发生改变时,绑定的值响应式改变-->
<input type="text " v-model="name">
<!-- v-on: 事件绑定,用于绑定事件和方法-->
<!-- @click:@符为v-on的缩写-->
<input type="button" v-on:click="foo1" value="+1">
<input type="button" @click="foo2(1,2,$event)" value="-1">
<!-- vue调用方法有两种方式-->
<!-- 第一种为函数名调用,例:foo 不能传参,默认传递event(元素本身)-->
<!-- 第二种为函数调用,例:foo() 可以传参,需要使用元素本身需最后添加$event参数-->
</div>
<script src="js/vue.js"></script>
<script>
var vm = new Vue({
// el:用于绑定元素,值为选择器
el: '#app',
// data:用于存放数据
data: {
name: 'yang',
html: '<h1>你好</h1>',
num: 1
},
// methods:用于存放方法
methods: {
foo1: function (event) {
// data中的数据需要用 对象.参数 来调用
vm.num++;
console.log(event.target.tagName)
},
foo2: function (a1,a2,eve) {
// 在当前对象中this代表当前对象,所以this==vm为true
this.num--
console.log(a1,a2)
console.log(eve.target.tagName)
},
}
})
</script>
</body>
</html>
事件修饰符
事件冒泡
在以下代码中,当点击button按钮时会触发btn()
方法,同时会触发divEle()
方法,使num+1,这种情况就是事件冒泡,
我们并不希望触发divEle()
方法,就需要阻止事件冒泡
<div id="app">
<div v-text="num"></div>
<div @click="divEle">
<button @click="btn">按钮</button>
</div>
</div>
<script src="js/vue.js"></script>
<script>
var vm=new Vue({
el:'#app',
data:{
num:1
},
methods:{
divEle:function () {
this.num++
console.log('这里是div')
},
btn:function () {
console.log('这里是button')
}
}
})
</script>
阻止事件冒泡
我们只需要在为button绑定事件时在后面添加事件修饰符.stop
就可以阻止事件冒泡
<div id="app">
<div v-text="num"></div>
<div @click="divEle">
<button @click.stop="btn">按钮</button>
</div>
</div>
元素默认行为
在以下代码中,当我们点击a元素,会跳转到href中的地址中,这是a元素的默认行为,如果我们不需要这种行为,可以通过使用事件修饰符来解决
<div id="app">
<a href="http:www.baidu.com" @click="foo">百度</a>
</div>
<script src="js/vue.js"></script>
<script>
var vm=new Vue({
el:'#app',
data:{},
methods:{
foo:function () {
}
}
})
</script>
阻止元素默认行为
当我们不需要使用a元素的自动跳转行为时,可以通过添加.prevent
事件修饰符来解决
<div id="app">
<a href="http:www.baidu.com" @click.prevent="foo">百度</a>
</div>
<script src="js/vue.js"></script>
<script>
var vm=new Vue({
el:'#app',
data:{},
methods:{
foo:function () {
}
}
})
</script>
按键修饰符
vue提供了常用的按键修饰符,例如回车、删除,并且提供了可以自定义的按键修饰符
回车键
以下代码给<input type=‘password’>
元素添加@keyup.enter
事件,当在此元素按下回车会触发foo事件
<div id="app">
<!-- 动态绑定unman参数-->
<input type="text" v-model="uname">
<!-- 动态绑定passwd参数,为元素绑定键盘事件,当按下回车触发foo方法-->
<input type="password" v-model="passwd" @keyup.enter="foo">
<!-- 为按钮绑定单击事件,触发foo方法-->
<input type="button" value="提交" @click="foo">
</div>
<script src="js/vue.js"></script>
<script>
var vm=new Vue({
el:'#app',
data:{
uname:'',
passwd:'',
},
methods:{
foo:function () {
console.log(this.uname,this.passwd)
}
}
})
</script>
删除键
以下代码给<input type=‘uname’>
元素添加@keyup.delete
事件,当在此元素按下回车会触发del事件,清空输入框
<div id="app">
<!-- 动态绑定unman参数-->
<input type="text" v-model="uname" @keyup.delete="del">
<!-- 动态绑定passwd参数,为元素绑定键盘事件,当按下回车触发foo方法-->
<input type="password" v-model="passwd" @keyup.enter="foo">
<!-- 为按钮绑定单击事件,触发foo方法-->
<input type="button" value="提交" @click="foo">
</div>
<script src="js/vue.js"></script>
<script>
var vm=new Vue({
el:'#app',
data:{
uname:'',
passwd:'',
},
methods:{
foo:function () {
console.log(this.uname,this.passwd)
},
del:function () {
this.uname=''
}
}
})
</script>
自定义按键修饰符
通过使用Vue.config.keyCodes.自定义修饰符名称=按键代码
这种方式来定义按键修饰符,按键代码可以使用event.keyCode
来获取按键代码
在以下代码中,当在表单中按下按键,可以在控制台中看到对应的按键代码
<div id="app">
<input type="text" v-model="uname" @keyup="foo">
</div>
<script src="js/vue.js"></script>
<script>
var vm=new Vue({
el:'#app',
data:{
uname:'',
},
methods:{
foo:function (event) {
console.log(event.keyCode)
},
}
})
</script>
例如按下F1
会输出112,我们通过使用Vue.config.keyCodes.F1=112
就可以定义,使用方式相同
<div id="app">
<input type="text" v-model="uname" @keyup.F1="foo">
</div>
<script src="js/vue.js"></script>
<script>
Vue.config.keyCodes.F1=112
var vm=new Vue({
el:'#app',
data:{
uname:'',
},
methods:{
foo:function (event) {
console.log('你按下了F1')
},
}
})
</script>
案例(计算器)
<div id="app">
<input type="text" v-model="a1">
<input type="text" v-model="a2">
<input type="button" @click="foo" value="计算">
计算结果:<div v-text="num"></div>
</div>
<script src="js/vue.js"></script>
<script>
var vm=new Vue({
el:'#app',
data:{
a1:'',
a2:'',
num:''
},
methods:{
foo:function (event) {
this.num=parseInt(this.a1)+parseInt(this.a2)
},
}
})
</script>
属性绑定
v-bind
vue提供了v-bind
指令来绑定元素属性,简写为:
<div id="app">
<input type="button" @click="foo" v-bind:value="btn">
</div>
<script src="js/vue.js"></script>
<script>
var vm=new Vue({
el:'#app',
data:{
btn:'按钮'
},
methods:{
foo:function (event) {
if(this.btn=='按钮'){
this.btn='anniu'
}else {
this.btn='按钮'
}
},
}
})
</script>
v-model(双向绑定)的实现原理
给表单value属性绑定值为name,此时当name发生改变,value会动态发生改变,实现了单向绑定,当value发生改变时,name不会发生改变,
然后给表单绑定input事件,当value发生改变时,调用foo方法,通过获取event.target.value属性赋值给name使其发生改变,实现双向绑定
<div id="app">
<div v-text="name"></div>
<!-- 实现原理-->
<input type="text" :value="name" @input="foo">
<!-- 简写-->
<input type="text" :value="name" @input="name=$event.target.value">
<!-- 指令方式-->
<input type="text" v-model="name">
<!--以上三种双向数据绑定为等价,代码风格不同-->
</div>
<script src="js/vue.js"></script>
<script>
var vm=new Vue({
el:'#app',
data:{
name:'yang'
},
methods:{
foo:function (event) {
this.name=event.target.value
},
}
})
</script>
v-bind指令 绑定class 属性
v-bind绑定class 属性有两种方式,一是对象形式,二是数组形式
对象形式
:class="{class1:isClass1,class2:isClass2}"
对象形式属性名为class 名,属性值为布尔类型,值需要在data中定义,用于控制类名的开关,
以下代码中当鼠标进入元素,触发foo方法,关闭class1,打开class2,
<!doctype html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>测试vue</title>
<style rel="stylesheet">
.class1{
width: 100px;
height: 100px;
background-color: #d58512;
transition: background-color .2s,width .2s,height .2s;
}
.class2{
width: 200px;
height: 200px;
background-color: red;
transition: background-color .2s,width .2s,height .2s;
}
</style>
</head>
<body>
<div id="app">
<!-- @mouseover鼠标移入事件,@mouseleave鼠标移出事件-->
<div :class="{class1:isClass1,class2:isClass2}" @mouseover="foo" @mouseleave="foo"></div>
</div>
<script src="js/vue.js"></script>
<script>
var vm=new Vue({
el:'#app',
data:{
isClass1:true,
isClass2:false
},
methods:{
foo:function () {
this.isClass1=!this.isClass1
this.isClass2=!this.isClass2
}
}
})
</script>
</body>
</html>
数组形式
<!doctype html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>测试vue</title>
<style rel="stylesheet">
.class1{
width: 100px;
height: 100px;
background-color: #d58512;
transition: background-color .2s,width .2s,height .2s;
}
.class2{
width: 200px;
height: 200px;
background-color: red;
transition: background-color .2s,width .2s,height .2s;
}
</style>
</head>
<body>
<div id="app">
<!-- @mouseover鼠标移入事件,@mouseleave鼠标移出事件-->
<div :class="[c1,c2]" @mouseover="foo" @mouseleave="foo"></div>
</div>
<script src="js/vue.js"></script>
<script>
var vm=new Vue({
el:'#app',
data:{
c1:'class1',
c2:''
},
methods:{
foo:function () {
if (this.c1=='class1'){
this.c2='class2'
this.c1=''
}else {
this.c1='class1'
this.c2=''
}
}
}
})
</script>
</body>
</html>
数组&对象 结合(嵌套)使用
数组形式和对象形式可以结合使用
<div id="app">
<!-- @mouseover鼠标移入事件,@mouseleave鼠标移出事件-->
<div :class="[c1,{class2:isClass2}]" @mouseover="foo" @mouseleave="foo"></div>
</div>
<script src="js/vue.js"></script>
<script>
var vm=new Vue({
el:'#app',
data:{
c1:'class1',
isClass2:false,
},
methods:{
foo:function () {
this.isClass2=!this.isClass2
if(this.c1=='class1'){
this.c1='';
}else {
this.c1='class1';
}
}
}
})
</script>
简写数组
当class名过多时会影响代码可读性,所以可以使用简写形式,使用以下方式简写,实际页面中会有class1,class2两个类名
但是当c1中的元素发生改变时,实际页面不会响应式发生改变
<div id="app">
<!-- @mouseover鼠标移入事件,@mouseleave鼠标移出事件-->
<div :class="c1" @mouseover="foo" @mouseleave="foo"></div>
</div>
<script src="js/vue.js"></script>
<script>
var vm=new Vue({
el:'#app',
data:{
c1:['class1','class2'],
},
methods:{
foo:function () {
}
}
})
</script>
简写对象
<div id="app">
<!-- @mouseover鼠标移入事件,@mouseleave鼠标移出事件-->
<div :class="c1" @mouseover="foo" @mouseleave="foo"></div>
</div>
<script src="js/vue.js"></script>
<script>
var vm=new Vue({
el:'#app',
data:{
c1:{
class1:true,
class2:false
},
},
methods:{
foo:function () {
this.c1.class1=!this.c1.class1
this.c1.class2=!this.c1.class2
}
}
})
</script>
保留默认类名
以下代码中默认存在的class2会保留
<div id="app">
<!-- @mouseover鼠标移入事件,@mouseleave鼠标移出事件-->
<div :class="c1" class="class2" @mouseover="foo" @mouseleave="foo"></div>
</div>
<script src="js/vue.js"></script>
<script>
var vm=new Vue({
el:'#app',
data:{
c1:'class1',
},
methods:{
foo:function () {
}
}
})
</script>
v-bind指令 绑定style 属性
在vue中可以用对象的形式来绑定样式,当样式改变时可以响应式改变
<div id="app">
<!-- @mouseover鼠标移入事件,@mouseleave鼠标移出事件-->
<div :style="c1" @mouseover="foo" @mouseleave="foo"></div>
</div>
<script src="js/vue.js"></script>
<script>
var vm=new Vue({
el:'#app',
data:{
c1:{
width:'100px',
height:'100px',
border:'#1a1a1a 1px solid',
transition: 'width .2s,height .2s'
},
},
methods:{
foo:function () {
this.c1.width='200px'
this.c1.height='200px'
}
}
})
</script>
还可以通过数组的形式来绑定多个样式对象
<div id="app">
<!-- @mouseover鼠标移入事件,@mouseleave鼠标移出事件-->
<div :style="[c1,c2]" @mouseover="foo" @mouseleave="foo"></div>
</div>
<script src="js/vue.js"></script>
<script>
var vm=new Vue({
el:'#app',
data:{
c1:{
width:'100px',
height:'100px',
},
c2:{
border:'#1a1a1a 1px solid',
transition: 'width .2s,height .2s'
}
},
methods:{
foo:function () {
this.c1.width='200px'
this.c1.height='200px'
}
}
})
</script>
v-if v-else-if v-else
以下代码中,当num小于50显示c,小于80大于50显示B,大于80显示A,符合条件的元素渲染,不符合条件的不渲染(页面中不存在)
<div id="app">
<!-- @mouseover鼠标移入事件,@mouseleave鼠标移出事件-->
<div v-if="num>80">A</div>
<div v-else-if="num<80&&num>50">B</div>
<div v-else>C</div>
<input type="text" v-model="num">
</div>
<script src="js/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
num: 60
},
methods: {
}
})
</script>
v-show
以下代码与上面功能相同,但不同于v-if的是,不符合条件的代码渲染但不显示,会被添加style="display: none;"
样式
<div id="app">
<!-- @mouseover鼠标移入事件,@mouseleave鼠标移出事件-->
<div v-show="num>80">A</div>
<div v-show="num<80&&num>50">B</div>
<div v-show="num<50">C</div>
<input type="text" v-model="num">
</div>
<script src="js/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
num: 60
},
methods: {
}
})
</script>
v-for
遍历数组
v-for 类似于Python中for循环,用于遍历数组,本质为迭代器,:key="userInfo.id"
为循环添加唯一属性,提高性能
<div id="app">
<ul>
<li :key="userInfo.id" v-for="(userInfo,index) in list">
<div>索引{{index}}</div>
<div>用户名{{userInfo.name}}</div>
<div>密码{{userInfo.passwd}}</div>
</li>
</ul>
</div>
<script src="js/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
list:[
{
id:1,
name:'yang',
passwd:'111'
},
{
id:2,
name:'li',
passwd:'22222'
},
{
id:3,
name:'wang',
passwd:'3333'
},
{
id:4,
name:'song',
passwd:'44444'
},
]
},
methods: {
}
})
</script>
遍历对象
<div id="app">
<ul>
<li v-for="(value,key,index) in dc">
{{index}}---{{key}}----{{value}}
</li>
</ul>
</div>
<script src="js/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
dc:{
id:1,
name:'yang',
passwd:'111'
},
},
methods: {
}
})
</script>
v-if&&v-for
结合使用,渲染符合条件的内容
<div id="app">
<ul>
<li :key="userInfo.id" v-if="userInfo.id>2" v-for="(userInfo,index) in list">
<div>ID{{userInfo.id}}</div>
<div>用户名{{userInfo.name}}</div>
<div>密码{{userInfo.passwd}}</div>
</li>
</ul>
</div>
<script src="js/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
list:[
{
id:2,
name:'li',
passwd:'22222'
},
{
id:3,
name:'wang',
passwd:'3333'
},
{
id:4,
name:'song',
passwd:'44444'
},
]
},
methods: {
}
})
</script>
</body>
总结
选项卡案例
<!doctype html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>测试vue</title>
<style rel="stylesheet">
*{
margin: 0;
padding: 0;
border:none;
}
#app ul li{
list-style: none;
display: inline-block;
padding:0 5px 0 ;
margin-left:5px ;
height: 25px;
text-align: center;
line-height: 25px;
border-radius: 10px;
background-color: #EEEEEE;
}
#app li:hover{
background-color: #00bcd4;
}
#app .active{
background-color: #00bcd4;
}
#app div{
display: none;
}
#app .show{
display: block;
}
</style>
</head>
<body>
<div id="app">
<ul>
<li :key="i.id" :class="code==index?'active':''" v-for="(i,index) in list" @click="foo(index)">{{i.name}}</li>
</ul>
<div :key="i.id" :class="code==index?'show':''" v-for="(i,index) in list">
<img :src="i.url">
</div>
</div>
<script src="js/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
code:0,
list:[
{
id:1,
name:'K30',
url:'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/2c16238f786e4f93bdb175d7bf21aa47.jpg?thumb=1&w=200&h=200&f=webp&q=90'
},
{
id:2,
name:'K30 5G',
url:'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/53641901fbc28cbcdb495b17fdf69e46.jpg?thumb=1&w=200&h=200&f=webp&q=90'
},
{
id:3,
name:'9 CC pro',
url:'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/07270cc09689eb9b13b29aa9f6bc41eb.jpg?thumb=1&w=200&h=200&f=webp&q=90'
}
]
},
methods: {
foo:function (index) {
this.code=index
}
}
})
</script>
</body>
</html>
常用表单数据绑定方式
<div id="app">
<input type="text" v-model="text">
<input type="radio" id="nan" v-model="code" value="1"><label for="nan">男</label>
<input type="radio" id="nv" v-model="code" value="2"><label for="nv">女</label>
<input type="checkbox" value="1" id="yx" v-model="list"><label for="yx">游戏</label>
<input type="checkbox" value="2" id="dy" v-model="list"><label for="dy">电影</label>
<input type="checkbox" value="3" id="lq" v-model="list"><label for="lq">篮球</label>
<select v-model="num">
<option value="1">电脑</option>
<option value="2">电视</option>
<option value="3">电话</option>
</select>
<select v-model="num1" multiple="true" style="height: auto">
<option value="1">电脑</option>
<option value="2">电视</option>
<option value="3">电话</option>
<option value="4">电视</option>
<option value="5">电话</option>
<option value="6">电视</option>
<option value="7">电话</option>
</select>
<textarea v-model="text1" style="height: 100px;width: 100px;"></textarea>
</div>
<script src="js/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
text:'',
code:1,
list:[1],
num:1,
num1:[1,3,5],
text1:'sad'
},
methods: {
foo:function (index) {
this.code=index
}
}
})
</script>
自定义组件
使用Vue.component(自定义组件名,{data:方法,props:['自定义传入参数'],template:"组件HTML代码"})
自定义组件HTML代码中有且只能有一个根元素,且不支持v-for迭代,子元素事件可以通过使用$emit(‘自定义名称’)
的方式来传递给父组件,父组件通过@自定义名称
来监控子元素传递的事件,从而调用绑定的方法
<div id="app">
<nav1 :list1="list"></nav1>
<div :style="{fontSize: fontSize + 'px'}" >
{{fontSize}}
<!-- 父元素使用@自定义事件名来监控事件,并执行绑定的方法-->
<blog :ls="ls" @fs="foo"></blog>
</div>
</div>
<script>
Vue.component('blog', {
data: function () {
return {
}
},
props: ['ls'],
// 子组件中绑定事件可通过$emit(`自定义事件名`)来传递给父元素
template: '<div><div class="text" :key="j.id" v-for="j in ls"><h3>{{j.header}}</h3><button @click="$emit(`fs`)">放大</button><div>{{j.text}}</div></div></div>',
})
var vm = new Vue({
el: '#app',
data: {
fontSize:50,
list: [
{id: 1, name: 'yang', url: 'yang111'},
{id: 2, name: 'wang', url: 'wang111'},
{id: 3, name: 'jaca', url: 'yang111'},
{id: 4, name: '手机', url: 'www.baidu.com'}
],
ls: [
{id: 1, header: '阿里看见法拉第', text: 'adsfadfsfs'},
{id: 2, header: 'ccc', text: 'vzxvcvz'},
{id: 3, header: 'ccc', text: 'vzxvcvz'},
{id: 4, header: 'ccc', text: 'vzxvcvz'}
],
},
methods:{
foo:function () {
this.fontSize+=1
}
}
})
</script>
在$emit(‘自定义名称’,参数)
中可以添加一个参数,这个参数可以通过
e
v
e
n
t
来
访
问
,
而
方
法
默
认
传
递
event来访问,而方法默认传递
event来访问,而方法默认传递event参数,所以可以在foo方法中直接调用
<div id="app">
<nav1 :list1="list"></nav1>
<div :style="{fontSize: fontSize + 'px'}" >
{{fontSize}}
<!-- 父元素使用@自定义事件名来监控事件,并执行绑定的方法-->
<blog :ls="ls" @fs="foo"></blog>
<!-- @fs='foo'默认传递$event参数,-->
</div>
</div>
<script>
Vue.component('blog', {
data: function () {
return {
}
},
props: ['ls'],
// 子组件中绑定事件可通过$emit(`自定义事件名`)来传递给父元素
template: '<div><div class="text" :key="j.id" v-for="j in ls"><h3>{{j.header}}</h3><button @click="$emit(`fs`,2)">放大</button><div>{{j.text}}</div></div></div>',
})
var vm = new Vue({
el: '#app',
data: {
fontSize:50,
list: [
{id: 1, name: 'yang', url: 'yang111'},
{id: 2, name: 'wang', url: 'wang111'},
{id: 3, name: 'jaca', url: 'yang111'},
{id: 4, name: '手机', url: 'www.baidu.com'}
],
ls: [
{id: 1, header: '阿里看见法拉第', text: 'adsfadfsfs'},
{id: 2, header: 'ccc', text: 'vzxvcvz'},
{id: 3, header: 'ccc', text: 'vzxvcvz'},
{id: 4, header: 'ccc', text: 'vzxvcvz'}
],
},
methods:{
foo:function (event) {
// 可以直接调用
this.fontSize+=event
}
}
})
</script>