适合初学者的Vue-1.0教程(三)

计算属性

    <div id="box">
        a => {{a}}
        <br>
        b => {{b}}
    </div>
    <script>
        var vm=new Vue({
            el:'#box',
            data:{
                a:1
            },
            computed:{
                b:function(){
                 return 2;
                }
            }
        });
        console.log(vm.a);
    </script>

计算属性和data对象属性都是可以直接在DOM上直接使用的

var vm=new Vue({
            el:'#box',
            data:{
                a:1
            },
            computed:{
                b:function(){
                    //业务逻辑代码
                    return this.a+1;
                }
            }
        });
        document.onclick=function(){
            vm.a=101;
        };

但计算属性可以获取data对象属性,根据获取的data对象属性计算出想要的值
上面的写法只适用于向计算属性取值

<div id="box">
        a => {{a}}
        <br>
        b => {{b}}
    </div>
    <script>
        var vm=new Vue({
            el:'#box',
            data:{
                a:1
            },
            computed:{
                b:{
                    get:function(){
                        return this.a+2;
                    },
                    set:function(val){
                        this.a=val;
                    }
                }
            }
        });

        document.onclick=function(){
            vm.b=10;
        };
    </script>
image.png

点击之后
这种写法,无论是对计算属性取值或赋值,代码都有做相应的处理


image.png

监听数据变化

    <script>
        window.onload=function(){
            var vm=new Vue({
                el:'#box',
                data:{
                    a:111,
                    b:2
                }
            });
            vm.$watch('a',function(){
                alert('发生变化了');

                this.b=this.a+100;
                
            });
            document.onclick=function(){
                vm.a=1;
            };
        };
    </script>
    <div id="box">
        {{a}}
        <br>
        {{b}}
    </div>
image.png

点击之后
会弹出“发生变化了”的弹出框

image.png

使用钩子函数$mount

        var vm=new Vue({
            data:{
                arr:['apple','pear','orange']
            },
            methods:{
                add:function(){
                    this.arr.push('tomato');
                }
            }
        }).$mount('#box');

实例化之后再挂载目标元素

生命周期
<div id="box">
        {{msg}}
    </div>
    <script>
        var vm=new Vue({
            el:'#box',
            data:{
                msg:'well'
            },
            created:function(){
                alert('实例已经创建');
            },
            beforeCompile:function(){
                alert('编译之前');
            },
            compiled:function(){
                alert('编译之后');
            },
            ready:function(){
                alert('插入到文档中');
            },
            beforeDestroy:function(){
                alert('销毁之前');
            },
            destroyed:function(){
                alert('销毁之后');
            }
        });

        /*点击页面销毁vue对象*/
        document.onclick=function(){
            vm.$destroy();
        };
    </script>

Vue的生命周期依次为:
实例已经创建、编译之前、编译之后、插入到文档中、销毁之前、销毁之后

Vue也提供了一些便捷方式去操作绑定元素、获取数据、操作实例等
<div id="box">
        {{a}}
    </div>
    <script>
        var vm=new Vue({
            el:'#box',
            data:{
                a:1,
                b:2
            }
        });
    </script>
vm.$el.style.background='red';

对vue的实例vm挂载目标进行背景变红操作
.$el表示实例挂载的目标

console.log(vm.$data.a);

在控制台打印出vue实例vm的数据对象data的属性a
.$data表示数据对象

var vm=new Vue({
            data:{
                a:1,
                b:2
            }
        }).$mount('#box');

如果实例化时没有挂载目标,可以在实例化之后再挂载
vm.$mount('选择器')挂载目标元素

var vm=new Vue({
            aa:11, //自定义属性,
            show:function(){
                alert(1);
            },
            data:{
                a:1
            }
        }).$mount('#box');

        vm.$options.show();
        console.log(vm.$options.aa);

数据除了放在data对象里,还可以放在自定义的属性里,不过自定义属性都在options对象里
vm.$options.aa表示自定义属性对象options的aa属性

vm.$log();

是console.log(vm)的一个便捷方式
会打印出vue的实例对象

计算属性的用法
<div id="box">
        a => {{a}}
        <br>
        b => {{b}}
    </div>
    <script>
        var vm=new Vue({
            el:'#box',
            data:{
                a:1
            },
            computed:{
                b:function(){
                    //业务逻辑代码
                    return this.a+1;
                }
            }
        });
        document.onclick=function(){
            vm.a=101;
        };
    </script>

在点击页面之后,a的值被重新赋值,b则是跟a的值有关联会跟着变动
计算属性一般用来处理业务逻辑的
所以监听数据a,数据b随着a的变化而变化

