标签:过滤 模板编译 自己的 this fun lov 避免 冒号 语法
bower info vue
npm init --yes
cnpm install vue --save
vue2.0和1.0相比,最大的变化就是引入了Virtual DOM(虚拟DOM),页面更新效率更高,速度更快
js:
new Vue({
el:‘#itany‘, //指定关联的选择器
data:{ //存储数据
msg:‘Hello World‘,
name:‘tom‘
}
});
html:
<div id="itany">
{{msg}}
</div>
直接将vue-devtools解压缩,然后将文件夹中的chrome拖放到扩展程序中
//配置是否允许vue-devtools检查代码,方便调试,生产环境中需要设置为false
Vue.config.devtools=false;
Vue.config.productionTip=false; //阻止vue启动时生成生产消息
+ v-model
双向数据绑定,一般用于表单元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>常用指令:v-model</title>
<script src="js/vue.js"></script>
<script>
window.onload=function(){
new Vue({
// el:‘.itany‘,
el:‘div‘, //vue2.0中不允许将vue实例挂载到<html>或<body>元素,在vue1.0中是可以的
data:{
name:‘‘, //即使没有值,也不能省略,报错
age:21,
flag:true,
nums:[12,4,23,5],
user:{id:9527,name:‘唐伯虎‘}
}
});
}
</script>
</head>
<body>
<!-- <div id="itany"> -->
<!-- <div class="itany"> -->
<div>
用户名:<input type="text" v-model="name">
<br>
{{name}} <br>
{{age}} <br>
{{flag}} <br>
{{nums}} <br>
{{user}}
</div>
</body>
</html>
+ v-for
对数组或对象进行循环操作,使用的是v-for,不是v-repeat
注:在vue1.0中提供了隐式变量,如$index、$key,在vue2.0中去除了隐式变量,已被废除
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>常用指令:v-for</title>
<script src="js/vue.js"></script>
<script>
window.onload=function(){
new Vue({
el:‘#itany‘,
data:{
arr:[12,4,5,34,2,11],
user:{id:9527,name:‘唐伯虎‘,age:25},
arr2:[12,4,5,34,2,11,12],
users:[
{id:9527,name:‘唐伯虎‘,age:25},
{id:1001,name:‘秋香‘,age:22},
{id:1002,name:‘石榴姐‘,age:24}
]
}
});
}
</script>
</head>
<body>
<div id="itany">
<!-- {{arr}} -->
<ul>
<!-- 普通循环 -->
<li v-for="value in arr">{{value}}</li>
<!--<li v-for="value in user">{{value}}</li>-->
<!-- 键值循环 -->
<!-- <li v-for="(v,k) in arr">{{k}}={{v}}</li> -->
<!-- <li v-for="(v,k) in user">{{k}}={{v}}</li> -->
<!-- 可以直接循环包含重复数据的集合,可以通过指定:key属性绑定唯一key,当更新元素时可重用元素,提高效率,类似于vue1.0中track-by -->
<!-- <li v-for="(v,k) in arr2" :key="k">{{v}}</li> -->
<!--<li v-for="(user,index) in users">-->
<!--{{index+1}},{{user.id}},{{user.name}},{{user.age}}-->
<!--</li>-->
</ul>
</div>
</body>
</html>
+ v-on
用来绑定事件,用法:v-on:事件="函数"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>常用指令:v-on</title>
<script src="js/vue.js"></script>
<script>
window.onload=function(){
let vm=new Vue({
el:‘#itany‘,
data:{ //存储数据
arr:[12,34,45,23,5]
},
methods:{ //存储方法
show:function(){
console.log(‘show方法‘);
},
add(){
// console.log(this); //this表示当前vue实例
// console.log(this===vm); //true
this.arr.push(666); //使用this访问当前实例中的成员
// this.show();
}
}
});
}
</script>
</head>
<body>
<div id="itany">
<!-- <button onclick="show()">点我</button> -->
<button v-on:click="show">点我</button>
<button v-on:click="add()">向数组中添加一个元素</button>
<br>
{{arr}}
<hr>
<button v-on:mouseover="show">鼠标经过</button>
<button v-on:dblclick="show">鼠标双击</button>
</div>
</body>
</html>
+ v-show/v-if
用来显示或隐藏元素,v-show是通过display实现,v-if是每次删除后再重新创建,与angular中类似
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>常用指令:v-show</title>
<script src="js/vue.js"></script>
<script>
window.onload=function(){
let vm=new Vue({
el:‘#itany‘,
data:{
flag:true
},
methods:{
change(){
this.flag=!this.flag;
}
}
});
}
</script>
</head>
<body>
<div id="itany">
<!-- <button v-on:click="change">隐藏</button> -->
<button v-on:click="flag=!flag">隐藏</button>
<hr>
<div style="width: 100px;height: 100px; background-color: red" v-if="flag">欢迎来到南京网博</div>
</div>
</body>
</html>
事件简写
v-on:click="" 简写方式 @click=""
事件对象$event
包含事件相关信息,如事件源、事件类型、偏移量 target、type、offsetx
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件简写和事件对象$event</title>
<script src="js/vue.js"></script>
<script>
window.onload=function(){
let vm=new Vue({
el:‘#itany‘,
methods:{
show(){
console.log(111);
},
print(e){
// console.log(e);
console.log(e.target.innerHTML); //DOM对象
console.log(this);
}
}
});
}
</script>
</head>
<body>
<div id="itany">
<button v-on:click="show">点我</button>
<button @click="show">点我</button>
<hr>
<button @click="print($event)">Click Me</button>
</div>
</body>
</html>
事件冒泡
阻止事件冒泡:
a)原生js方式,依赖于事件对象
b)vue方式,不依赖于事件对象@click.stop
事件默认行为
阻止默认行为:
a)原生js方式,依赖于事件对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件冒泡和默认行为</title>
<script src="js/vue.js"></script>
<script>
window.onload=function(){
let vm=new Vue({
el:‘#itany‘,
methods:{
show(){
console.log(111);
// e.stopPropagation();
},
print(){
console.log(222);
},
write(){
console.log(333);
},
study(){
console.log(444);
// e.preventDefault();
}
}
});
}
</script>
</head>
<body>
<div id="itany">
<div @click="write">
<p @click="print">
<!-- <button @click="show($event)">点我</button> -->
<button @click.stop="show">点我</button>
</p>
</div>
<hr>
<!-- <a href="#" @click="study($event)">俺是链接</a> -->
<a href="#" @click.prevent="study">俺是链接</a>
</div>
</body>
</html>
键盘事件
回车:@keydown.13 或@keydown.enter
上:@keydown.38 或@keydown.up
默认没有@keydown.a/b/c...事件,可以自定义键盘事件,也称为自定义键码或自定义键位别名
事件修饰符
.stop - 调用 event.stopPropagation()。
.prevent - 调用 event.preventDefault()。
.{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
.native - 监听组件根元素的原生事件。
.once - 只触发一次回调。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>键盘事件</title>
<script src="js/vue.js"></script>
<script>
/**
* 自定义键位别名
*/
Vue.config.keyCodes={
a:65,
f1:112
}
window.onload=function(){
let vm=new Vue({
el:‘#itany‘,
methods:{
show(e){
console.log(e.keyCode);
if(e.keyCode==13){
console.log(‘您按了回车‘);
}
},
print(){
// console.log(‘您按了回车‘);
// console.log(‘您按了方向键上‘);
console.log(‘11111‘);
}
}
});
}
</script>
</head>
<body>
<div id="itany">
<!-- 键盘事件:@keydown、@keypress、@keyup -->
<!-- 用户名:<input type="text" @keydown="show($event)"> -->
<!-- 简化按键的判断 -->
<!-- 用户名:<input type="text" @keydown="show($event)"> -->
<!-- 用户名:<input type="text" @keydown.13="print"> -->
<!-- 用户名:<input type="text" @keydown.enter="print"> -->
<!-- 用户名:<input type="text" @keydown.up="print"> -->
用户名:<input type="text" @keydown.f1="print">
<!-- 事件修饰符 -->
<button @click.once="print">只触发一次</button>
</div>
</body>
</html>
属性绑定和属性的简写
v-bind 用于属性绑定, v-bind:属性=""
属性的简写:v-bind:src="" 简写为 :src=""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>属性绑定和属性的简写</title>
<script src="js/vue.js"></script>
<script>
window.onload=function(){
let vm=new Vue({
el:‘#itany‘,
data:{
url:‘https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png‘,
w:‘200px‘,
h:‘100px‘
}
});
}
</script>
</head>
<body>
<div id="itany">
<!-- <img src="{{url}}"> -->
<!-- 可以直接访问vue中的数据,不需要使用{{}} -->
<!-- <img v-bind:src="url"> -->
<img :src="url" :width="w" :height="h">
</div>
</body>
</html>
class和style属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>class和style属性</title>
<script src="js/vue.js"></script>
<script>
window.onload=function(){
let vm=new Vue({
el:‘#itany‘,
data:{
bb:‘aa‘,
dd:‘cc‘,
flag:true,
num:-2,
hello:{aa:true,cc:true},
xx:{color:‘blue‘,fontSize:‘30px‘},
yy:{backgroundColor:‘#ff7300‘}
}
});
}
</script>
<style>
.aa{
color:red;
font-size:20px;
}
.cc{
background-color:#ccc;
}
</style>
</head>
<body>
<div id="itany">
<!--
class属性
-->
<!-- <p class="aa">南京网博</p> --> <!-- 可以访问,普通css方式 -->
<!-- <p :class="aa">南京网博</p> --> <!-- 不可以,Vue的属性绑定时不能直接css样式 -->
<!-- 方式1:变量形式 -->
<!-- <p :class="bb">南京网博</p> -->
<!-- 方式2:数组形式,同时引用多个 -->
<!-- <p :class="[bb,dd]">南京网博</p> -->
<!-- 方式3:json形式,常用!!! -->
<!-- <p :class="{aa:true,cc:flag}">南京网博</p> -->
<!-- <p :class="{aa:num>0}">南京网博</p> -->
<!-- 方式4:变量引用json形式 -->
<!-- <p :class="hello">南京网博</p> -->
<!--
style属性
-->
<p :style="[xx,yy]">itany</p>
</div>
</body>
</html>
Vue.js使用基于HTML的模板语法,可以将DOM绑定到Vue实例中的数据
模板就是{{}},用来进行数据绑定,显示在页面中,也称为Mustache语法
a.双向绑定
v-model
b.单向绑定
方式1:使用两对大括号{{}},可能会出现闪烁的问题,可以使用v-cloak解决
方式2:使用v-text、v-html
v-once 数据只绑定一次
v-pre 不编译,直接原样显示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板</title>
<script src="js/vue.js"></script>
<script>
window.onload=function(){
let vm=new Vue({
el:‘#itany‘,
data:{
msg:‘welcome to itany‘
},
created:function(){
// alert(111);
}
});
}
</script>
<style>
/* 必须配置css样式,否则不生效 */
[v-cloak]{
display:none;
}
</style>
</head>
<body>
<div id="itany">
<input type="text" v-model="msg">
<h3>aaa<span v-cloak>{{msg}}</span></h3>
<h3 v-text="msg"></h3>
<h3 v-html="msg"></h3>
<h3 v-once>{{msg}}</h3>
<h3 v-pre>{{msg}}</h3>
</div>
</body>
</html>
用来过滤模型数据,在显示之前进行数据处理和筛选
语法:{{ data | filter1(参数) | filter2(参数)}}
1. 关于内置过滤器
vue1.0中内置许多过滤器,如:
currency、uppercase、lowercase
limitBy
orderBy
filterBy
vue2.0中已经删除了所有内置过滤器,全部被废除
如何解决:
a.使用第三方工具库,如lodash、date-fns日期格式化、accounting.js货币格式化等
b.使用自定义过滤器
2. 自定义过滤器
分类:全局过滤器、局部过滤器
自定义全局过滤器
使用全局方法Vue.filter(过滤器ID,过滤器函数)
自定义局部过滤器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定义过滤器</title>
<script src="js/vue.js"></script>
<script>
/**
* 自定义全局过滤器
*/
Vue.filter(‘addZero‘,function(data){
// console.log(data);
return data<10?‘0‘+data:data;
});
/*Vue.filter(‘number‘,(data,n) => {
// console.log(data,n);
return data.toFixed(n);
});*/
Vue.filter(‘date‘,data => {
let d=new Date(data);
return d.getFullYear()+‘-‘+(d.getMonth()+1)+‘-‘+d.getDate()+‘ ‘+d.getHours()+‘:‘+d.getMinutes()+‘:‘+d.getSeconds();
});
window.onload=function(){
let vm=new Vue({
el:‘#itany‘,
data:{
currentTime:Date.now()
},
filters:{ //局部过滤器
number:(data,n) => {
return data.toFixed(n);
}
}
});
}
</script>
</head>
<body>
<div id="itany">
<!-- <h3>{{3 | addZero}}</h3> -->
<!-- 课后作业:自己实现toFiexed()四舍五入的功能 -->
<h3>{{12.345678 | number(2)}}</h3>
<!-- <h3>{{12.045 | number(2)}}</h3> -->
<h3>{{currentTime | date}}</h3>
</div>
</body>
</html>
vue实例从创建到销毁的过程,称为生命周期,共有八个阶段,分别为数据观测前,数据观测后,模板挂载前,模板挂载后,组件更新前,组件更新后,组件销毁前,组件销毁后
其中最常用的就是监测数据后(created)和模板挂载后(mounted)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue生命周期</title>
<script src="js/vue.js"></script>
<script>
window.onload=function(){
let vm=new Vue({
el:‘#itany‘,
data:{
msg:‘welcome to itany‘
},
methods:{
update(){
this.msg=‘欢迎来到南京网博!‘;
},
destroy(){
// this.$destroy();
vm.$destroy();
}
},
beforeCreate(){
alert(‘组件实例刚刚创建,还未进行数据观测和事件配置‘);
},
created(){ //常用!!!
alert(‘实例已经创建完成,并且已经进行数据观测和事件配置‘);
},
beforeMount(){
alert(‘模板编译之前,还没挂载‘);
},
mounted(){ //常用!!!
alert(‘模板编译之后,已经挂载,此时才会渲染页面,才能看到页面上数据的展示‘);
},
beforeUpdate(){
alert(‘组件更新之前‘);
},
updated(){
alert(‘组件更新之后‘);
},
beforeDestroy(){
alert(‘组件销毁之前‘);
},
destroyed(){
alert(‘组件销毁之后‘);
}
});
}
</script>
</head>
<body>
<div id="itany">
{{msg}}
<br>
<button @click="update">更新数据</button>
<button @click="destroy">销毁组件</button>
</div>
</body>
</html>
计算属性也是用来存储数据,但具有以下几个特点:
将计算属性的get函数定义为一个方法也可以实现类似的功能
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>计算属性</title>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script src="js/vue-resource.min.js"></script>
</head>
<body>
<div id="itany">
<!--基本用法-->
<h2>基本属性:{{ msg }}</h2>
<h2>计算属性:{{ msg2 }}</h2>
<!--对数据处理再显示-->
<h2>基本属性:{{ msg.split(‘ ‘).reverse().join(‘ ‘) }}</h2>
<h2>计算属性:{{ reverseMsg }}</h2>
<button @click="change">修改值</button>
<p>小结:如果涉及值运算,运用计算属性,提高代码可读性和可维护性</p>
<br>
<!--计算属性 vs 方法-->
<h2>{{ num1 }}</h2>
<h2>{{ num2 }}</h2>
<h2>{{ getNum2() }}</h2>
<button onclick="fn()">修改num2</button>
<p>小结:依赖发生变化时,才会执行计算属性,否则取的是 之前缓存的结果</p>
<!--get和set-->
<h2>{{ num2 }}</h2>
<button @click="change2">修改计算属性</button>
</div>
<script>
var vm = new Vue({
el : ‘#itany‘,
data : {
msg : ‘welcome to dasha‘,
num1 : 8
},
computed : {//计算属性
msg2 : function(){//该函数必须有返回值,用来获取属性,称为get函数
return ‘欢迎来到南京网博‘
},
reverseMsg : function(){
//可以包含逻辑处理操作,同时reverseMsg依赖于msg
return this.msg.split(‘ ‘).reverse().join(‘ ‘)
},
num2 : {
get : function(){
console.log(‘num2:‘ + new Date());
return this.num1 - 1;
},
set : function(val){
console.log(‘修改num2值‘);
this.num1 = val;
}
}
},
methods : {
getNum2(){
console.log(‘基本方法‘);
console.log(new Date());
return this.num1 - 1;
},
change(){
this.msg = ‘i love you‘;
},
change2(){
this.num2 = 111;
}
}
});
function fn(){
setInterval(function(){
//console.log(vm.num2); 计算属性触发
console.log(vm.getNum2()); //基本方法
},1000)
}
</script>
</body>
</html>
vm.$el 获取vue实例关联的元素 DOM对象
vm.$data 获取数据对象data 也可以直接用vm.属性名取
vm.$options 获取自定义属性
vm.$refs 获取所有添加ref属性的元素
vm.$mount() 手动挂载vue实例
vm.$destroy() 销毁实例
vm.$nextTick(callback) 在DOM更新完成后再执行回调函数,一般在修改数据之后使用该方法,以便获取更新后的DOM
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue实例的属性和方法</title>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script src="js/vue-resource.min.js"></script>
</head>
<body>
<div id="itany">
{{ msg }}
<h2 ref="hello">hello</h2>
<h2 ref="world">world</h2>
</div>
<script>
var vm = new Vue({
el : ‘#itany‘,
data : {
msg : ‘welcome to itany‘
},
name : ‘tom‘,
age : 24,
show : function(){
console.log(‘show‘);
}
});
/*属性*/
//vm.属性名 获取data中的属性
//console.log(vm.msg);
//vm.$el 获取ue实例关联的元素
//console.log(vm.$el); //DOM对象
//vm.$el.style.color = ‘red‘;
//vm.$data //获取数据对象data
//console.log(vm.$data);
//console.log(vm.$data.msg);
//vm.$options //获取自定义属性
//console.log(vm.$options);
//console.log(vm.$options.name);
//console.log(vm.$options.age);
//console.log(vm.$options.show);
//vm.$refs 获取所有添加ref属性的元素
//console.log(vm.$refs);
//console.log(vm.$refs.hello); //DOM对象
//vm.$refs.hello.style.color = ‘blue‘;
/*方法*/
//vm.$mount() 手动挂载vue实例
//vm.$mount(‘#itany‘);
//var vm = new Vue({
// data : {
// msg : ‘欢迎来到南京网博‘,
// name : ‘tom‘
// }
//}).$mount(‘#itany‘);
//vm.$destroy() 销毁实例
//vm.$destroy();
// vm.$nextTick(callback) 在DOM更新完成后再执行回调函数,一般在修改数据之后使用该方法,以便获取更新后的DOM
//修改数据
vm.name=‘汤姆‘;
//DOM还没更新完,Vue实现响应式并不是数据发生改变之后DOM立即变化,需要按一定的策略进行DOM更新,需要时间!!
// console.log(vm.$refs.title.textContent);
vm.$nextTick(function(){
//DOM更新完成,更新完成后再执行此代码
console.log(vm.$refs.title.textContent);
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加和删除属性: $set、$delete</title>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script src="js/vue-resource.min.js"></script>
</head>
<body>
<div id="itany">
<button @click="doUpdate">修改属性</button>
<button @click="doAdd">添加属性</button>
<button @click="doDelete">删除属性</button>
<br>
<h2>{{ user.name }}</h2>
<h2>{{ user.age }}</h2>
</div>
<script>
var vm = new Vue({
el : ‘#itany‘,
data : {
user : {
id : 1001,
name : ‘tom‘
}
},
methods : {
doUpdate(){
this.user.name = ‘汤姆‘
},
doAdd(){
//通过普通方式为对象添加属性时 vue无法实时监控
//this.user.age = 25; //属性添加成功,但是页面不显示
this.$set(this.user,‘age‘,18); //通过vue实例的$set方法为对象体添加属性,可以实时监控到
Vue.set(this.user,‘age‘,22); //全局设置
if(this.user.age){
console.log(this.user.age);
this.user.age++;
}else{
Vue.set(this.user,‘age‘,1)
}
},
doDelete(){
if(this.user.age){
Vue.delete(this.user, ‘age‘);
}
}
}
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>监视数据的变化 $watch</title>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script src="js/vue-resource.min.js"></script>
</head>
<body>
<div id="itany">
<input type="text" v-model="name">
<h3>{{ name }}</h3>
<hr>
<input type="text" v-model="age">
<h3>{{ age }}</h3>
<hr>
<input type="text" v-model="user.name">
<h3>{{ user.name }}</h3>
</div>
<script>
var vm = new Vue({
el : ‘#itany‘,
data : {
name : ‘tom‘,
age : 23,
user : {
id : 1001,
name : ‘alice‘
}
},
watch : {//方式2:使用vue实例提供的watch选项
age : (newValue,oldValue) => {
console.log(‘age被修改啦,原值:‘+oldValue+‘,新值:‘+newValue);
},
user : {
handler : (newValue,oldValue) => {
console.log(‘user被修改啦,原值:‘+oldValue.name+‘,新值:‘+newValue.name);
},
deep : true //深度监视,当对象中的属性发生变化时也会监视
}
}
});
//方式1 使用vue实例提供的$watch()方法
vm.$watch(‘name‘,function(newValue,oldValue){
console.log(‘name被修改啦,原值:‘ + oldValue + ‘, 新值:‘ + newValue);
})
</script>
</body>
</html>
分类:全局指令、局部指令
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定义指令</title>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script src="js/vue-resource.min.js"></script>
</head>
<body>
<div id="itany">
<!--<p>验证钩子函数 或者 说是指令执行的生命周期</p>-->
<!--<h3 v-hello>{{ msg }}</h3>-->
<!--<button @click="change">更新数据</button>-->
<!--<hr>-->
<!--<p>定义指令参数验证</p>-->
<!--<h3 v-world:wbs17022.haha>{{ msg }}</h3>-->
<p>自定义局部指令</p>
<input type="text" v-model="msg" v-focus>
</div>
<script>
/*自定义全局指令*/
/*注:使用指令时必须在指令名称前加前缀v-,即v-指令名称*/
Vue.directive(‘hello‘,{
bind(){//常用!
alert(‘指令第一次绑定到元素上时调用,只调用一次,可执行初始化操作‘);
},
inserted(){
alert(‘被绑定元素插入到DOM中时调用‘);
},
update(){
alert(‘被绑定元素所在模板更新时调用‘);
},
componentUpdated(){
alert(‘被绑定元素所在模版完成一次更新周期时调用‘);
},
unbind(){
alert(‘指令与元素解绑时调用,只调用一次‘);
}
});
//钩子函数的参数
Vue.directive(‘world‘,{
bind(el,binding){
console.log(el);
el.style.color = ‘red‘;
console.log(binding); //指令name
console.log(binding.arg); //冒号后面的值
console.log(binding.modifiers); //后缀对象 {haha: true}
}
});
//传入一个简单的函数, bind 和 update时调用
Vue.directive(‘wbs‘,function(){
alert(‘wbs17022‘);
});
var vm = new Vue({
el : ‘#itany‘,
data : {
msg : ‘welcome to itany‘
},
methods : {
change(){
this.msg = ‘hello world‘
}
},
directives : {//自定义局部指令
focus : {
//当被绑定元素插入到DOM中时获取焦点
inserted(el){
el.focus();
}
}
}
});
</script>
</body>
</html>
Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果本质上还是使用CSS3动画:transition、animation
使用transition组件,将要执行动画的元素包含在该组件内<transition>运动的元素</transition> 过滤的CSS类名:6个,通过设置好这几个类就达到动画的效果,提供8个钩子函数在动画生命周期里写入触发事件函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>单个动画</title>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script src="js/vue-resource.min.js"></script>
<style>
p{
width : 300px;
height : 300px;
background-color : red;
}
.fade-enter-active,.fade-leave-active{
transition : all 3s ease;
}
.fade-enter-active{
opacity : 1;
width : 300px;
height : 300px;
}
.fade-leave-active{
opacity : 0;
width : 50px;
height : 50px;
}
/* .fade-enter需要放在.fade-enter-active的后面*/
.fade-enter{
opacity : 0;
width : 100px;
height : 100px;
}
</style>
</head>
<body>
<div id="itany">
<button @click="flag=!flag">点我</button>
<!--name可以随便取-->
<transition name="fade"
@before-enter="beforeEnter" @enter="enter"
@after-enter="afterEnter" @before-leave="beforeLeave"
@leave="leave" @after-leave="afterLeave">
<p v-show="flag">wang bo</p>
</transition>
</div>
<script>
var vm = new Vue({
el : ‘#itany‘,
data : {
flag : false
},
methods : {
beforeEnter(el){
alert(‘动画进入之前‘);
},
enter(){
alert(‘动画进入‘);
},
afterEnter(el){
alert(‘动画进入之后‘);
el.style.background=‘blue‘;
},
beforeLeave(){
alert(‘动画即将离开之前‘)
},
leave(){
alert(‘动画离开‘);
},
afterLeave(el){
alert(‘动画离开之后‘);
el.style.background = ‘red‘;
}
},
});
</script>
</body>
</html>
当然你也可以结合第三方提供动画插件animate实现动画效果,只要使用它提供的样式就可以了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>动画</title>
<link rel="stylesheet" href="css/animate.css">
<script src="js/vue.js"></script>
<style>
p{
width: 300px;
height: 300px;
background-color:red;
margin:0 auto;
}
</style>
</head>
<body>
<div id="itany">
<button @click="flag=!flag">点我</button>
<transition enter-active-class="animated fadeInLeft" leave-active-class="animated fadeOutRight">
<p v-show="flag">网博</p>
</transition>
</div>
<script>
var vm=new Vue({
el:‘#itany‘,
data:{
flag:false
}
});
</script>
</body>
</html>
上面transition标签也只能实现单个动画效果,如果想实现多个动画效果,就必须使用transition-group标签,并且每个动画标签都要给key属性绑定一个唯一值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>多元素动画</title>
<link rel="stylesheet" href="css/animate.css">
<script src="js/vue.js"></script>
<style>
p{
width: 100px;
height: 100px;
background-color:red;
margin:20px auto;
}
</style>
</head>
<body>
<div id="itany">
<button @click="flag=!flag">点我</button>
<transition-group enter-active-class="animated bounceInLeft" leave-active-class="animated bounceOutRight">
<p v-show="flag" :key="1">itany</p>
<p v-show="flag" :key="2">网博</p>
</transition-group>
</div>
<script>
var vm=new Vue({
el:‘#itany‘,
data:{
flag:false
}
});
</script>
</body>
</html>
组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码组件是自定义元素(对象)
定义组件的两种方式:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>定义组件的两种方式</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="itany">
<hello></hello>
<my-world></my-world>
</div>
<script>
/*方式1:先创建组件构造器,然后由组件构造器创建组件*/
//1.使用Vue.extend()创建一个组件构造器
var MyComponent = Vue.extend({
template : ‘<h3>Hello World</h3>‘
});
//2.使用Vue.component(标签名,组件构造器) 根据组件构造器来创建组件
Vue.component(‘hello‘, MyComponent);
/*方式2:直接创建组件(推荐)*/
Vue.component(‘my-world‘,{
template : ‘<h1>你好,世界</h1>‘
})
var vm = new Vue({//这里的vm也是一个组件 称为根组件Root
el : ‘#itany‘,
data : {
msg : ‘wang bo‘
}
})
</script>
</body>
</html>
组件分为全局组件、局部组件,全局组件由Vue.component方法定义,而局部组件则是vue实例中的components里定义
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>组件的分类</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="itany">
<my-hello></my-hello>
<my-world></my-world>
</div>
<script>
/*全局组件,可以在所有vue实例中使用*/
Vue.component(‘my-hello‘,{
template : ‘<h3>{{ name }}</h3>‘,
data : function(){//在组件中存储数据时,必须以函数形式,函数返回一个对象
return {
name : ‘alex‘
}
}
});
/*局部组件,只能在当前vue实例中使用,vue实例中提供components选项定义*/
vm = new Vue({
el : ‘#itany‘,
data : {
name : ‘wang bo‘
},
components : {
‘my-world‘ : {
//vue实例本身也是组件,和当前my-world组件是父子组件关系,子组件是不能直接访问父组件的data数据的
//template : ‘<h3>{{ name }}</h3>‘,
template : ‘<h3>{{ age }}</h3>‘,
data(){
return {
age : 25
}
}
}
}
})
</script>
</body>
</html>
引用模板:除了在组件里的template选项指定模板外,另外还提供了一种方式--将组件内容放到模板<template>中并引用
另外在用template标签定义模板时,需要保证template标签只有一个根元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>引用模板</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="itany">
<my-hello></my-hello>
</div>
<template id="wbs">
<!--template必须有且只有一个根元素-->
<div>
<h3>{{ msg }}</h3>
<ul>
<li v-for="value in arr">{{ value }}</li>
</ul>
</div>
</template>
<script>
var vm = new Vue({
el : ‘#itany‘,
components : {
‘my-hello‘ : {
name : ‘wbs17022‘, //指定组件的名称,默认为标签名,可以不设置
template : ‘#wbs‘,
data(){
return {
msg : ‘welcome to the world‘,
arr : [‘tom‘, ‘jack‘, ‘mike‘]
}
}
}
}
})
</script>
</body>
</html>
动态组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>动态组件</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="itany">
<button @click="flag=‘my-hello‘">显示hello组件</button>
<button @click="flag=‘my-world‘">显示world组件</button>
<!--使用keep-alive组件缓存非活动组件,可以保留状态,避免重新渲染,默认每次都会销毁非活动组件并重新创建-->
<keep-alive>
<component :is="flag"></component>
</keep-alive>
</div>
<script>
var vm = new Vue({
el : ‘#itany‘,
data : {
flag : ‘my-hello‘
},
components : {
‘my-hello‘ : {
template : ‘<h2>我是hello组件{{x}}</h2>‘,
data(){
return {
x : Math.random()
}
}
},
‘my-world‘ : {
template : ‘<h3>我是world组件{{y}}</h3>‘,
data(){
return {
y : Math.random()
}
}
}
}
})
</script>
</body>
</html>
在一个组件内部定义另一个组件,称为父子组件,子组件只能在父组件内部使用,默认情况下,子组件无法访问父组件中的数据,每个组件实例的作用域是独立的
子组件访问父组件的数据:
总结:父组件通过props向下传递数据给子组件
注:组件中的数据共有三种形式:data、props、computed
父组件访问子组件的数据:
总结:子组件通过events给父组件发送消息,实际上就是子组件把自己的数据发送到父组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>父子组件及组件间数据传递</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="itany">
<my-hello></my-hello>
<!--嵌套的子组件是不可以直接访问的,只能在父组件的模板下访问-->
<!--<my-world></my-world>-->
</div>
<template id="hello">
<div>
<h3>我是hello父组件</h3>
<h3>访问自己的数据:{{ msg }},{{ name }},{{ age }},{{ user.username }}</h3>
<br>
<h4>子组件只能在父模板下访问</h4>
<my-world :message="msg" :name="name" :age="age" @e-world="getData"></my-world>
<!--<my-world :message="msg" :name="name" :age="age" :user="user"></my-world>-->
<h3>访问子组件的数据:{{ sex }},{{ height }}</h3>
</div>
</template>
<template id="world">
<div>
<h4>我是world子组件</h4>
<h4>访问自己的数据:{{ sex }},{{ height }}</h4>
<br>
<h4>访问父组件中的数据:{{ message }},{{ name }},{{ age }},{{ user.username}}</h4>
<button @click="send">将子组件的数据向上传递给父组件</button>
</div>
</template>
<script>
var vm = new Vue({//根组件
el : ‘#itany‘,
components : {
‘my-hello‘ : { //父组件
methods : {
getData(sex,height){
this.sex = sex;
this.height = height;
}
},
data(){
return {
msg : ‘wang bo‘,
name : ‘tom‘,
age : 23,
user : {id:9527,username:‘唐伯虎‘},
sex : ‘‘,
height : ‘‘
}
},
template : ‘#hello‘,
components : {
‘my-world‘ : {//子组件
data(){
return {
sex : ‘male‘,
height : 180.5
}
},
template : ‘#world‘,
//props : [‘message‘,‘name‘,‘age‘,‘user‘] //简单的字符串数组
props : {//也可以是对象形式
message : String,
name : {
type : String,
required : true,
},
age : {
type : Number,
default : 18,
validator : function(value){
return value >= 0;
}
},
user : {
type : Object,
default : function(){//对象或数组的默认值必须使用函数的形式来返回
return {id:3306,username:‘秋香‘};
}
}
},
methods : {
send(){//如果你希望在加载就被父组件访问到,可以用vue生命周期中挂载事件
//console.log(this); //此处的this表示当前子组件实例
this.$emit(‘e-world‘,this.sex,this.height); //使用$emit()触发一个事件,发送数据
}
}
}
}
}
}
})
</script>
</body>
</html>
单向数据流
子组件修改父组件解决方案:
使用.sync(1.0版本中支持,2.0版本中不支持,2.3版本又开始支持) 需要$emit显式地触发一个更新事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>单向数据流</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="itany">
<h2>父组件:{{ name }}</h2>
<h4>双向绑定,改变父组件的数据,子组件传入的数据也会跟着改</h4>
<input type="text" v-model="name">
<h2>父组件{{ user.age }}</h2>
<hr>
<!--在调用子组件时,通过.sync允许子组件修改指定名称父组件传递的数据-->
<my-hello :name.sync="name" :user="user"></my-hello>
</div>
<template id="hello">
<div>
<h3>子组件{{ name }}</h3>
<!--变量赋值修改-->
<!--<h3>子组件{{ username }}</h3>-->
<h3>子组件{{ user.age }}</h3>
<h4>而子组件想修改父组件的数据,是不能直接修改的,修改报错</h4>
<!--方式1:赋值给新的变量-->
<button @click="change">修改数据</button>
</div>
</template>
<script>
var vm = new Vue({
el : ‘#itany‘,
data : {
name : ‘tom‘,
user : {
name : ‘zhangsan‘,
age : 24
}
},
components : {
‘my-hello‘ : {
template : ‘#hello‘,
props : [‘name‘,‘user‘],
data(){
return {
username : this.name //方式1:将数据存入另一个变量中再操作
}
},
methods : {
change(){
//this.name = ‘alex‘; 直接修改 报错
//this.username = ‘alex‘; 赋值修改
this.$emit(‘update:name‘,‘alex‘); //方式2:a.使用.sync,需要用$emit显式触发更新事件
this.user.age = 10000; //方式2:b.利用对象是引用类型,修改属性时,不会改变内存地址
}
}
}
}
})
</script>
</body>
</html>
非父子组件间的通信
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>非父子组件通信</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="itany">
<my-a></my-a>
<my-b></my-b>
<my-c></my-c>
</div>
<template id="a">
<div>
<h3>A组件{{ name }}</h3>
<button @click="send">将数据发送给C组件</button>
</div>
</template>
<template id="b">
<div>
<h3>B组件{{ age }}</h3>
<button @click="send">将数组发送给C组件</button>
</div>
</template>
<template id="c">
<div>
<h3>C组件{{ name }}{{ age }}</h3>
</div>
</template>
<script>
//定义一个空的Vue实例
var Event = new Vue({
name : ‘yes‘
});
var A = {
template : ‘#a‘,
data(){
return {
name : ‘tom‘
}
},
methods : {
send(){
Event.$emit(‘data-a‘, this.name);
}
}
};
var B = {
template : ‘#b‘,
data(){
return {
age : ‘2555‘
}
},
methods : {
send(){
Event.$emit(‘data-b‘, this.age);
}
}
};
var C = {
template : ‘#c‘,
data(){
return {
name : ‘‘,
age : ‘‘
}
},
mounted(){//在模板编译完成后执行
//Event.$on(‘data-a‘,function(name){
// console.log(name);
// console.log(this); //此时的this是Event,也就是空Vue实例
//});
Event.$on(‘data-a‘,name => {
this.name = name;
console.log(this); //此时this是C组件,和上面的函数调用方式有所区别
});
Event.$on(‘data-b‘,age => {
this.age = age;
})
}
};
var vm = new Vue({
el : ‘#itany‘,
components : {
‘my-a‘ : A,
‘my-b‘ : B,
‘my-c‘ : C
}
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>slot内容分发</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="itany">
<!--<my-hello></my-hello>-->
<!--<my-hello>456</my-hello>-->
<my-hello>
<ul slot="s1">
<li>aaa</li>
<li>bbb</li>
<li>ccc</li>
</ul>
<ol slot="s2">
<li>111</li>
<li>222</li>
<li>333</li>
</ol>
</my-hello>
</div>
<template id="hello">
<div>
<h3>welcome to itany</h3>
<!--如果my-hello标签间没有内容,则用默认值123-->
<!--<slot>123</slot>-->
<slot name="s2"></slot>
<hr>
<slot name="s1"></slot>
</div>
</template>
<script>
var vm = new Vue({
el : ‘#itany‘,
components : {
‘my-hello‘ : {
template : ‘#hello‘
}
}
});
</script>
</body>
</html>
使用Vue.js开发SPA(Single Page Application)单页面应用,根据不同url地址,显示不同的内容,但显示在同一个页面中,称为单页面应用 [参考](https://router.vuejs.org/zh-cn)
cnpm install vue-router -S
路由配置分四步走
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>路由基本用法</title>
<script src="js/vue.js"></script>
<script src="js/vue-router.js"></script>
<style>
.active{
font-size : 20px;
color : #ff7300;
text-decoration : none;
}
</style>
</head>
<body>
<div id="itany">
<div>
<router-link to="/home">主页</router-link>
<router-link to="/news">新闻</router-link>
</div>
<div>
<router-view></router-view>
</div>
</div>
<script>
//1.定义组件
var Home = {
template : ‘<h3>我是主页</h3>‘
};
var News = {
template : ‘<h3>我是新闻</h3>‘
};
//2.配置路由
const routes = [
{path:‘/home‘,component:Home},
{path:‘/news‘,component:News},
{path:‘*‘,redirect:‘/home‘} //重定向
];
//3.创建路由实例
const router = new VueRouter({
routes, //简写,相当于routes:routes
//mode : ‘history‘, //更改模式
linkActiveClass : ‘active‘ //更新活动链接的class类名
});
//4.创建根实例并将路由挂载到Vue实例上
new Vue({
el : ‘#itany‘,
router //注入路由
})
</script>
</body>
</html>
传参的两种方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>路由嵌套和参数传递</title>
<link rel="stylesheet" href="css/animate.css">
<script src="js/vue.js"></script>
<script src="js/vue-router.js"></script>
<style>
.active{
font-size : 20px;
color : #ff7300;
text-decoration : none;
}
</style>
</head>
<body>
<div id="itany">
<div>
<router-link to="/home">主页</router-link>
<router-link to="/user">用户</router-link>
</div>
<div>
<transition
enter-active-class="animated bounceInLeft"
leave-active-class="animated bounceOutRight"
>
<router-view></router-view>
</transition>
<hr>
<button @click="push">添加路由</button>
<button @click="replace">替换路由</button>
</div>
</div>
<template id="user">
<div>
<h3>用户信息</h3>
<ul>
<!--router-link里还提供tag选项 用指定生成什么标签-->
<router-link to="/user/login?username=alex&age=89" tag="li">用户登录</router-link>
<router-link to="/user/regist/alex/89" tag="li">用户注册</router-link>
</ul>
<router-view></router-view>
</div>
</template>
<script>
var Home = {
template : ‘<h3>我是主页</h3>‘
};
var User = {
template : ‘#user‘
};
var Login = {
template : ‘<h4>用户登录....获取参数:{{ $route.query }},{{ $route.path }}</h4>‘,
mounted : function(){
alert(this.$route.query.username);
}
};
var Regist = {
template : ‘<h4>用户注册 获取参数:{{ $route.params }},{{ $route.path }}</h4>‘
};
const routes = [
{
path : ‘/home‘,
component : Home
},
{
path : ‘/user‘,
component : User,
children : [
{
path : ‘login‘,
component : Login
},
{
path : ‘regist/:username/:password‘,
component : Regist
}
]
},
{
path : ‘*‘,
redirect : ‘/home‘
}
];
const router = new VueRouter({
routes,
linkActiveClass : ‘active‘
});
new Vue({
el : ‘#itany‘,
router,
methods : {
push(){
router.push({path:‘home‘}); //添加路由, 本质上就是在触发时 切换路由 这里切换到home
},
replace(){
router.replace({path:‘user‘}); //替换路由 还是切换路由 没有历史记录
}
}
})
</script>
</body>
</html>
标签:过滤 模板编译 自己的 this fun lov 避免 冒号 语法
原文地址:https://www.cnblogs.com/xinsiwei18/p/9037089.html