汤小洋Vue全家桶笔记-day02 生命周期和属性和方法以及自定义指令与过渡

作者: 小疯子 分类: Vue 发布时间: 2019-11-10 16:36

Vue.js 五天 汤小洋

一、 发送AJAX请求(01.html)

1. 简介

vue本身不支持发送AJAX请求,需要使用vue-resource、axios等插件实现<font color=red>我是红色</font>
axios是一个基于Promise的HTTP请求客户端,用来发送请求,也是vue2.0官方推荐的,同时不再对vue-resource进行更新和维护

参考:GitHub上搜索axios,查看API文档

2. 使用axios发送AJAX请求

2.1 安装axios并引入

npm install axios -S
也可直接下载axios.min.js文件

2.2 基本用法

axios([options])  
axios.get(url[,options]);
    传参方式:
        1.通过url传参
        2.通过params选项传参
axios.post(url,data,[options]);
    axios默认发送数据时,数据格式是Request Payload,并非我们常用的Form Data格式,
    所以参数必须要以键值对形式传递,不能以json形式传参
    传参方式:
        1.自己拼接为键值对
        2.使用transformRequest,在请求发送前将请求数据进行转换
        3.如果使用模块化开发,可以使用qs模块进行转换

axios本身并不支持发送跨域的请求,没有提供相应的API,作者也暂没计划在axios添加支持发送跨域请求,所以只能使用第三方库

3. 使用vue-resource发送跨域请求

3.1 安装vue-resource并引入

cnpm install vue-resource -S

3.2 基本用法

使用this.$http发送请求  
    this.$http.get(url, [options])
    this.$http.head(url, [options])
    this.$http.delete(url, [options])
    this.$http.jsonp(url, [options])
    this.$http.post(url, [body], [options])
    this.$http.put(url, [body], [options])
    this.$http.patch(url, [body], [options])  

4. 练习(02.html)

百度搜索列表
课后作业:
    1.只显示4条
    2.回车后在新页面中显示搜索结果

二、Vue生命周期(03.html)

vue实例从创建到销毁的过程,称为生命周期,共有八个阶段-https://cn.vuejs.org/v2/api/#%E9%80%89%E9%A1%B9-%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E9%92%A9%E5%AD%90

相关代码

<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>

三、计算属性(04.html)

1. 基本用法

计算属性也是用来存储数据,但具有以下几个特点:
    a.数据可以进行逻辑处理操作
    b.对计算属性中的数据进行监视(针对依赖于的数据进行监视,监视数据改变则计算属性也跟着变更)

`var vm=new Vue({
            el:'#itany',
            data:{ //普通属性
                msg:'welcome to itany',
                num1:8
            },
            computed:{ //计算属性
                msg2:function(){ //该函数必须有返回值,用来获取属性,称为get函数
                    return '欢迎来到南京网博';
                },
                reverseMsg:function(){
                    //可以包含逻辑处理操作,同时reverseMsg依赖于msg
                    return this.msg.split(' ').reverse().join(' ');
                },
            },
            methods:{
                change(){
                     this.msg='i love you'; //这个msg改变,则计算属性reverseMsg值也会改变
                },`
            }}

2.计算属性 vs 方法