<div id="box">
        a => {{a}}
        <br>
        b => {{b}}
    </div>
    <script>
        var vm=new Vue({
            el:'#box',
            data:{a:1 },
            computed:{
                b:{  get:function(){ return this.a+2; }, set:function(val){ this.a=val; }  }
            }
        });
        document.onclick=function(){
            vm.b=10;
        };

监听数据b,数据a随着b的变化而变化
计算属性computed的b属性值是对象,get属性用于取值,set属性用于赋值

监听数据变化
            var vm=new Vue({
                el:'#box',
                data:{ a:111, b:2 }
            });
            vm.$watch('a',function(){
                alert('发生变化了');
                this.b=this.a+100;                
            });
            document.onclick=function(){vm.a=1; };

当点击页面时,data数据对象里的a属性值被重新赋值,由于监听了a属性,则a的值变化之后,b的值也随之改变
vm.$watch属性方法用来监听data数据对象里的属性

<div id="box">
        {{json | json}}
        <br>
        {{b}}
    </div>
    <script>
            var vm=new Vue({
                el:'#box',
                data:{
                    json:{name:'strive',age:16},
                    b:2
                }
            });
            vm.$watch('json',function(){
                alert('发生变化了');
            });
            document.onclick=function(){
                vm.json.name='aaa';
            };
    </script>

点击页面之后,data数据对象里json属性对象的name属性值被重新赋值,但并没有弹出“发生变化了”的提示框
因为vm.$watch监听的属性是浅度监听

vm.$watch('json',
function(){ alert('发生变化了');},
{deep:true});

.$watch方法的第三个参数是一个对象,用来设置监听程度
{deep:true}表示深度监听
所以点击页面后会弹出“发生变化了”的提示框

如果v-for指令的数组中有重复的成员该怎么办

一般情况下重复成员会被过滤掉,不会显示出来

<div id="box">
        <input type="button" value="添加" @click="add">
        <ul>
            <li v-for="val in arr" track-by="$index">
                {{val}}
            </li>
        </ul>
    </div>
    <script>
        var vm=new Vue({
            data:{  arr:['apple','pear','orange'] },
            methods:{
                add:function(){this.arr.push('tomato'); }
            }
        }).$mount('#box');
    </script>

添加track-by="index”之后使v-for指令可以打印出重复的成员

自定义过滤器
<div id="box">
        {{a | toDou}}
        {{b | toDou}}
    </div>
    <script>
        Vue.filter('toDou',function(input){
            return input<10?'0'+input:''+input;
        });
        var vm=new Vue({
            data:{a:9, b:11 }
        }).$mount('#box');
    </script>

当数据对象的属性小于10,前面加前缀‘0’,否则则不加
Vue.filter()用来自定义过滤器,
第一个参数是过滤器的标识符,第二个参数是处理函数

<div id="box">
        {{a | toDou 1 2}}
</div>
 Vue.filter('toDou',function(input,a,b){
        alert(a+','+b);
        return input<10?'0'+input:''+input;
});

会弹出“1,2”提示框
过滤器后面的1、2作为处理函数的第二参数和第三参数,第一参数是要处理的属性

    <div id="box">
        {{a | date}}
    </div>
    <script>
        Vue.filter('date',function(input){
            var oDate=new Date(input);
            return  oDate.getFullYear()+'-'+
            (oDate.getMonth()+1)+'-'+
            oDate.getDate()+' '+
            oDate.getHours()+':'+ 
            oDate.getMinutes()+':'+
            oDate.getSeconds();
        });
        var vm=new Vue({
            data:{
                a:Date.now()
            }
        }).$mount('#box');
    </script>

2017-8-13 15:29:34
会得到以上格式的一个时间
Date.now()会得到一个时间戳,然后过滤器对这个时间戳进行处理,就变成这种格式

<div id="box">
        <input type="text" v-model="msg | filterHtml">
        <br>
        {{{msg}}}
    </div>
    <script>
        Vue.filter('filterHtml',{
            read:function(input){ //model-view
                return input.replace(/<[^<]+>/g,'');
            },
            write:function(val){ //view -> model
                console.log(val);
                return val;
            }
        });
        window.onload=function(){
            var vm=new Vue({
                data:{
                    msg:'<strong>welcome</strong>'
                }
            }).$mount('#box');
        };
    </script>

带有html标签的内容写入输入框中,会改变data对象中msg属性的值,由于过滤器写入时不会对内容操作,所以msg的值就是写入时的值,但是在使用过滤器的输入框中输出的值被过滤器将html标签替换成空字符,
所以输入框中值的html标签会消失,
而{{msg}}的值则是带有标签的输入框的值

