vue

2019-05-05  本文已影响0人  致自己_cb38

一、技术栈

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客户端

特点

发送请求的两种方式

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

created

beforeMount

mounted

beforeUpdate

updated

activated

deactivated

beforeDestroy

destroyed

errorCaptured

2.5.0+ 新增

<!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
上一篇下一篇

猜你喜欢

热点阅读