vue

作者: 致自己_cb38 | 来源:发表于2019-05-05 17:51 被阅读0次

    一、技术栈

    image.png

    二、参考文献

    三、引入

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <style type="text/css">
                [v-cloak]{
                    display:none;
                }
            </style>
            
            <!-- 2. 使用CDN -->
            <!-- <script src="https://cdn.jsdelivr.net/npm/vue"></script> -->
            
            <!-- 3. npm加载 npm i vue -->
        </head>
        <body>
            <div id="app" v-cloak>
                <h1>{{ msg }}</h1>
                状态码是:<span>{{ code }}</span>
            </div>
            <!-- 1. 直接下载源码,使用script标签引入 -->
            <script src="vue.js"></script>
            <script type="text/javascript">
                new Vue({
                    el:'#app',  //element 挂载在DOM节点上
                    data:{
                        msg:"欢迎学习VUE",
                        code:"200"
                    }
                });
            </script>
        </body>
    </html>
    

    四、常用指令

    1、v-bind(简写为:)

    动态地绑定一个或多个特性,或一个组件 prop 到表达式

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <style>
                .bg-color-red{
                    background: red;
                }
                .color-white{
                    color:#fff;
                }
                .color-blue{
                    color:blue;
                }
            </style>
        </head>
        <body>
            <div id="app">
                <span :class="cla" :style="style">这里是文字</span>
            </div>
            <script src="vue.js" type="text/javascript"  charset="utf-8"></script>
            <script type="text/javascript">
                new Vue({
                    el:"#app",
                    data:{
                        cla:{
                            "bg-color-red":true,
                            "color-white":true
                        },
                        style:{
                            background:"yellow",
                            color:"lightgreen"
                        }
                    }
                })
            </script>
        </body>
    </html>
    

    2、v-on(简写为:@)

    绑定事件监听器。事件类型由参数指定。表达式可以是一个方法的名字或一个内联语句,如果没有修饰符也可以省略。

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
            <title></title>
        </head>
        <body>
            <div id="app">
                <input type="button" value="点击" v-on:click="sayhello">
            </div>
            <script src="vue.js" type="text/javascript" charset="utf-8"></script>
            <script type="text/javascript">
                new Vue({
                    el:'#app',
                    data:{},
                    methods:{
                        sayhello(){
                            alert('hello')
                        }
                    }
                });
            </script>
            
        </body>
    </html>
    
    

    案例:跑马灯

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
        </head>
        <body>
            <div id="app">
                <input type="button" value="浪起来" @click="lang">
                <input type="button" value="猥琐发育" @click="weisuo">
                <p>{{msg}}</p>
            </div>
        </body>
        <script src="vue.js" type="text/javascript" charset="utf-8"></script>
        <script>
            new Vue({
                el:"#app",
                data:{
                    msg:"猥琐发育,别浪~",
                    timer:null
                },
                methods:{
                    lang(){
                        clearInterval(this.timer);
                        this.timer = setInterval(()=>{
                            this.msg = this.msg.substring(1)+this.msg.substring(0,1);
                        },300)
                        
                    },
                    weisuo(){
                        clearInterval(this.timer);
                    }
                }
            })
        </script>
        
    </html>
    
    

    3、v-model

    在表单控件或者组件上创建双向绑定

    案例:计算器

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title></title>
        <style type="text/css">
            [v-cloak]{
                display: none;
            }
        </style>
    </head>
    <body>
        <div id="app" v-cloak>
            <input type="text" v-model:value="num1">
            <select v-model:value="fuhao">
                <option value ="+" >+</option>
                <option value ="-">-</option>
                <option value ="*">×</option>
                <option value ="/">÷</option>
            </select>
            <input type="text" v-model:value="num2">
            <button @click="cal()">=</button>
            <span v-text="re"></span>
        </div>
        <script src="vue.js"></script>
        <script type="text/javascript">
        new Vue({
            el:"#app",
            data:{
                num1: '',
                num2:'',
                fuhao:'',
                re: ''
            },
            methods:{
                cal:function(){
                    this.re = eval(this.num1 +  this.fuhao + this.num2) ;
                }
            },
            computed:{
                
            }
        });
        </script>
    </body>
    </html>
    

    4、v-for

    遍历

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title></title>
    </head>
    <body>
        <div id="app" v-cloak>
        <ul>
            <li v-for="user in users" :key="user.id"><input type="checkbox">{{user.id}}-----{{user.name}}</li>
        </ul>
        <button @click="del">shanchu</button>
        <!-- <ol>
            <li v-for="(iten,key) in zhangsan">{{iten}}--{{key}}</li>
        </ol> -->
        </div>
        <script src="vue.js"></script>
        <script type="text/javascript">
        new Vue({
            el:"#app",
            data:{
                users:[
                    {id:2,name:'zengke'},
                    {id:3,name:'zhangzhen'},
                    {id:4,name:'lihaoshuahg'},
                    {id:7,name:'xiongli'},
                    {id:9,name:'yanhe'}
                ],
                zhangsan:{
                    age:19,
                    sex:"man",
                    grade:'大三年级'
                },
                
            },
            methods:{
                del(){
                    this.users.shift()
                }
            }
        });
        </script>
    </body>
    </html>
    

    五、filter

    过滤器

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title></title>
    </head>
    <body>
        <div id="app" v-cloak>
            <p>{{ msg | change('--') | dada('**') }}</p>
        </div>
        <div id="dapp">
            {{msg | dada('xixi')}}
        </div>
        <script src="js/vue.js"></script>
        <script type="text/javascript">
            
            //全局过滤器.任何一个Vue节点都可以使用
            Vue.filter('change',function(data,arg){
                return data.replace(/天真/g,arg);
            });
            Vue.filter('dada',function(data,arg){
                return data.replace(/我/g,arg);
            });
        new Vue({
            el:"#app",
            data:{
                msg:"天真的我对天真的自己说,我是这个世界上最天真的人呢!"
            },
            // 局部过滤器
            filters:{
                dada:function(data,arg){
                    return data.replace(/我/g,arg)+'--------------------';  //就近原则
                }
            }
        });
        
        new Vue({
            el:"#dapp",
            data:{
                msg:"快乐的池塘里我有一只快乐的我小青蛙"
            }
        })
        </script>
    </body>
    </html>
    

    六、键盘事件

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title></title>
    </head>
    <body>
        <div id="app" v-cloak>
            <input type="text" @keyup.82="print">
            {{ msg }}
        </div>
        <script src="js/vue.js"></script>
        <script type="text/javascript">
        //自定义键盘事件修饰符
        // Vue.config.keyCodes.add = 82;
        new Vue({
            el:"#app",
            data:{
                msg:''
            },
            methods:{
                print(event){
                    this.msg = event.target.value;
                }
            }
        });
        </script>
    </body>
    </html>
    

    七、自定义指令

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title></title>
    </head>
    <body>
        
        <form action="" id="app">
            用户名<input type="text" id="user" v-focus><br><br>
            <!-- 使用自定义的指令必须要添加v-前缀 vue指令的规范是所有的指令都是以v-前缀开始的 -->
            密码<input type="text"><br><br>
            <input type="submit">
        </form>
        
    </body>
    <script src="../day1/vue.js" type="text/javascript" charset="utf-8"></script>
    <script>
        /*
        window.onload = function(){
            document.getElementById('user').focus();
        }
        */
        //扩展VUE指令,自定义指令
        //全局的
        //参数一:指令的名称,注意这里的指令的名称是定义的时候,不需要添加v-前缀
        //参数二:是一个指令的配置对象
        Vue.directive('focus',{
            //配置项,钩子函数
            //第一个参数,指令操作的节点
            bind:function(el){ 
                //指令在第一次调用的时候出发,VUE的虚拟dom在进行渲染的时候触发.这个时候节点还没有进入真实dom
            },
            inserted:function(el){
                //在虚拟dom进去到真实dom的时候调用
                el.focus();
    
            },
            update:function(el){
                //在节点更新的时候使用
            }
        });
        new Vue({
            el:"#app",
            data:{
            }
        });
    </script>
    </html>
    

    八、自定义有值指令

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title></title>
    </head>
    <body>
        <div id="app" v-cloak>
            <p v-fontsize:style="'20px'" >要经常给妈妈点钱,让妈妈去挥霍吧!</p>
        </div>
        <script src="../day1/vue.js"></script>
        <script type="text/javascript">
        Vue.directive('fontsize',{
            bind:function(el,binding){
                // binding.arg 元素的键(style)
                el[binding.arg].fontSize = binding.value; 
                console.log(binding)
            },
            inserted:function(){},
            update:function(){}
        })
        Vue.directive('name',function(el,song){
            // el.操作
        })
        new Vue({
            el:"#app",
            data:{
            }
        });
        </script>
    </body>
    </html>
    

    九、自定义指令对象传参

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <style>
                div>div{
                    width:20px;
                    height:20px;
                    background: #2AC845;
                }
                .show{
                    border: 1px dashed #007AFF;
                }
                .size{
                    width:200px;
                    height: 200px;
                }
            </style>
        </head>
        <body>
            <div id="app" v-cloak>
                <div v-bind:class="style" v-style:style="{'font-size':'20px',background:'red'}">
                    lalalala
                </div>
            </div>
            <script src="../day1/vue.js"></script>
            <script type="text/javascript">
            Vue.directive('style',function(el,bin){
                for(let i in bin.value){
                    el.style[i] = bin.value[i];
                }
            })
            new Vue({
                el:"#app",
                data:{
                    style:{
                        show: true,
                        size:true
                    }
                }
            });
            </script>
        </body>
    </html>
    
    

    十、局部定义

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
        </head>
        <body>
            <div id="app" v-cloak>
                <!-- <input type="text" v-focus> -->
            </div>
            
            <footer id="dapp">
                <input type="text" v-focus>
            </footer>
            <script src="../day1/vue.js"></script>
            <script type="text/javascript">
            /*
            Vue.directive('focus',{
                bind:function(){},
                inserted:function(el){
                    el.focus();
                },
                update:function(){}
            })
            */
            new Vue({
                el:"#app",
                data:{
                },
                directives:{
                    focus:{
                        bind:function(){},
                        inserted:function(el){
                            el.focus();
                        },
                        update:function(){}
                    }
                }
            });
            new Vue({
                el:"#dapp",
                data:{
                }
            });
            </script>
        </body>
    </html>
    
    

    十一、vue-resource

    网络请求

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title></title>
        <style>
            ul{
                list-style: none;
            }
            ul li {
                width:100px;
                height:150px;
                border:1px solid #ccc;
                margin: 20px;
            }
            ul li img{
                width:100%;
            }
        </style>
    </head>
    <body>
        <div id="app" v-cloak>
            <ul>
                <li v-for="user in list">
                <img v-bind:src="user.avatar_url" alt="user.login">
                {{user.login}}
                </li>
            </ul>
        </div>
        <script src="../day1/vue.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/vue-resource@1.5.1"></script>
        <script type="text/javascript">
        new Vue({
            el:"#app",
            data:{
                list:[]
            },
            created:function(){
                this.$http.get('https://api.github.com/users').then(function(response){
                    this.list = response.body;
                },function(){
                    
                });
            }
            
        });
        </script>
    </body>
    </html>
    

    十二、axios

    基于promise用于浏览器和node.js的http客户端

    特点

    • 支持浏览器和node.js
    • 支持promise
    • 能拦截请求和响应
    • 能转换请求和响应数据
    • 能取消请求
    • 自动转换JSON数据
    • 浏览器端支持防止CSRF(跨站请求伪造)

    发送请求的两种方式

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title></title>
    </head>
    <body>
        <div id="app" v-cloak>
            <input type="button" value="获取" @click="getlist">
            <ul>
                <li v-for="item in list" :key="item.id">item.name</li>
            </ul>
        </div>
        <script src="../day1/vue.js"></script>
        <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
        <script type="text/javascript">
        new Vue({
            el:"#app",
            data:{
                list:[]
            },
            methods:{
                getlist:function(){
                    axios.get('http://localhost/vue_api/index.php?m=api&a=getlist').then(response=>{
                        this.list = response.data;
                        console.log(this.list);
                    }).catch(error=>{
                        //处理错误
                    })
                }
            },
            
        });
        </script>
    </body>
    </html>
    
    
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
        </head>
        <body>
            <div id="app" v-cloak>
                <input type="text" v-model:value="id">
                <input type="text" v-model:value="name">
                <input type="button" value="提交" @click="add">
            </div>
            <script src="../day1/vue.js"></script>
            <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
            <script type="text/javascript">
            new Vue({
                el:"#app",
                data:{
                    id:"",
                    name:''
                },methods:{
                    add(){
                        // axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
    
                        /*
                        axios.post('http://localhost/vue_api/index.php?m=api&a=addcar',{id:this.id,name:this.name,ctime:new Date().toUTCString()}).then(response=>{
                            console.log(response.data);
                        })
                        */
                       axios({
                           method:'post',
                           url:'http://localhost/vue_api/index.php?m=api&a=addcar',
                           data:{
                              id:this.id,
                              name:this.name,
                              ctime:new Date().toUTCString() 
                           },
                           headers:{
                               'Content-Type':'application/x-www-form-urlencoded'
                           },
                           //在传递post数据的时候如果没有经过这样的处理,那么后端接收数据会非常麻烦.
                           /*
                           transformRequest:[
                               data=>{
                                let params = '';
                                for (var index in data) {
                                    params += index + '=' + data[index] + '&'
                                }
                                return params;
                               }
                           ]
                           */
                       }).then(response=>{
                            console.log(response.data);
                        })
                    }
                }
            });
            
        
            </script>
            
        </body>
    </html>
    
    

    十三、动画

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <style>
                @keyframes boom{
                    0%{
                        transform: scale(0);
                    }
                    50%{
                        transform: scale(1.5);
                    }
                    100%{
                        transform: scale(1);
                    }
                }
                .v-enter-active{
                    animation: boom 1s ease;
                }
                .v-leave-active{
                    animation: boom 1s reverse;
                }
                p{
                    width:200px;
                    height:200px;
                    background: #4CD964;
                }
            </style>
        </head>
        <body>
            <div id="app" v-cloak>
                <button @click="flag=!flag">boom</button>
                <!-- 所有需要进行动画或者过度的元素必须添加在transition标签里面 -->
                <transition>
                    <p v-show="flag">好烦你呀</p>
                </transition>
            </div>
            <script src="../day1/vue.js"></script>
            <script type="text/javascript">
            new Vue({
                el:"#app",
                data:{
                    flag:true
                }
            });
            </script>
        </body>
    </html>
    
    

    十四、使用动画类实现动画

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css">
        </head>
        <body>
            <div id="app" v-cloak>
            <button @click="flag=!flag">animate</button>
            
            <!-- 如果传入的值是一个固定的值,那么这个值表示的是进场与离场动画相同的时间 -->
            <!-- :duration="1000" -->
            <transition name="my"
            enter-active-class="bounceInDown"
            leave-active-class="bounceOutDown"
            :duration="{enter:800,leave:500}"
            >
                <div v-show="flag" class="animated">中午睡觉吃了一只蚊子</div>
            </transition>
            </div>
            <script src="../day1/vue.js"></script>
            <script type="text/javascript">
            new Vue({
                el:"#app",
                data:{
                    flag:false
                }
            });
            </script>
        </body>
    </html>
    
    

    十五、钩子函数实现动画效果

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title></title>
        <style>
            #app div{
                width:50px;
                height:50px;
                background: cyan;
                border-radius: 50%;
            }
        </style>
    </head>
    <body>
        <div id="app" v-cloak>
            <button @click="flag=!flag">动画</button>
            <transition
            @before-enter="before"
            @enter="enter"
            @after-enter="after"
            >
                <div v-show="flag"></div>
            </transition>
        </div>
        <script src="../day1/vue.js"></script>
        <script type="text/javascript">
        new Vue({
            el:"#app",
            data:{
                flag:false
            },
            methods:{
                // el表示要操作的DOM对象
                before(el){
                    el.style.transform = 'translate(0,0)';
                },
                enter(el,done){
                    el.offsetWidth ;
                    // 需要使用offset系列实现动画的刷新或者平滑过渡
                    el.style.transform = 'translate(350px,150px)';
                    el.style.transition = 'all .3s ease';
                    done(); //down回调函数就是指下面after函数
                },
                after(el){
                    this.flag= !this.flag;
                }
            }
        });
        </script>
    </body>
    </html>
    

    十六、列表过渡

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title></title>
        <style>
            li{
                line-height: 50px;
                padding:5px;
                border:1px dashed #333;
                margin-bottom: 10px;
                text-indent: 1em;
                width:100%
            }
            li:hover{
                background: lightseagreen;
                transition: all 0.3s ease;
            }
            input {
                margin-left:40px;
                height:60px;
                width:200px;
                font-size: 20px;
                text-indent: 20px;
            }
            .my-enter,
            .my-leave-to{
                transform: translateY(200px);
                opacity: 0;
            }
            
            .my-enter-active,
            .my-leave-active{
                transition: all 1s ease-in-out;
            }
            .my-move{
                transition : all 1s ;
            }
            .my-leave-active {
                position: absolute;
            }
        </style>
    </head>
    <body>
        <div id="app" v-cloak>
            <input type="text" v-model:value="id">
            <input type="text" v-model:value="name">
            <input type="button" value="添加" @click="add">
            <transition-group name="my" tag="ul" appear >
                <li v-for="(item,index) in list" :key="item.id" @click="del(index)">{{item.id}}. {{item.name}}</li>
            </transition-group>
        </div>
        <script src="../day1/vue.js"></script>
        <script type="text/javascript">
        new Vue({
            el:"#app",
            data:{
                id:'',
                name:'',
                list:[
                    {id:1,name:'魏忠贤'},
                    {id:3,name:'赵高'},
                    {id:4,name:'曹正淳'},
                    {id:6,name:'李公公'},
                ]
            },
            methods:{
                add(){
                    this.list.push({id:this.id,name:this.name});
                    this.id = this.name = '';
                },
                del(i){
                    this.list.splice(i,1);
                }
            }
        });
        </script>
    </body>
    </html>
    

    十七、生命周期函数

    参考文献:https://segmentfault.com/a/1190000011381906

    Vue生命周期中mounted和created的区别

    beforeCreate

    • 类型Function

    • 详细

      在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。

    • 参考生命周期图示

    created

    • 类型Function

    • 详细

      在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。

    • 参考生命周期图示

    beforeMount

    • 类型Function

    • 详细

      在挂载开始之前被调用:相关的 render 函数首次被调用。

      该钩子在服务器端渲染期间不被调用。

    • 参考生命周期图示

    mounted

    • 类型Function

    • 详细

      el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。

      注意 mounted 不会承诺所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以用 vm.$nextTick 替换掉 mounted

      mounted: function () {
        this.$nextTick(function () {
          // Code that will run only after the
          // entire view has been rendered
        })
      }
      

      该钩子在服务器端渲染期间不被调用。

    • 参考生命周期图示

    beforeUpdate

    • 类型Function

    • 详细

      数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。

      该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行。

    • 参考生命周期图示

    updated

    • 类型Function

    • 详细

      由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。

      当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性watcher 取而代之。

      注意 updated 不会承诺所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕,可以用 vm.$nextTick 替换掉 updated

      updated: function () {
        this.$nextTick(function () {
          // Code that will run only after the
          // entire view has been re-rendered
        })
      }
      

      该钩子在服务器端渲染期间不被调用。

    • 参考生命周期图示

    activated

    deactivated

    beforeDestroy

    • 类型Function

    • 详细

      实例销毁之前调用。在这一步,实例仍然完全可用。

      该钩子在服务器端渲染期间不被调用。

    • 参考生命周期图示

    destroyed

    • 类型Function

    • 详细

      Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

      该钩子在服务器端渲染期间不被调用。

    errorCaptured

    2.5.0+ 新增

    • 类型(err: Error, vm: Component, info: string) => ?boolean

    • 详细

      当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false以阻止该错误继续向上传播。

      你可以在此钩子中修改组件的状态。因此在模板或渲染函数中设置其它内容的短路条件非常重要,它可以防止当一个错误被捕获时该组件进入一个无限的渲染循环。

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
        </head>
        <body>
            <div id="app" v-cloak>
                <button @click="msg='还好吧'">改变</button>
            {{msg}}
            </div>
            <script src="../day1/vue.js"></script>
            <script type="text/javascript">
            new Vue({
                el:"#app",
                data:{
                    msg:'今天真是个好日子呀'
                },
                methods:{},
                computed:{},
                filters:{},
                directives:{},
                components:{}, //组件
                
                beforeCreate:function(){
                    alert('beforeCreate');
                },
                created:function(){
                    alert('created');
    
                },
                beforeMount:function(){
                    alert('beforeMount');
    
                },
                mouted:function(){
                    alert('mouted');
    
                },
                beforeUpdate:function(){
                    alert('beforeUpdate');
    
                },
                updated:function(){
                    alert('updated');
    
                },
                beforeDestroy:function(){
                    alert('beforeDestroy');
    
                },
                destroyed:function(){
                    alert('destroyed');
    
                } 
            });
            </script>
        </body>
    </html>
    
    

    十八、创建组建的方式

    //法一
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
        </head>
        <body>
            <div id="app" v-cloak>
            <!-- //全局组件可以使用在任何一个VUE所挂载的DOM上。 -->
                <!-- //使用的组件的方式是将组建用于类似于HTML的结构,按照HTML双标签的格式书写 -->
                <mycom></mycom>
            </div>
            <script src="../day1/vue.js"></script>
            <script type="text/javascript">
                /*
            //创建组件对象
            var com= Vue.extend({
                template:'<h3>这里是组件在内容</h3>'
            });
            //注册组件
            //参数1是组件的名称,使用组件的时候要使用这个名称
            //参数2是组件的对象
            Vue.component('mycom',com);
            */
            Vue.component('mycom',Vue.extend({
                template:'<h3>也行</h3>'
            }))
            new Vue({
                el:"#app",
                data:{
                }
            });
            </script>
        </body>
    </html>
    
    
    
    //法二
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
        </head>
        <body>
            <div id="app" v-cloak>
                <my-com></my-com>
            </div>
            <script src="../day1/vue.js"></script>
            <script type="text/javascript">
                
            //组件的名称可以是驼峰法命名,但是在使用的时候要替换成以中划线分隔的形式
            Vue.component('my-com',{
                template:'<h3>这里是组件模板</h3>'
            });
            new Vue({
                el:"#app",
                data:{
                }
            });
            </script>
        </body>
    </html>
    
    
    
    //法三
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
        </head>
        <body>
            <div id="app" v-cloak>
                <mycom></mycom>
            </div>
            
            <!-- //需注意模板必须是放置在挂载节点之外。 -->
            <!-- 使用id作为组件的标识 -->
            <!-- 组件的模板只允许具有一个根节点 -->
            <template id="tl">
                <div>
                    <h3>这里是组件</h3>
                    <div>lalalal</div>
                </div>
            </template>
            <script src="../day1/vue.js"></script>
            <script type="text/javascript">
            Vue.component('mycom',{
                template: '#tl' 
            })
            new Vue({
                el:"#app",
                data:{
                }
            });
            </script>
        </body>
    </html>
    
    
    //法四
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
        </head>
        <body>
            <div id="app" v-cloak>
                <mycom></mycom>
            </div>
            <!-- 每一个组件都是一个VUE的实例 -->
            <script id="el" type="x-template">
                <div>这里是组件内容</div>
            </script>
            <script src="../day1/vue.js"></script>
            <script type="text/javascript">
            
            Vue.component('mycom',{
                template:"#el",
                //组件的数据必须是一个函授,而且这个函数必须返回的是一个对象,而且这个对象必须是内置定义的对象
                data:function(){
                    return {};
                }
            })
            new Vue({
                el:"#app",
                data:{
                }
            });
            </script>
        </body>
    </html>
    
    

    案例:组件计算器

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
        </head>
        <body>
            <div id="app" v-cloak>
                <mycom></mycom>
                <mycom></mycom>
                <mycom></mycom>
                <mycom></mycom>
                <mycom></mycom>
            </div>
            <div id="dapp">
                <mycom></mycom>
            </div>
            <template id="el">
                <div>
                    <button @click="add">+1</button>
                    {{count}}
                </div>
            </template>
            <script src="../day1/vue.js"></script>
            <script type="text/javascript">
            Vue.component('mycom',{
                template:'#el',
                data:function(){
                    //每一次返回的是一个新的对象,不同的组件之间是不会相互影响的
                    return {
                        count:0
                    };
                },
                methods:{
                    add(){
                        this.count++;
                    }
                }
            })
            new Vue({
                el:"#app",
                data:{
                }
            });
            new Vue({
                el:'#dapp'
            })
            </script>
        </body>
    </html>
    
    

    十九、私有组件

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
        </head>
        <body>
            <div id="app" v-cloak>
                <mycom></mycom>
            </div>
            <div id="dapp">
                <mycom></mycom>
            </div>
            <template id="cc">
                <div>
                    这里是私有组件
                </div>
            </template>
            <script src="../day1/vue.js"></script>
            <script type="text/javascript">
            new Vue({
                el:"#app",
                data:{
                },
                components:{
                    mycom:{
                        template:"#cc"
                    }
                }
            });
            new Vue({
                el:"#dapp"
            })
            </script>
        </body>
    </html>
    
    

    二十、组件切换

    //法一:v-if
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
        </head>
        <body>
            
            <div id="app" v-cloak>
                <a href="" @click.prevent="flag=true">登录</a>
                <a href="" @click.prevent="flag=false">注册</a>
                <login v-if="flag"></login>
                <register v-else="flag"></register>
            </div>
            <template id="login">
                <div><h3>这里是登录组件</h3></div>
            </template>
            <template id="register">
                <div>
                    <h3>这里是注册组件</h3>
                </div>
            </template>
            <script src="../day1/vue.js"></script>
            <script type="text/javascript">
            new Vue({
                el:"#app",
                data:{
                    flag:false
                },
                components:{
                    login:{
                        template:"#login"
                    },
                    register:{
                        template:"#register"
                    }
                }
            });
            </script>
        </body>
    </html>
    
    
    
    //法二:components
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <style>
                h3{
                    width:80%;
                    height:300px;
                    background: lightgreen;
                    margin:80px auto;
                }
                .my-animate-enter,
                .my-animate-leave-to{
                    opacity: 0;
                    transform: translateX(50px);
                }
                
                .my-animate-enter-active,
                .my-animate-leave-active{
                    transition: all 1s ease;
                }
            </style>
        </head>
        <body>
            <div id="app" v-cloak>
                <a href="" @click.prevent="com='login'">登录</a>
                <a href="" @click.prevent="com='register'">注册</a>
                <transition name="my-animate" mode="out-in">
                    <component :is="com"></component>
                </transition>
                <!-- component  组件切换-->
                <!-- trasnition 过度动画-->
                <!-- transition-group 列表的过度动画-->
                <!-- template 组件的模板-->
            </div>
            <script src="../day1/vue.js"></script>
            <script type="text/javascript">
            new Vue({
                el:"#app",
                data:{
                    com:'login'
                },
                components:{
                    login:{
                        template:'<h3>这是登录组件</h3>'
                    },
                    register:{
                        template:'<h3>这是注册组件</h3>'
                    }
                }
            });
            </script>
        </body>
    </html>
    
    

    二十一、组件传值

    //父组件向子组件传值
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
        </head>
        <body>
            <div id="app" v-cloak>
                父组件向子组件传值,使用数据绑定的方式传递。:后面的值必须在组建中使用pros接收。否则在子组件中没有办法获取到父组件通过这种方式传过来的值
                <mycom :pmsg="parentmsg" ></mycom>
            </div>
            <template id="el">
                <div>
                    <h2>这里是我创建的组件:{{msg}}-{{pmsg}}</h2>
                </div>
            </template>
            <script src="../day1/vue.js"></script>
            <script type="text/javascript">
            new Vue({
                el:"#app",
                data:{
                    parentmsg:'古道西风瘦马'
                },
                components:{
                    mycom:{
                        template:'#el',
                        data(){
                            return {
                                msg:'风吹草低见牛羊',
                            }
                        },
                        methods:{
                            
                        },
                        //这里使用pros接受的数据的名称与组件传递的时候绑定的名称是一模一样的
                        props:['pmsg']
                    }
                },
            });
            </script>
        </body>
    </html>
    
    
    
    
    //父组件向子组件传递方法
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
        </head>
        <body>
            <div id="app" v-cloak>
                {{conso('不怕热')}}
                对于方法来说,传递到子组件要是用事件绑定的形式
                <mycom v-on:func="conso"></mycom>
            </div>
            <template id="el">
                <button @click="tirrger">点击触发父组件的conso方法</button>
            </template>
            <script src="../day1/vue.js"></script>
            <script type="text/javascript">
            new Vue({
                el:"#app",
                data:{
                },
                methods:{
                    conso(i){
                        console.log('30度的日子就要来临了---'+i)
                    }
                },
                components:{
                    mycom:{
                        template:'#el',
                        data:function(){
                            return {};
                        },
                        props:[],
                        methods:{
                            tirrger(){
                                //对于父组件传递的方法而言,其实并不是将这个方法传递给子组件,而是要求子组件将这个方法进行触发.
                                //$emit 函数触发的函数如果是需要传递参数,那么按照参数的顺序从第二个参数开始进行传递
                                this.$emit('func','不怕辣');
                            }
                        }
                    }
                }
            });
            </script>
        </body>
    </html>
    
    
    
    //子组件向父组件传递方法
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
        </head>
        <body>
            <div id="app" v-cloak>
                {{conso('不怕热')}}
                对于方法来说,传递到子组件要是用事件绑定的形式
                <mycom v-on:func="conso"></mycom>
            </div>
            <template id="el">
                <button @click="tirrger">点击触发父组件的conso方法</button>
            </template>
            <script src="../day1/vue.js"></script>
            <script type="text/javascript">
            new Vue({
                el:"#app",
                data:{
                    msg:''
                },
                methods:{
                    conso(i){
                        this.msg = i;
                    }
                },
                components:{
                    mycom:{
                        template:'#el',
                        data:function(){
                            return {
                                msg:'僵小鱼'
                            };
                        },
                        props:[],
                        methods:{
                            tirrger(){
                                //对于父组件传递的方法而言,其实并不是将这个方法传递给子组件,而是要求子组件将这个方法进行触发.
                                //$emit 函数触发的函数如果是需要传递参数,那么按照参数的顺序从第二个参数开始进行传递
                                this.$emit('func',this.msg);
                            }
                        }
                    }
                }
            });
            </script>
        </body>
    </html>
    
    

    案例:列表评论

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
             <link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet">
        </head>
        <body>
            <div id="app" v-cloak>
                <discuss @func="flash"></discuss>
                <ul class="list-group">
                  <li class="list-group-item" v-for="item in list" :key="item.id">
                    <span class="badge">{{item.name}}</span>
                    {{item.content}}
                  </li>
                </ul>
            </div>
            <template id="el">
                <form action="">
                    <div class="form-group">
                        <label for="author">作者</label>
                        <input type="text" class="form-control" id="author" v-model:value="author">
                    </div>
                    <div class="form-group">
                        <label for="content">内容</label>
                        <textarea  id="content" class="form-control" v-model:value="content"></textarea>
                    </div>
                    <div class="form-group">
                        <input type="button" class="form-control btn-primary" value="发表" @click="add">
                    </div>
                </form>
            </template>
            <script src="../day1/vue.js"></script>
            <script type="text/javascript">
            new Vue({
                el:"#app",
                data:{
                    list:[]
                },
                methods:{
                    flash(){
                        this.list = JSON.parse(localStorage.getItem('discuss-list') || '[]');
                    }
                },
                components:{
                    discuss:{
                        template:'#el',
                        data(){
                            return {
                                author:'',
                                content:''
                            };
                        },
                        methods:{
                            add(){
                                let list = JSON.parse(localStorage.getItem('discuss-list') || '[]');
                                list.push({id:Math.random(100),name:this.author,content:this.content});
                                localStorage.setItem('discuss-list',JSON.stringify(list));
                                this.author=this.content = '';
                                this.$emit('func');
                            }
                        }
                    }
                },
                created:function(){
                    this.flash();
                }
            });
            </script>
        </body>
    </html>
    
    

    二十二、插槽

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title></title>
    </head>
    <body>
    <div id="app" v-cloak>
        <com>
            <!-- 插槽机制也能够帮助我们实现数据的传递,只是这种传递是停留在视图层的,并没有进入到代码层 -->
            here is the best place!---{{pm}}
        </com>
    </div>
    <template id="el">
        <div>
            <h1>这里是组件</h1>
            {{msg}}
            <slot></slot>
        </div>
    </template>
    <script src="../day1/vue.js"></script>
    <script type="text/javascript">
    new Vue({
        el:"#app",
        data:{
            pm:'my name is  pm'
        },
        components:{
            com:{
                template:"#el",
                data(){
                    return {
                        msg:"这是组件数据"
                    };
                }
            }
        }
    });
    </script>
    </body>
    </html>
    

    二十三、路由

    参考文献:https://router.vuejs.org/zh/

    什么是路由?

    • 我们认识的路由

    进入到网站的根目录,然后根据文件夹的名称或者文件名去找到对应的文件,然后运行

    • 后端的路由

    指网络上的某一个资源URL

    后端框架的出现,以及安全性的考虑,后端一般做单一的入口
    例如:http://localhost/vue_api/index.php?m=api&a=getlist

    单一的入口是指在这个入口文件中,通过路由参数的方式(m=api&a=getlist)将请求分发给不同的资源或者文件处理

    • 前端路由

    锚点实现的路由

    前端的路由是不会发生页面的刷新或者页面的重启请求的

    hash值的变化是不会造成页面重新请求的

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            
            <style>
            /* mint-active */
                .router-link-active{
                    background: #00FFFF;
                    color:lightseagreen;
                    font-size: 20px;
                }
                .v-enter,
                .v-leave-to{
                    opacity: 0;
                    transform: translateX(200px);
                }
                .v-enter-active,
                .v-leave-active{
                    transition: all 1s ease;
                }
            </style>
        </head>
        <body>
            <div id="app" v-cloak>
                <!-- 使用router-link的标签实现路由的连接 -->
                <router-link to="/login" tag="span">登录</router-link>
                <router-link to="/register" tag="span">注册</router-link>
                <!-- <router-link to="/guanggai" tag="span">逛街</router-link> -->
                <!-- <a href="#/login">登录</a>
                <a href="#/register">注册</a> -->
                <transition mode="out-in">
                    <router-view></router-view>
                </transition>
            </div>
            <script src="../lib/vue.js"></script>
            <script src="../lib/vue-router.js" type="text/javascript" charset="utf-8"></script>
            <script type="text/javascript">
            const login = {
                        template:`
                        <div>
                        这是登录组件
                        </div>
                        `,
                    };
            const register = {
                        template:`
                        <div>
                        这是注册组件
                        </div>
                        `,
                    }
            
            new Vue({
                el:"#app",
                data:{
                },
                          //不能这样使用
                <!--components:{
                    guanggai:{
                        template:'<div>这是逛街</div>'
                    }
                },-->
                //路由规则
                router: new VueRouter({
                    routes:[
                        //redirect重定向,将符合规则的路由发送到指定的路由
                        {path:'/',redirect:'/login'},
                        {path:'/login',component:login},
                        {path:'/register',component:register},
                        // {path:'/guanggai',component:guanggai}
                    ],
                    linkActiveClass:'is_selected'
                })
            
            });
            </script>
        </body>
    </html>
    
    

    二十四、vuex

    参考文献:https://vuex.vuejs.org/zh/

    概念:在多个组件中共享状态(需要多个组件共享的变量全部存储在一个对象里面,然后将这个对象放在顶层的Vue实例中,让其他组件可以使用,并且是响应式)

    适用情况:用户登陆状态、用户名称、头像、地理位置,商品收藏、购物车中的物品等等

    image.png

    相关文章

      网友评论

          本文标题:vue

          本文链接:https://www.haomeiwen.com/subject/pauknqtx.html