自定义键盘信息
window.onload=function(){
            var vm=new Vue({
                el:'#box',
                data:{  a:'blue' },
                methods:{ show:function(){  alert(1); }  }
            });
        };
<div id="box">
        <input type="text" @keydown.c="show"></div>

当键盘按下c键时触发show,弹出“1”提示框

<input type="text" @keydown.17="show">

ctrl的键码是17,按下ctrl键会弹出“1”的提示框

Vue.directive('on').keyCodes.ctrl=17;
<input type="text" @keydown.ctrl="show">

常用的字母Vue都已经定义好了,
但是ctrl、Alt等按键则没有定义好,
将ctrl的键码17赋值给ctrl这个标识符,
则可以语义化的设置keydown的参数

Vue.directive('on').keyCodes.myenter=13;
<input type="text" @keydown.myenter="show">

按下Enter键,会弹出“1”的提示框
参数名可以自定义

自定义指令
    <script>
        Vue.directive('red',function(){
            this.el.style.background='red';
        });

        window.onload=function(){
            var vm=new Vue({
                el:'#box',
                data:{ msg:'welcome'}
            });
        };
    </script>
    <div id="box">
        <span v-red>
            redBackground
        </span>
    </div>
image.png

使用了v-red指令的标签,背景颜色变成红色
要在自定义的指令标识符前面加上前缀“v-”

<script>
        Vue.directive('red',function(color){
            this.el.style.background=color;
        });
        window.onload=function(){
            var vm=new Vue({
                el:'#box',
                data:{ backgroundColor:'red'}
            });
        };
    </script>
    <div id="box">
        <span v-red="backgroundColor">
            redBackground
        </span>
    </div>

也会显示红色背景的”redBackground”
指令v-red的参数从data数据对象里的backgroundColor属性获取,
自定义指令directive中的函数则将参数传入给
相应元素的样式属性中

        <span v-red="'red'">
            redBackground
        </span>

之间传入字符串参数也可以,需要用单引号' '包裹

<style>
    #box{
        border:1px solid;
        width:300px;
        height:300px;
        margin-top:100px;
        position: relative;;
    }
    </style>
    <script>
        Vue.directive('drag',function(){
            var oDiv=this.el;
            oDiv.onmousedown=function(ev){
                var disX=ev.clientX-oDiv.offsetLeft;
                var disY=ev.clientY-oDiv.offsetTop;
                console.log('ev.clientY',ev.clientY);
                console.log('oDiv.offsetTop',oDiv.offsetTop);
                oDiv.onmousemove=function(ev){
                    var l=ev.clientX-disX;
                    var t=ev.clientY-disY;
                    oDiv.style.left=l+'px';
                    oDiv.style.top=t+'px';
                };
                oDiv.onmouseup=function(){
                    oDiv.onmousemove=null;
                    oDiv.onmouseup=null;
                };
            };
        });
        window.onload=function(){
            var vm=new Vue({
                el:'#box',
                data:{
                    msg:'welcome'
                }
            });
        };
    </script>
    <div id="box">
        <div v-drag :style="{width:'100px', height:'100px', background:'blue', position:'absolute', right:0, top:0}"></div>
        <div v-drag :style="{width:'100px', height:'100px', background:'red', position:'absolute', left:0, top:0}"></div>
    </div>

利用上面的原理,可以做一个拼图

自定义元素指令(标签)
<style>
        zns-red{
            background: gray;
            display: inline;
        }
    </style>
    <script>
        Vue.elementDirective('zns-red',{
            bind:function(){
                this.el.style.background='red';
            }
        });
        window.onload=function(){
            var vm=new Vue({
                el:'#box',
                data:{}
            });
        };
    </script>
    <div id="box">
        <zns-red>red-bakground</zns-red>
   </div>
image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,594评论 18 139
  • 1.安装 可以简单地在页面引入Vue.js作为独立版本,Vue即被注册为全局变量,可以在页面使用了。 如果希望搭建...
    Awey阅读 10,986评论 4 129
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,863评论 6 13
  • 这篇笔记主要包含 Vue 2 不同于 Vue 1 或者特有的内容,还有我对于 Vue 1.0 印象不深的内容。关于...
    云之外阅读 5,044评论 0 29
  • Vue 实例 属性和方法 每个 Vue 实例都会代理其 data 对象里所有的属性:var data = { a:...
    云之外阅读 2,198评论 0 6