• Vue-one


    一:vue指令:

    <div id="app">
       //使用v-cloak,可以解决插值表达式的闪烁问题 ,不会覆盖元素中原有的内容,只会替换自己的占位符
       <p v-cloak>11111{{msg1}}9999</p>
       //没有闪烁问题,但是会覆盖原有的内容 
       <h1 v-text="msg2"></h1>
       //输出html格式,会覆盖元素中原有的内容 
       <h1 v-html="msg2"></h1>
       //v-bind 可以简写为:,绑定属性的指令
       <input type="button" value="按钮" v-bind:title="mytitle">
       <input type="button" value="按钮" :title="mytitle">
       //v-bind会把后面的当作js表达式执行,后面可以写合法的表达式,mytitle变量+表达式 
       <input type="button" value="按钮" :title="mytitle + '123'">
       //v-on:click 绑定事件,相当于onclick
       <input type="button" value="按钮" :title="mytitle + '123'" v-on:click="handle">
       //v-on:缩写为@
       <input type="button" value="按钮" :title="mytitle + '123'" @click="handle">
    </div>

    vue代码:

    var vm = new Vue({
            el: '#app',
            // 数据
            data: {
                msg1: '哈哈哈哈',
                msg2: '<h1>kkkkkk</h1>',
                mytitle: 'title',
            },
            // 对象
            methods: {
                handle: function () {
                    alert("hello");
                }
            }
        });

    例子:跑马灯效果

    substring 来进行字符串的截取,把第一个截取放最后面

    html代码如下:

    <div class="app2">
            <input type="button" value="开始" v-on:click="handle1">
            <input type="button" value="停止" v-on:click="handle2">
            <h4>{{ msg }}</h4>
    </div>

    vue代码如下:

    var vm = new Vue({
            el: '.app2',
            data: {
                msg: '这是一个跑马灯效果',
                timer: null,
            },
            methods: {
                // 在vm实例中,要获取data的数据,或者是methods的方法,必须要this.属性名数据或this.方法名
                // handle1: function () {
                //     // console.log(this.msg);
                //     var _this=this;
                //     setInterval(function () {
                //         // 获取第一个字符
                //         var start = _this.msg.substring(0, 1);
                //         // 从第一个截取到最后
                //         var end = _this.msg.substring(1);
                //         // 从新拼接,赋值给msg
                //         _this.msg = end + start;
                //     },1000)
                // },
                // handle2: function () {
                // }
                // es6写法,可以省略function,箭头函数可以指向外面的this
                handle1() {
                    if (this.timer != null) {
                        return;
                    }
                    this.timer = setInterval(() => {
                        // 获取第一个字符
                        var start = this.msg.substring(0, 1);
                        // 从第一个截取到最后
                        var end = this.msg.substring(1);
                        // 从新拼接,赋值给msg
                        this.msg = end + start;
                    }, 1000)
                },
                handle2() {
                    clearInterval(this.timer);
                    this.timer = null;
                }
            },
        })
    v-on事件修饰符:
    //<!-- capture捕获事件,从外到里输出 -->
        <div id="app3" @click="divHandle">
            //<!-- .stop阻止冒泡 -->
            <input type="button" value="点1" @click.stop="btnHandle1">
            //<!-- self点击当前元素的时候才会触发当前事件 -->
            <input type="button" value="点2" @click.self="btnHandle2">
            //<!-- prevent阻止默认行为 -->
            <a href="http://www.baidu.com" @click.prevent="linkClick">app</a>
            //<!-- once只执行一次 -->
            <a href="http://www.baidu.com"     @click.prevent.once="linkClick">app</a>
     </div>
    var vm = new Vue({
            el: '#app3',
            data: {},
            methods: {
                divHandle() {alert("这是div的点击事件");},
                btnHandle1() {alert("这是button的点击事件");},
                btnHandle2() {alert("self");},
                linkClick() {alert("Baidu");}
            }
        });

      v-model:数据绑定

    //<!-- v-model双向数据绑定,只能运用于表单元素,radio,text,address,mail,select,CheckBox -->
    <div id="app1">
       <h4>{{msg1}}</h4>
       <input type="text" v-model:value="msg1" style=" 500px;">
    </div>
    var vm = new Vue({
            el: '#app1',
            data: {
                msg1: 'hellodfdfddkfjdfjdfjdkfdkfjdkfjkdfjd',
            },
            methods: {}
        });

    例子:使用v-model实现计算器案例

    <div id="app2">
            <input type="text" name="" id="" v-model="msg1">
            <select v-model="opt">
                <option value="+">+</option>
                <option value="-">-</option>
                <option value="*">*</option>
                <option value="/">/</option>
            </select>
            <input type="text" name="" id="" v-model="msg2">
            <input type="button" value="=">
            <input type="text" name="" id="" v-model="result">
            <input type="button" value="计算" @click="calc">
    </div>
    var vm = new Vue({
            el: '#app2',
            data: {
                msg1: '0',
                msg2: '0',
                result: '0',
                opt: '-'
            },
            methods: {
                calc() {
                    // 方法一
                    //     switch (this.opt){
                    //         case '+':this.result =parseInt(this.msg1)+parseInt(this.msg2);break ;
                    //         case '-':this.result =parseInt(this.msg1)-parseInt(this.msg2);break ;
                    //         case '*':this.result =parseInt(this.msg1)*parseInt(this.msg2);break ;
                    //         case '/':this.result =parseInt(this.msg1)/parseInt(this.msg2);break ;
                    //     }
                    // 方法二
                    var codeStr = 'parseInt(this.msg1)' + this.opt + 'parseInt(this.msg2)';
                    this.result = eval(codeStr);
                },
            }
        });

    vue使用样式:

    <div id="app3">
            <h2>第一种:数组</h2>
            <h1 :class="['wraper1','wraper2','wraper3']">hkdlfjhklddhfjdfkd</h1>
            <h2>第一种:在数组中使用三元表达式</h2>
            <h1 :class="['wraper1','wraper2',flag?'wraper3':'']">1211111111</h1>
            <h2>第一种:在数组写对象,提高可读性,flag为true就显示</h2>
            <h1 :class="['wraper1',{'wraper2':flag},'wraper3']">1211111111</h1>
            <h2>第一种:直接使用对象</h2>
            <!-- class 使用v-bind绑定对象的属性时,由于对象的属性是类名,所以,对象的属性可带引号,可不带,属性的值是标识符 -->
            <h1 :class="{wraper1:true,wraper2:false,wraper3:false}">1211111111</h1>
            <!-- 把他放在属性里面 -->
            <h1 :class="obj">1211111111</h1>
    </div>
    new Vue({
            el: '#app3',
            data: {
                flag: true,
                obj: { wraper1: true, wraper2: true, wraper3: false },
            }
        });
    v-for指令:
    <div id="app5">
            <p v-for="item in list1">{{item}}</p>
            <p v-for="(item,i) in list1">索引值{{i}}+" "+{{item}}</p>
            //<!-- 遍历数组 -->
            <p v-for="(item,i) in list2">{{item.id}}+" "+{{item.name}}+" "+索引值{{i}}</p>
            //<!-- 遍历对象 -->
            <p v-for="(value,key,i) in list3">值:{{value}}+" "+键:{{key}}+" "+索引值{{i}}</p>
           // <!-- 迭代数组, 如果使用数字时从1开始-->
            <p v-for="count in 10">这是第{{count}}次</p>
            <h1>v-for使用注意事项<h1>
            id:<input type="text" v-model="id">
            name:<input type="text" v-model="name">
            <input type="button" value="添加" @click="add">
            //<!--v-for key只能使用number或string,key使用时要用v-bind  -->
            //<!-- 在组件中使用v-for,或特殊情况,使用时有问题,必须指定唯一的 字符串、数字类型的key -->
            <p v-for="(item,i) in list2" v-bind:key="item.id">
            <input type="checkbox" name="" id="">{{item.id}}+" "+{{item.name}}</p>
    </div>
    new Vue({
            el: '#app5',
            data: {
                id: '',
                name: '',
                list1: [1, 2, 3, 4, 5],
                list2: [
                    { id: 1, name: 'lisi1' },
                    { id: 2, name: 'lisi2' },
                    { id: 3, name: 'lisi3' },
                    { id: 4, name: 'lisi4' }
                ],
                list3: {
                    id: 1,
                    name: 'haha',
                    age: 12,
                    adddress: '中国',
                }
            },
            methods: {
                add() {
                    this.list2.push({ id: this.id, name: this.name })
                }
            }
        });

    v-if:

    <div id="app6">
            //<!-- <input type="button" value="toggle" @click="toggle"> -->
            //<!-- 等于下面的 -->
            <input type="button" value="toggle" @click="flag=!flag">
            <h3 v-if="flag">这是v-if控制的元素</h3>
            <h3 v-show="flag">这是v-show控制的元素</h3>
            //<!-- v-if每一次都会重新删除和创建元素 ,有较高的切换性能消耗
            如果元素频繁的切换,最好不要使用-->
            //<!-- v-show每一次都不会重新删除和创建元素 ,只是切换了元素的dispaly:none样式,有较高的初始渲染消耗
            如果元素可能永远也不会显示出来被用户看,推荐使用-->
    </div>
    new Vue({
            el: '#app6',
            data: {
                flag: true,
            },
            methods: {
                toggle() {
                    this.flag = !this.flag;
                }
            }
        });

    品牌例子:

    <div id="day1">
            <div class="panel panel-primary">
                <div class="panel-heading">
                    <h1 class="panel-title">添加品牌</h1>
                </div>
                <div class="panel-body form-inline">
                    <label>
                        id:<input type="text" name="" id="" class="form-control" v-model="id">
                    </label>
                    <label>
                        //<!-- @keyup="add"是键盘抬起触发add事件 .enter键盘抬起按enter键就可以触发-->
                        name:<input type="text" name="" id="" class="form-control" v-model="name" @keyup.enter="add">
                    </label>
                    <label>
                        //<!-- v-color=('blue')是传递的值 -->
                        搜索关键字:<input type="text" name="" id="" class="form-control" v-model="keywords" v-focus
                            v-color=('blue')>
                    </label>
                    //<!-- 在vue中使用事件绑定,如果加了小括号就可以传参数add() -->
                    <input type="button" value="添加" class="btn btn-primary" @click="add">
                </div>
            </div>
            <table class="table table-bordered table-hover table-striped">
                <thead>
                    <tr>
                        <th>id</th>
                        <th>name</th>
                        <th>time</th>
                        <th>option</th>
                    </tr>
                </thead>
                <tbody>
    //<!-- 自定义search()方法,通过传参的形式,传递给search方法 在这个方法中通过for循环,把符合条件的数据保存到一个新数组中返回-->
                    <tr v-for="item in search(keywords)" :key="item.id">
                        <td>{{item.id}}</td>
                        <td v-text="item.name"></td>
                        <td>{{item.time|dateFormat('')}}</td>
                        //<!-- 根据id删除 -->
                        <td><a href="" @click.prevent="del(item.id)">删除</a></td>
                    </tr>
                </tbody>
            </table>
        </div>
    new Vue({
            el: '#day1',
            data: {
                id: '',
                name: '',
                keywords: '',
                list: [
                    { id: 1, name: '李四1', time: new Date() },
                    { id: 2, name: '李四2', time: new Date() },
                    { id: 3, name: '李四3', time: new Date() },
                    { id: 4, name: '李四4', time: new Date() },
                ]
            },
            methods: {
                add() {//添加方法
                    this.list.push({ id: this.id, name: this.name, time: new Date() })
                    // 添加了要清空input的数据
                    this.id = this.name = "";
                },
                del(id) {//删除
                    // //根据id删除
                    // this.list.some((item, i) => {
                    //     if (this.id = id) {
                    //         this.list.splice(i, 1);// 根据id查找索引,找到索引,直接调用数组splce方法删除
                    //         // 终止后续循环
                    //         return true;
                    //     }
                    // })
                    // 删除方法二
                    var index = this.list.findIndex(item => {
                        if (item.id == id) {
                            // 终止后续循环
                            return true;
                        }
                    })
                    this.list.splice(index, 1);
                    console.log(index);
                },
                search(keywords) {//根据关键字,进行数据搜索
                    // var newList = [];
                    // this.list.forEach(item => {
                    //     if (item.name.indexOf(keywords) != -1) {
                    //         newList.push(item);
                    //     }
                    // })
                    // return newList;
    
                    // 方法二
                    // forEach,some,filter,dindIndex都是素组的新方法
                    return this.list.filter(item => {
                        if (item.name.includes(keywords)) {
                            return item;
                        }
                    });
                }
            },
        });

    定义组件:

    <h1>定义全局过滤器</h1>
        <div class="filter">
            //<!-- sgFormat('青青+1')括号里面是传递参数,可传递多个 -->
            <p>{{msg|msgFormat('青青+1')}}</p>
        </div>
          <h1>定义私有过滤器</h1>
          <div id="day3">
          <h1 v-color="'green'">{{time|dateFormat}}</h1>
      </div> </div>
      // 过滤器的使用
        // 1、只能应用于v-bind和mustache(插值表达式{{}})
        // 2、格式:{{name|nameope}}
        // 3、定义全局过滤器 Vue.filter('过滤器名称',function (){})
        Vue.filter('msgFormat', function (msg, arg) {
            return msg.replace(/清清/g, arg)
        })
        new Vue({
            el: '.filter',
            data: {
                msg: '我是我是彭清清我是我是彭清清'
            },
            methods: {}
        })
        // 定义私有过滤器
        new Vue({
            el: '#day3',
            data: {
                time: new Date(),
            },
            methods: {
            },
            // 全局指令带s,私有指令不带s
            filters: {//定义私有过滤器,有两个条件:过滤器名称和处理函数,调用的时候采用就近原则,如果私有过滤器和全局过滤器的名称一致,优先调用私有
                dateFormat: function (dateStr, timePattern = "") {
                    var time = new Date(dateStr);
                    var year = time.getFullYear();
                    // month 从0开始
                    var month = time.getMonth() + 1;
                    var day = time.getDate();
                    if (timePattern.toLowerCase() == 'yyyy-mm-dd') {
                        return `${year}-${month}-${day}`;
                    } else {
                        var hour = time.getHours();
                        var minutes = time.getMinutes();
                        var seconds = time.getSeconds();
                        return `${year}-${month}-${day}  ${hour}:${minutes}:${seconds}----`;
                    }
                }
            },
        })
     Vue.config.keyCodes.f2 = 113;//自定义按键修饰符
        Vue.directive('focus', {// 自定义全局指令获取焦点  注意:参数1:指令名称 :定义的时候不需要加v-前缀,调用的时候必须加v-
            // 参数2:是一个对象,
            bind: function (el) {//每当指令绑定到元素上的时候,会执行这个函数
                // 在每一个函数中,第一个参数永远是el,表示被绑定指令的元素,这个元素是原始的js对象
            },
            inserted: function (el) {//插入到DOM的时候,执行这个函数
                el.focus()
            },
            updated: function () {//每当vNode更新的时候执行
            }
        })
        Vue.directive('color', {//自定义全局设置字体颜色的指令}
            bind: function (el, binding) {
                //el.style.color = 'red'//样式只要通过指令不绑定给了元素,不管有没有插入到页面中,这个元素肯定有了内联样式
                el.style.color = binding.value;
            }
            // 和样式相关的在bind设置就可以,和行为相关的在inserted设置,防止js行为不生效
        })
        // 定义全局格式化时间
        Vue.filter('dateFormat', function (dateStr, timePattern = "") {
            var time = new Date(dateStr);
            var year = time.getFullYear();
            // month 从0开始
            var month = time.getMonth() + 1;
            var day = time.getDate();
            // 如果传递timePattern参数不等于yyyy-mm-dd,就把他转化为小写,如果是yyyy-mm-dd格式的
            // 说明显示的是年月日否则就是完整的时间
            if (timePattern.toLowerCase() == 'yyyy-mm-dd') {
                return `${year}-${month}-${day}`;
            } else {
                var hour = time.getHours();
                var minutes = time.getMinutes();
                var seconds = time.getSeconds();
                return `${year}-${month}-${day}  ${hour}:${minutes}:${seconds}`;
            }
        })

     定义私有指令:指令名称是驼峰命名的,由于html不认识驼峰命名,所以引用的时候用-连接起来

    html代码如下:

    <div id="day3">
       <h1 v-font-Style="'italic'" v-font-Size="30">{{time|dateFormat}}</h1>
    </div>

    vue代码如下:

    new Vue({
            el: '#day3',
            data: {
                time: new Date(),
            },
            methods: {
            },
            // 全局指令带s,私有指令不带s 
            filters: {//定义私有时间过滤器,有两个条件:过滤器名称和处理函数,调用的时候采用就近原则,如果私有过滤器和全局过滤器的名称一致,优先调用私有
                dateFormat: function (dateStr, timePattern = "") {
                    var time = new Date(dateStr);
                    var year = time.getFullYear();
                    // month 从0开始
                    var month = time.getMonth() + 1;
                    var day = time.getDate();
    
    
                    if (timePattern.toLowerCase() == 'yyyy-mm-dd') {
                        return `${year}-${month}-${day}`;
                    } else {
                        var hour = time.getHours();
                        var minutes = time.getMinutes();
                        var seconds = time.getSeconds();
                        return `${year}-${month}-${day}  ${hour}:${minutes}:${seconds}----`;
                    }
                }
            },
            directives: {//定义私有指令
                'fontStyle': {
                    bind: function (el, binding) {
                        el.style.fontStyle = binding.value;
                    }
                },
                'fontSize': function (el, binding) {//这个函数等同于把代码写到了bind和update中
                    el.style.fontSize = parseInt(binding.value) + 'px';
                }
            }
        });

     vue动画:

    (1)、使用过渡类名定义动画

    HTML代码如下:

    <div id="app">
            <input type="button" value="toggle" @click="show=!show">
            //<!-- 使用transition把需要动画的元素包裹起来 这是vue官方提供的-->
            <transition name="my">
               // <!--使用name属性来定义前缀来自定义动画,使用的时候.my-enter-->
                //<!-- 点击按钮让小圆展示出来,v-show 和v-if都行-->
                <h3 class="circle" v-show="show">这是一个动画</h3>
            </transition>
    </div>

    样式代码如下:

        //* 自定义两组样式,来控制transition内部的元素实现动画 */
            .my-enter,
           //*这是一个时间点,是进入之前元素的起始状态,此时还没有开始进入*/
            v-leave-to {
               //*这是一个时间点,是离开之后,离开的终止状态,此时动画已结束*/
                opacity: 0;
                transform: translateX(150px);
            }
            .my-enter-active,
           / /*入场动画的时间段*/
            .my-leave-active {
            / /*离场动画的时间段*/
                transition: all 1s ease;
            }

    vue代码如下:

    new Vue({
            el: '#app',
            data: {
                show: false
            },
            methods: {},
        });

    (2)、使用第三方css类库定义动画

    <div id="app">
            <input type="button" value="toggle" @click="show=!show">
            //<!-- :duration="400"统一设置动画的出场,和入场动画时长 -->
            //<!-- :duration="{enter:200,leave:400} 分别设置动画的出场,和入场动画时长-->
            <transition enter-active-class="animated bounceIn" leave-active-class="animated bounceOut" :duration="400">
                <h3 class="circle" v-show="show">这是一个动画</h3>
            </transition>
            //<!-- 把animated放在元素上 -->
            <transition enter-active-class="bounceIn" leave-active-class="bounceOut" :duration="{enter:200,leave:400}">
                <h3 class="circle" v-show="show" class="animated">这是一个动画</h3>
            </transition>
        </div>

     (3) 、钩子函数实现半场动画(只需要进入动画或是只需要出场动画)

    例子:小球动画

     HTML 代码如下:

    <div id="app">
            <input type="button" value="toggle" @click="show=!show">
            <transition @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter">
                <h3 class="circle" v-show="show"></h3>
            </transition>
    </div>

    样式代码如下:

     .circle {
                 20px;
                height: 20px;
                border-radius: 50%;
                background-color: olive;
            }

    vue代码如下:

     new Vue({
            el: '#app',
            data: {
                show: false
            },
            methods: {
                //动画钩子函数的第一个参数是el,不是要执行动画的DOM元素,是原生的jsDOM对象,可以认为是通过document.getElementById获取到的
                beforeEnter(el) {//这个函数是表示,动画入场前,此时动画未开始,在这里设置动画之前的起始样式
                    el.style.transform = "translate(0,0)"//设置小球开始前的动画
                },
                enter(el,done) {//这个函数是表示,动画开始之后的样式,可以设置小球完成后的结束状态
                    el.offsetWidth;//这句话没有实际应用,强制动画刷新,不设置动画就不会出来,有height,left,top
                    el.style.transform = "translate(150px,150px)";
                    el.style.transition = "all 1s ease";
                    done();//这个是afterEnter函数的引用,加上会停留一会在消失,不然就会立即消失
                },
                afterEnter(el) {//这个函数是表示,动画完成之后
                    this.show=!this.show;
                }
            },
        });

     (4)、使用transition-group实现列表组动画

    HTML代码如下:

     <div id="app">
            <div>
                <label>Id:<input type="text" v-model="id"></label>
                <label>Name:<input type="text" v-model="name"></label>
                <input type="button" value="添加" @click="add">
            </div>
            //<!-- <ul> -->
           // <!-- 实现列表过渡的时候,如果过渡的元素是v-for循环渲染的,不能使用transition包裹,使用transition-group -->
            //<!-- 如果用v-for循环创建动画,必须为每一个元素设置:key属性 -->
            <transition-group appear tag="ul">
                //<!--给transition-group添加appear属性,给页面刚展示出来入场效果-->
                <li v-for="item in list" :key="item.id" @click="del">
                    {{item.id}}---{{item.name}}
                </li>
            </transition-group>
            //<!--  由于transition-group默认会渲染为span元素,span里面包含li是不符合w3c规范,所以要设置tag属性为ul-->
            //<!-- </ul> -->
        </div>

    样式代码如下:

     li {
                list-style: none;
                border: orange 1px solid;
                margin-right: 5px;
                line-height: 30px;
                font-size: 12px;
                 100%;
            }
    
            //* 进入动画 */
            .v-enter,
            .v-leave-to {
                opacity: 0;
                transform: translateX(15px);
            }
    
            .v-enter-active,
            .v-leave-active {
                transition: all 1s ease;
            }
    
            li:hover {
                background-color: olivedrab;
                transition: all 0.4s ease;
            }
    
           //* 离开动画 .v-move/v-leave和.v-leave配合使用*/
            .v-move {
                /*v-leave也行*/
                transition: all 1s ease;
            }
    
            .v-leave-active {
                position: absolute;
            }

    vue代码如下:

    new Vue({
            el: '#app',
            data: {
                id: '',
                name: '',
                list: [
                    { id: 1, name: '李四1' },
                    { id: 2, name: '李四2' },
                    { id: 3, name: '李四3' },
                    { id: 4, name: '李四4' },
                ]
            },
            methods: {
                add() {
                    console.log("a");
                    this.list.push({ id: this.id, name: this.name })
                },
                del(i) {//删除
                    this.list.splice(i, 1);
                }
            },
        });

     vue组件化和模块化:

    什么是组件组建是为了拆分实例的代码量,能够让我们以不同的主见来划分不同的功能模块,将来我们需要什么样的功能就可以去调用对应的组件

    组件化和模块化的不同:
    模块化是从代码逻辑的角度进行划分的,方便代码分量开发,保证每个功能模块的职能单一
    组件化是从ui界面的角度进行划分的,前端的组件转变,uI组件的重用

    (1)、分别使用Vue.extend和Vue.component创建组件

    <div id="app">
        //<!-- 如果要使用组件,直接把组件的名称以HTML标签形式引入到页面中 -->
        <my-Com1></my-Com1>
    </div>
    // 1、使用Vue.extend创建的全局组件
        var com1 =Vue.extend({
            template:'<h3>这是使用Vue.extend创建的全局组件</h3>'//通过template属性指定组件要展示的HTML结构
        });
        // 2、Vue.component('组件名称',创建出来的组件模块对象)
        Vue.component('myCom1',com1)//注意:组件名称是驼峰命名法,引用的时候两个单词之间要使用—连接
        // 创建vue实例
        new Vue({
            el:'#app',
            data:{}
        });

    (2)、使用对象字面量的形式创建

    // Vue.component第一个参数:组件名称,将来引入的时候就使用标签的形式引入,第二个参数:Vue.extend创建的组件,其中template属性就是组件要展示的HTML内容
        Vue.component('myCom1',Vue.extend({
            template:'<h3>这是使用Vue.extend创建的全局组件</h3>'
        }));
        // 上面的方式还可以简化,使用对象字面量的形式创建
        Vue.component('myCom1',{
            // 注意:无论使用哪种方式创建组件,属性template指定的模板内容有且只有唯一一个根元素,要用div包裹起来
            template:'<div><h3>这是使用Vue.extend创建的全局组件<span>123</span></h3></div>'
        });
        // 创建vue实例
        new Vue({
            el:'#app',
            data:{}
        });

    (3)、把模板template单独的抽取出去

    <body>
        <div id="app"> 
            <my-Com1></my-Com1>
        </div>
        //<!-- 在被控制的#app外面,使用template元素,定义组件HTML结构 -->
        <template id="com1">
            <div>
                <h3>这是通过template元素,在外部定义的组件结构,这个方式有代码提示</h3>
            </div>
        </template>
    </body>
    </html>
    <script>
        Vue.component('myCom1', {
            template: '#com1'
        });
        // 创建vue实例
        new Vue({
            el: '#app',
            data: {}
        });
    </script>

     以上都是全局的

    (4)、使用components创建私有组件

    <div id="app"> 
         <login></login>
    </div>
    // 创建vue实例 new Vue({ el: '#app', data: {}, methods: {}, components:{ login:{ template:'<h3>这是通过template元素</h3>' } } });

    (5)、组件中的data:组件中可以有自己的data,但和实力中的data不一样,组件中的data要为一个函数,并且返回的是一个对象,但使用方式是一样的

    Vue.component('myCom1', {
            template: '<h3>这是全局组件--{{msg}}</h3>',
            data:function (){
                return {
                    msg:'这是组件中定义的data数据'
                };
            }
        });

     (6)、为什么组件的data要为一个function,下面用实例演示

     <div id="app">
            <my-Com1></my-Com1>
            <my-Com1></my-Com1>
            <my-Com1></my-Com1>
        </div>
        <template id="day">
            <div>
                <input type="button" value="+1" @click="add">
                <h3>{{count}}</h3>
            </div>
        </template>
    // var dataObject={count: 0};
        Vue.component('myCom1', {
            template: '#day',
            data: function () {
                return {
                    count: 0
                    // dataObject//如果把对象定义在外面,当调用多次组件的时候,点击一个按钮其他按钮会受到影响
                };
            },
            methods: {
                add() {
                    this.count++;
                }
            },
        });
        // 创建vue实例
        new Vue({
            el: '#app',
            data: {},
            methods: {},
        });

    组件的切换:

     (1)、v-if和v-else实现很多组件的切换,缺点是:只能切换两个,当有多个的时候就不行

    <div id="app">
            <a href="" @click.prevent="show=true">登入</a>
            <a href=""  @click.prevent="show=false">注册</a>
            <login v-if="show"></login>
            <register v-else="show"></register>
    </div>
    Vue.component('login', {
            template: '<h3>登入组件</h3>',
        });
        Vue.component('register', {
            template: '<h3>注册组件</h3>',
        });
        // 创建vue实例
        new Vue({
            el: '#app',
            data: {
                show:true
            },
            methods: {},
        });

    (2)、使用component切换多个组件

     <div id="app">
            <a href="" @click.prevent="comName='login'">登入</a>
            <a href="" @click.prevent="comName='register'">注册</a>
            //<!-- vue提供的component来展示对应名称的组件,component是一个占位符,is属性指定要展示的组件的名称 -->
            <component :is="comName"></component>
          // <!-- 属性绑定会把后面的当作表达式解析 -->
     </div>
    // 组件名称是字符串,:is属性绑定会把后面的当作表达式解析,并不是真正的字符串,所以'login'要用单引号包起来
        Vue.component('login', {
            template: '<h3>登入组件</h3>',
        });
        Vue.component('register', {
            template: '<h3>注册组件</h3>',
        });
        // 创建vue实例
        new Vue({
            el: '#app',
            data: {
                comName:'login'//这个comName是 :is属性绑定的组件名称,默认展示login
            },
            methods: {},
        });

    (3)、组件切换应用动画

    <div id="app">
            <a href="" @click.prevent="comName='login'">登入</a>
            <a href="" @click.prevent="comName='register'">注册</a>
            //<!-- mode属性:设置组件切换的模式,out-in是上一个消失了才消失下一个 -->
            <transition mode="out-in">
                <component :is="comName"></component>
            </transition>
    </div>
    /* 进入动画 */
            .v-enter,
            .v-leave-to {
                opacity: 0;
                transform: translateX(15px);
            }
    //出场动画
            .v-enter-active,
            .v-leave-active {
                transition: all 1s ease;
            }

     父组件和子组件传递值的data和props区别

    // 子组件,默认无法访问到副总监的data上的数据和methods中的方法,副组件可以在引用纸组件的时候,通过绑定v-bind的形式,
        // 把需要传递给子组件的数据以属性绑定的形式传递到子组件的内部,供子组件使用
        Vue.component('com1', Vue.extend({
            template:'<h1>hekk</h1>'
        }))
        new Vue({
            el: '#app',
            // data上的数据都是可读可写的
            data: {//注意:子组件的data数据,不是通过父组件传递过来的,而是子组件自身有的,如:子组件通过ajax,请求回来的数据,都可以在data上定义
                msg:'这是父组件中的数据'
            },
            methods: {},
            components:{
                com1:{
                    template:'<h1 >这是子组件---{{parentmsg}}</h1>',
                    // 注意:组件中的所有props中的数据都是通过父组件传递给子组件的
                    // props中的数据是只读的,无法重新复制被修改
                    props:['parentmsg']//把父组件传递过来的parentmsg属性,先在props数组中定义一下,才能使用
                }
            }
        });

    子组件通过事件调用向父组件传值

    var com1 = {
            template: '#com',
            data() {
                return {
                    sonmsg: { name: "李四", age: 13 }
                }
            },
            methods: {
                // 子组件的点击事件
                myclick() {
                    // $emit 英文意思是触发,发射
                    this.$emit('func', this.sonmsg)//调用父组件的方法并传递参数,this.sonmsg传递给父组件
                },
            },
        }
        new Vue({
            el: '#app',
            data: {
                datamsg:null
            },
            methods: {
                show(data) {
                    console.log("调用了父组件的方法");
                    this.datamsg=data;
                }
            },
            components: {
                com1
            }
        });

     使用ref获取dom元素和组件引用

    <!-- 使用ref获取dom元素和组件引用 -->
        <div id="app">
            <input type="button" value="获取元素" @click="getElement">
            <h3 id="myh3" ref="myh3">haha</h3>
            <login ref="loginref"></login>
        </div>
    </body>
     //上面是HTML
    <script>
        var login = {
            template: '<h3>login</h3>',
            data() {
                return {
                    msg: 'sonmsg'
                }
            },
            methods: {
                show() {
                    console.log('调用了子组件的方法')
                }
            },
        }
        new Vue({
            el: '#app',
            data: {},
            methods: {
                getElement() {
                    // console.log(document.getElementById('myh3').innerHTML);
                    // console.log(this.$refs.myh3.innerText);//ref是reference的缩写
                    console.log(this.$refs.loginref.msg);//用ref输出组件的信息
                    this.$refs.loginref.show();//调用组的方法
                }
            },
            components: {
                login
            }
        });

    vue路由

    后端路:由对于普通的网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上对应的资源

    前端路由:对于当页面应用程序来说,主要通过URL中的hash(#号)来实现不同页面之间的切换,同时hash有一个特点,HTTP请求中不会包含hash相关的内容,所以当页面跳转主要用hash实现,在单页面应用程序中,这种通过hash改变来切换页面的方式,称作前端路由

     (1)、router-link、router动画、路由高亮使用

    HTML代码:

     <div id="app">
            //<!-- <a href="#/login">登入</a> -->
            //<!-- <a href="#/register">注册</a> -->
            //<!-- router-link默认渲染的是a标签,用router-link就不用加# -->
            <router-link to="/login" tag="span">登入</router-link>
            //<!--tag="span"渲染为span标签-->
            <router-link to="/register">注册</router-link>
            
            //<!-- router-view是vue-router提供的元素,用来当占位符,路由规则匹配到的组件展示在这里 -->
            //<!--  给路由加动画 -->
            <transition mode="out-in">
                <router-view></router-view>
            </transition>
    </div>

    样式代码:

     //* 设置当前展示的样式,路由高亮(路由默认的,自带的) */
            .router-link-active {
                color: olive;
                font-weight: 500;
                text-decoration: underline;
                font-size: 30px;
            }
    
            //* 自定义的路由高亮 */
            .myactive {
                color: olive;
                font-weight: 500;
                text-decoration: underline;
                font-size: 30px;
            }
            //* 路由动画 */
            .v-enter,
            .v-leave-to{
                opacity: 0;
                transform: rotateX(140px);
            }
            .v-enter-active,
            .v-leave-active{
                transition: all 1s ease;
            }

    vue代码:

    var login = {
            template: '<h1>login</h1>'
        }
        var register = {
            template: '<h1>register</h1>'
        }
        // 创建一个路由对象,当导入vue-router包之后,在windows全局对象中就有了一个路由的构造函数叫做VueRouter
        var routerObj = new VueRouter({//new 一个路由对象,可以为一个构造函数,传递一个配置对象
            // 
            routes: [//这个配置对象的routes表示:路由匹配规则,
                // 每个匹配规则有两个属性,一:path,表示监听哪个路由链接地址
                // 二:component表示,如果路由是前面匹配到的path,则表示component属性对应的哪个组件
                // 注意:component属性值必须是一个组件对象,不能是组件的引用名称
                { path: '/', redirect: '/login' },//手动修改hash值
                { path: '/login', component: login },
                { path: '/register', component: register },
            ],
            linkActiveClass: 'myactive'//自定义自己的高亮样式
        })
        new Vue({
            el: '#app',
            data: {},
            methods: {},
            router: routerObj//将路由规则对象注册到我们的vm实例上,然后展示对应的组件
        });

     (2)、路由规则中定义参数

    2.1、使用query方式传递参数

    <div id="app">
            //<!-- 如果在路由中使用查询字符串,给路由传递参数则不需要修改路由规则的path属性,就是 { path: '/', redirect: '/login' }, -->
            //<!-- to="/login?id=10&&name=李思",传递参数,可以传递多个 -->
            <router-link to="/login?id=10&name=李思">登入</router-link>
            <router-link to="/register">注册</router-link>
            <router-view></router-view>
    </div>
    var login = {
            template: '<h1>login---{{$route.query.id}}---{{$route.query.name}}</h1>',//this可以省略
            data(){
                return{
                    msg:'124'
                }
            },
            created() {// 组件生命周期钩子函数
                console.log(this.$route);//$route和$ref差不多
                console.log(this.$route.query.id);//输出id里面的值。
            },
        }
        var register = {
            template: '<h1>register</h1>'
        }
        var routerObj = new VueRouter({
            routes: [
                { path: '/login', component: login },
                { path: '/register', component: register },
            ],
        });
        new Vue({
            el: '#app',
            data: {},
            methods: {},
            router: routerObj,//属性名和属性值一样可以简化,就是new出来的router的名称和router一样只用写一个,现在这个router: routerObj不一样
        });

    2.2、使用params方式传递路由参数

    <div id="app">
            //<!-- 使用params传递参数 -->
            <router-link to="/login/10/lisi">登入</router-link>
            <router-link to="/register">注册</router-link>
            <router-view></router-view>
    </div>
    <script>
        var login = {
            template: '<h1>login---{{$route.params.id}}--{{$route.params.name}}</h1>',//this可以省略
            data(){
                return{
                    msg:'124'
                }
            },
            created() {// 组件生命周期钩子函数
                console.log(this.$route.params.id);
            },
        }
        var register = {
            template: '<h1>register</h1>'
        }
        var routerObj = new VueRouter({
            routes: [
                { path: '/login/:id/:name', component: login },//:id解析id,:name解析name,通过URL地址,可以有多个参数
                { path: '/register', component: register },
            ],
        });
        new Vue({
            el: '#app',
            data: {},
            methods: {},
            router: routerObj,//属性名和属性值一样可以简化,就是new出来的router的名称和router一样只用写一个,现在这个router: routerObj不一样
        });

    使用children实现路由嵌套

    HTML代码如下:

    <body>
        <div id="app">
            <router-link to="/account">account</router-link>
            <router-view></router-view>
        </div>
        <template id="com">
            <div>
                <h1>这是Account组件</h1>
                <router-link to="/account/login">登入</router-link>
                <router-link to="/account/register">注册</router-link>
                <router-view></router-view>
            </div>
        </template>
    </body>

    vue代码如下:

    <script>
        var account = {
            template: '#com',
        }
        var login = {
            template: '<h3>登入</h3>',
        }
        var register = {
            template: '<h3>注册</h3>',
        }
        var router = new VueRouter({
            routes: [
                { path: '/account',
                 component: account ,
                 children:[
                     {path: 'login', component: login },//使用children属性前面,不带/,否则永远以跟路劲请求,不方便用户理解URL地址
                     {path: 'register', component: register },
                 ]
                },
                // { path: '/account/login', component: login },
                // { path: '/account/register', component: register },
            ]
        })
        new Vue({
            el: '#app',
            router//属性名和属性值一样可以简化,就是new出来的router的名称和router一样只用写一个
        });

     

  • 相关阅读:
    ES6对象展开运算符
    Vue中keep-alive的深入理解和使用
    彻底明白VUE修饰符sync
    函数去抖和函数节流
    vue cli4.0 配置环境变量
    什么是process.env?
    new Function和with
    inline-block元素没有对齐的解决方案及总结
    【译文】为什么你的浏览器会限制并发网络调用的数量?
    高德地图Marker缩放位置变化
  • 原文地址:https://www.cnblogs.com/pengppp/p/11768122.html
Copyright © 2020-2023  润新知