将计算属性的get函数定义为一个方法也可以实现类似的功能
区别:
    a.计算属性是基于它的依赖进行更新的,只有在相关依赖发生改变时才能更新变化
    b.计算属性是缓存的,只要相关依赖没有改变,多次访问计算属性得到的值是之前缓存的计算结果,不会多次执行

        var vm=new Vue({
            el:'#itany',
            data:{ //普通属性
                msg:'welcome to itany',
                num1:8
            },
            computed:{ //计算属性
                msg2:function(){ //该函数必须有返回值,用来获取属性,称为get函数
                    return '欢迎来到南京网博';
                },
                reverseMsg:function(){
                    //可以包含逻辑处理操作,同时reverseMsg依赖于msg
                    return this.msg.split(' ').reverse().join(' ');
                },
                num2:function(){ //这个函数就相当于计算属性的get方法获取,获取num2的时候就是get方法即此函数
                        console.log('num2:'+new Date());
                        return this.num1-1;
                }
function fn(){
            setInterval(function(){
                 console.log(vm.num2);
            },1000);
        }

3. get和set

计算属性由两部分组成:get和set,分别用来获取计算属性和设置计算属性
默认只有get,如果需要set,要自己添加,如果不添加,则设置上例中的num2属性不会生效

computed:{ //计算属性
                num2:{
                    get:function(){
                        console.log('num2:'+new Date());
                        return this.num1-1;
                    },
                    set:function(val){
                        // console.log('修改num2值');
                        // this.num2=val;  注释bb
                        this.num1=111;
                    }
                }
            },
            methods:{
                change2(){
                    this.num2=111;
                }
            }

计算属性一般都是有所依赖的,而不是直接赋值,如果没有依赖直接用属性就行了就不用用计算属性了。关于计算属性的set方法,它把值引入进来之后是给所依赖的属性赋值的而不是直接给计算属性赋值的,如果所示注释bb部分是错误的,因为在set方法中设置num2的值就会不停的还是调用set方法,就死循环了。

四、 vue实例的属性和方法(05.html)

1. 属性

vm.$el
vm.$data
vm.$options
vm.$refs

代码示例:


        var vm=new Vue({
            // el:'#itany',
            data:{
                msg:'welcome to itany'
            },
            name:'tom',
            age:24,
            show:function(){
                console.log('show');
            }
        });
        /**
         * 属性
         */
        //vm.属性名 获取data中的属性 是下面vm.$data.msg的简易写法
        // console.log(vm.msg);

        //vm.$el 获取vue实例关联的元素
        // console.log(vm.$el); //DOM对象
        // vm.$el.style.color='red';

        //vm.$data //获取数据对象data
        // console.log(vm.$data);
        // console.log(vm.$data.msg);

        //vm.$options //获取自定义属性 什么是自定义属性,就是直接写在vue实例属性中,非data子属性中的,见上面的vue实例
        // console.log(vm.$options.name);
        // console.log(vm.$options.age);
        // vm.$options.show();

        //vm.$refs 获取所有添加ref属性的元素,注意还是需要获取在el指定的标签中的子元素,取到的就是一个dom对象
        /**html内容:<div id="itany"><h2>你好</h2>世界</div>
        */ 
        // console.log(vm.$refs); 
        // console.log(vm.$refs.hello); //DOM对象 
        // vm.$refs.hello.style.color='blue';

2. 方法

vm.$mount()
vm.$destroy()
vm.$nextTick(callback)

vm.$set(object,key,value)   ____(06.html)
vm.$delete(object,key)
vm.$watch(data,callback[,options])

挂载和销毁和更新相关代码示例05.html:


        /**
         * 方法
         */
        //vm.$mount()  手动挂载vue实例
        // vm.$mount('#itany'); //不在new vue实例中指定el值,在这里制定
        var vm=new Vue({ //边创建完边挂载
            data:{
                msg:'欢迎来到南京网博',
                name:'tom'
            }
        }).$mount('#itany');

        //vm.$destroy() 销毁实例 大多数场景中不应该调用这个方法,最好使用v-if和v-for指令以数据驱动的方式控制子组件的生命周期。
        // vm.$destroy();

        // vm.$nextTick(callback) 在DOM更新完成后再执行回调函数,一般在修改数据之后使用该方法,以便获取更新后的DOM
        /**
        前提准备:
     先在vue实例的data中增加一个name数据值”tom"
     html中:html<h1 ref="title">{{name}}</h1>
     */ 
     //修改数据 vm.name='汤姆'; //DOM还没更新完,Vue实现响应式并不是数据发生改变之后DOM立即变化,需要按一定的策略进行DOM更新,需要时间!!me:所以获取页面h1dom中的数据还是会打印原数据tom,不是汤姆 
     // console.log(vm.$refs.title.textContent); 
     vm.$nextTick(function(){ 
     //DOM更新完成,更新完成后再执行此代码 
     console.log(vm.$refs.title.textContent); });

设置和删除属性set和delete代码示例06.html:

<div id="itany">
<button @click="doUpdate">修改属性</button>
<button @click="doAdd">添加属性</button>
<button @click="doDelete">删除属性</button>
<hr>
<h2>{{user.name}}</h2>
<h2>{{user.age}}</h2>
</div>

var vm=new Vue({ el:'#itany', data:{ user:{ id:1001, name:'tom' } }, methods:{ doUpdate(){ this.user.name='汤姆' }, doAdd(){ // this.user.age=25; //通过普通方式为对象添加属性时vue无法实时监视到,无法及时更新至dom对象中 // this.$set(this.user,'age',18); //通过vue实例的$set方法为对象添加属性,可以实时监视(当然也可以直接改了,这里是添加功能) // Vue.set(this.user,'age',22); if(this.user.age){ this.user.age++; }else{ Vue.set(this.user,'age',1); } // console.log(this.user); }, doDelete(){ if(this.user.age){ // delete this.user.age; //无效 Vue.delete(this.user,'age'); } } } });

$watch使用代码示例07.html:


<div id="itany">
<inputtype="text"v-model="name">
<h3>{{name}}</h3>
<hr>
<inputtype="text"v-model="age">
<h3>{{age}}</h3>
<hr>
<inputtype="text"v-model="user.name">
<h3>{{user.name}}</h3>
</div>
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);// 拿到的user对象是一个地址空间,所以拿到的oldvalue.name的值和新的值是一样的,只是这里深度监视能够触发这个处理方法,关于拿到的值都是新值 }, deep:true //深度监视,当对象中的属性发生变化时也会监视,me:否则只是对象的引用修改了 } } }); //方式1:使用vue实例提供的$watch()方法,没有全局的Vm.watch方法,因为不科学不可能监听所有实例中的name属性值变化 vm.$watch('name',function(newValue,oldValue){ console.log('name被修改啦,原值:'+oldValue+',新值:'+newValue); });

五、自定义指令08.html

分类:全局指令、局部指令
https://cn.vuejs.org/v2/api/#Vue-directive

1. 自定义全局指令

使用全局方法Vue.directive(指令ID,定义对象)    

代码示例:


        /**
         * 自定义全局指令
         * 注:**使用指令时必须在指令名称前加前缀v-,即v-指令名称**
         */
        Vue.directive('hello',{
            bind(){ //常用!!
                alert('指令第一次绑定到元素上时调用,只调用一次,可执行初始化操作');
            },
            inserted(){
                alert('被绑定元素插入到DOM中时调用');
            },
            update(){
                alert('被绑定元素所在模板更新时调用');
            },
            componentUpdated(){
                alert('被绑定元素所在模板完成一次更新周期时调用');
            },
            unbind(){
                alert('指令与元素解绑时调用,只调用一次');
            }
        });
        var vm=new Vue({
            el:'#itany',
            data:{
                msg:'welcome to itany',
                username:'alice'
            },
            methods:{
                change(){
                    this.msg='欢迎来到南京网博' // 模版更新触发update()钩子函数
                }
            },
        });
        在html中使用如下:<h3 v-hello>{{msg}}</h3>
        <button @click="change">更新数据</button>

自定义指令钩子函数赋予了参数,详细见:https://cn.vuejs.org/v2/guide/custom-directive.html


        //钩子函数的参数
        Vue.directive('world',{
            bind(el,binding){
                // console.log(el); //指令所绑定的元素,DOM对象
                // el.style.color='red';

                console.log(binding); //name:world, value:alice(alice是在vue实例中设置的data中的username的值,这个value不是一个实际具体的字符值,而是一个变量名称),expression:username,arg:wbs17022,modifiers:[hehe,haha]
            }
        });
        //传入一个简单的函数,bind和update时调用
        Vue.directive('wbs',function(){
            alert('wbs17022');
        });
        html:
        <h3 v-world:wbs17022.hehe.haha="username">{{msg}}</h3> 其中wbs17022对应了binding中的arg,后面.后面代表了修饰符modifiers

2. 自定义局部指令


var vm=new Vue({
            el:'#itany',
            data:{
                msg:'welcome to itany',
                username:'alice'
            },
            methods:{
                change(){
                    this.msg='欢迎来到南京网博'
                }
            },
            directives:{ //自定义局部指令
                focus:{
                    //当被绑定元素插入到DOM中时获取焦点
                    inserted(el){
                        el.focus();
                    }
                }
            }
        });

html:
        <input type="text" v-model="msg" v-focus>

3. 练习09.html

拖动页面中的元素
onmouseover onmouseout 
onmousedown onmousemove  onmouseup

Vue.directive('drag',function(el){
            el.onmousedown=function(e){
                //获取鼠标点击处分别与div左边和上边的距离:鼠标位置-div位置
                var disX=e.clientX-el.offsetLeft;
                var disY=e.clientY-el.offsetTop;
                // console.log(disX,disY);

                //包含在onmousedown里面,表示点击后才移动,为防止鼠标移出div,使用document.onmousemove;如果使用el.onmousemove的话,就仅仅针对在此div上的鼠标拖动事件操作,而鼠标如果移出此div,那么仍然拖动但是没有定义在外面拖动的事件,所以这里采用document.mousemove只要在文档内拖动即可
                document.onmousemove=function(e){
                    //获取移动后div的位置:鼠标位置-disX/disY
                    var l=e.clientX-disX;
                    var t=e.clientY-disY;
                    el.style.left=l+'px';
                    el.style.top=t+'px';
                }

                //停止移动
                document.onmouseup=function(e){
                    document.onmousemove=null;
                    document.onmouseup=null;
                }

            }
        });

        var vm=new Vue({
            el:'#itany',
            data:{
                msg:'welcome to itany',
                username:'alice'
            },
            methods:{
                change(){
                    this.msg='欢迎来到南京网博'
                }
            }
        });

#itany div{
            width: 100px;
            height: 100px;
            position:absolute;
        }
        #itany .hello{
            background-color:red;
            top:0;
            left:0;
        }
        #itany .world{
            background-color:blue;
            top:0;
            right:0;
        }

<div id="itany">
<divclass="hello"v-drag>itany</div>
<divclass="world"v-drag>网博</div>
</div>

六、过渡(动画)_10.html

1. 简介

Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果
本质上还是使用CSS3动画:transition、animation

2. 基本用法

使用transition组件,将要执行动画的元素包含在该组件内 me:注意必须给这个组件起一个名字name="fade"随便起
    <transition>
        运动的元素
    </transition>       
过滤的CSS类名:6个

代码示例:


        p{ /*不可以用#itanty p,可能内部解析不是这种嵌套解析的dom*/
            width: 300px;
            height: 300px;
            background-color:red;
        }
        .fade-enter-active,.fade-leave-active{ /* 进入和离开时候应用的动画效果,其中fade对应于transaction的name属性值,不设置就是文档中的.v-enter-active*/
            transition:all 3s ease; /*css3动画设置 https://cn.vuejs.org/v2/guide/transitions.html*/
        }
        .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{ /*定义进入动画的初始状态,如果不设置进入动画的过渡就可能是从透明度1到1了*/
            opacity:0;
            width: 100px;
            height: 100px;
        }
html:
<div id="itany">
<button @click="flag=!flag">点我</button>
<transition name="fade">
<p v-show="flag">网博</p>
</transition>
</div>

javascript:
var vm=new Vue({
            el:'#itany',
            data:{
                flag:false
            },
        });

3. 钩子函数

8个  动画进入之前、进入、进入以后等执行的钩子函数https://cn.vuejs.org/v2/guide/transitions.html#JavaScript-钩子

html:
<transition name="fade"
@before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter"
@before-leave="beforeLeave"
@leave="leave"
@after-leave="afterLeave">
<p v-show="flag">网博</p>
</transition>

javascript:
var vm=new Vue({
            el:'#itany',
            data:{
                flag:false
            },
            methods:{
                beforeEnter(el){
                    // alert('动画进入之前');
                },
                enter(){
                    // alert('动画进入');
                },
                afterEnter(el){
                    // alert('动画进入之后'); e表示运动的元素
                    el.style.background='blue';
                },
                beforeLeave(){
                    // alert('动画即将之前');
                },
                leave(){
                    // alert('动画离开');
                },
                afterLeave(el){
                    // alert('动画离开之后');
                    el.style.background='red';
                }
            }
        });

4. 结合第三方动画库animate..css一起使用_11.html

cmd中执行bower info animate.css进行下载animate库,拷贝到项目下的css文件夹中,或者直接网站上下载:https://daneden.github.io/animate.css/
项目中引入这个库,然后代码使用如下:

<transition enter-active-class="animated fadeInLeft" leave-active-class="animated fadeOutRight">
    <p v-show="flag">网博</p>
</transition>    

不需要设置name属性值了,注意要使用animate需要有基础样式animated

5. 多元素动画_13.html

<transition-group>    
示例:注意一定要设置key属性来进行区分,否则不生效
<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>

6. 练习

多元素动画   仅显示输入框包含的元素 

<div id="itany">
<inputtype="text"v-model="name">
<transition-groupenter-active-class="animated bounceInLeft"leave-active-class="animated bounceOutRight">
<pv-for="(v,k) in arr2":key="k">
{{v}}
</p>
</transition-group>
</div>

var vm=new Vue({
            el:'#itany',
            data:{
                flag:true,
                arr:['tom','jack','mike','alice','alex','mark'],
                name:''
            },
            computed:{
                arr2:function(){
                    var temp=[];
                    this.arr.forEach(val => {
                        if(val.includes(this.name)){
                            temp.push(val);
                        }
                    });
                    return temp;
                }
            }
        });
0

发表评论

电子邮件地址不会被公开。 必填项已用*标注