Vue笔记

Vue

1、Vue快速起步

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引入Vue的js库 -->
    <!-- 一旦引入Vue的js库,在浏览器内存中,多了一个构造器:Vue。 -->
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
</head>
<body>
    <div id="app">
        {{msg}}
    </div>
    <script>
        let vue = new Vue({
            el: "#app",
            data: {
                msg:"啦啦啦啦"
            }
        });
    </script>
</body>
</html>

2、v-bind的使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
</head>
<body>
    <div id="app">
        <a v-bind:title="msg">床前明月光</a>
        <a :title="msg2">凄凄惨惨戚戚</a>
    </div>

    <script>
        var app = new Vue({
            el: "#app",
            data: {
                msg: "李白",
                msg2: "李清照"
            }
        });
    </script>
</body>
</html>

3、v-on的使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
</head>
<body>
    <div id="app">
        <button v-on:click="f1">点点</button>    
        <button @click="f2">点点2</button>
    </div>

    <script>

        var app = new Vue({
            el: "#app",
            data:{
            },
            methods: {
                f1: function() {
                    console.log("f1......");
                },
                f2: function() {
                    console.log("f2......");
                }
            }
        });
    </script>
</body>
</html>

4、走马灯例子体会Vue的单向绑定

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
</head>
<body>
    <!-- 走马灯例子,体会Vue的强大之处 -->
    <div id="app">
        <button @click="lang">浪起来</button>
        <button v-on:click="stop">不要浪了</button>
        {{msg}}
    </div>

    <script>
        let time;
        let vue = new Vue({
            el: "#app",
            data: {
                msg: "大家好呀,欢迎来到..."
            },
            methods: {
                lang(){
                    this.msg=this.msg.substring(1)+this.msg.substring(0,1);
                    clearTimeout(time);
                    time = setTimeout(this.lang,1000);
                },
                stop(){
                    clearTimeout(time);
                }
            }
        })
    </script>
</body>
</html>

5、Vue中的5个事件修饰符

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
    <style>
        #d1 {
           width: 300px; height: 300px; background-color: #00b9f1;
        }
        #d2 {
           width: 200px; height: 200px; background-color: #8ab42e;
        }
        #d3 {
           width: 100px; height: 100px; background-color: #ff6600;
        }
    </style>
</head>
<body>
    <div id="app">
        <button @click.once="f1">一次性事件</button>
        <br />
        <a href="http://www.baidu.com" @click.prevent="f2">阻止默认事件的发生</a>
        <br />
        <div id="d1" @click="d1">
            <div id="d2" @click="d2">
                <div id="d3" @click="d3">
                    <!--stop事件修饰符,就是用来阻止事件冒泡的-->
                    <!--capture事件修饰符,就是将事件处理函数的执行时机,提前到了事件捕获阶段-->
                    <!--self事件修饰符,就是规定只有事件发生在自己身上的时候,才触发,冒泡上来的事件不算。-->
                </div>
            </div>
        </div>
    </div>
    <script>
        var app = new Vue({
            el: "#app",
            data: {
                msg: "Hello!!"
            },
            methods: {
                f1() {
                  console.log("f1: " + new Date().getTime());
                },
                f2() {
                    alert("f2....");
                },

                d1() {
                    console.log("d1");
                },
                d2() {
                    console.log("d2");
                },
                d3() {
                    console.log("d3");
                }
            }
        });
    </script>
</body>
</html>

5.1 事件委托

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
    <style>
        #d1 {
           width: 300px; height: 300px; background-color: #00b9f1;
        }
        #d2 {
           width: 200px; height: 200px; background-color: #8ab42e;
        }
        #d3 {
           width: 60px; height: 60px; background-color: #ff6600;
        }
        #d4 {
           width: 60px; height: 60px; background-color: #ff00f2;
        }
    </style>
</head>
<body>
    <div id="app">
        <button @click.once="f1">一次性事件</button>
        <br />
        <a href="http://www.baidu.com" @click.prevent="f2">阻止默认事件的发生</a>
        <br />
        <div id="d1" @click="d1">
            <div id="d2" >
                <div id="d3">
                    
                </div>
                <div id="d4">

                </div>
            </div>
        </div>
    </div>
    <script>
        var app = new Vue({
            el: "#app",
            data: {
                msg: "Hello!!"
            },
            methods: {
                f1() {
                  console.log("f1: " + new Date().getTime());
                },
                f2() {
                    alert("f2....");
                },
                d1(e) {//从事件中获取事件源,事件源就是动作的承受者
                    let t=e.target;
                    // console.log(t.id);
                    if(t.id=="d3"){
                        console.log("33333"); return ;
                    }
                    if(t.id=="d4"){
                        console.log("4444"); return ;
                    }
                }
            }
        });
    </script>
</body>
</html>

6、Vue双向绑定

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>

</head>
<body>
   <div id="app">
       <button @click="f1">点我试试</button>
       {{msg}}  <br>    
       <input v-model:value="msg">
   </div>
    
   <script>
       let vue = new Vue({
           el: "#app",
           data: {
               msg:"哈哈哈"
           },
           methods: {
               f1(){
                   this.msg="点就点"
               }
           }
       })

   </script>
</body>
</html>

6.1 双向绑定例子

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>

</head>
<body>
    <div id="app">
         <input id="i1" v-model:value="num1"> + <input id="i2" v-model:value="num2"> <button @click="calc"> = </button> 
         <input  :value="ans">
    </div>
    <script>
        let vue = new Vue({
            el: "#app",
            data: {
                num1:null,
                num2:null,
                ans:null
            },
            methods: {
                calc(){
                    this.ans=Number(this.num1)+Number(this.num2);
                }
            }
        })
    </script>
</body>
</html>

7、Vue绑定元素的class属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
    <style>
        .aa {
            border: #000000 solid 1px;
        }
        .bb {
            background-color: aquamarine;
        }
        .cc {
            font-size: 30px;
        }
    </style>
</head>
<body>
    <div id="app">

        <div v-bind:class="['aa','bb','cc']">
            Vue
        </div>

        <div v-bind:class="[p, p2, p3]">
            Vue2
        </div>

        <div v-bind:class="[ {'aa':flag},{'bb':flag2},{'cc':flag3}  ]">
            Vue3
        </div>

        <div v-bind:class="[ flag4 ? 'aa' : 'bb' ]">
            Vue4
        </div>

    </div>    
    <script>
        var app = new Vue({
            el: "#app",
            data: {
                p: "aa",
                p2: "bb",
                p3: "cc",
                flag: true,
                flag2: true,
                flag3: true,
                flag4: true
            }
        }); 
    </script>
</body>
</html>

8、v-for的使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>

</head>
<body>
    <div id="app">
        <!-- 遍历Json对象数组 -->
        <div v-for="item in list">
            {{item}}<br>
        </div>

        <!-- 遍历普通数组 -->
        <div v-for="(item,idx) in arr">
            {{idx}}---{{item}}<br>
        </div>

        <!-- 遍历对象属性 -->
        <div v-for="(v,k) in user">
            {{k}}---{{v}}
        </div>

        <!-- 循环数字 -->
        <div v-for="item in 10">
            {{item}}
        </div>

    </div>

    <script>
        let vue = new Vue({
            el: "#app",
            data: {
                list: [
                  {id: 1, name: '关羽'},
                  {id: 2, name: '张飞'},
                  {id: 3, name: '赵云'},
                  {id: 4, name: '马超'},
                  {id: 5, name: '黄忠'},
              ],
              arr: [11,22,33,44,55],
              user: {
                  uid: 1001,
                  name: "岳不群",
                  age: 24,
                  address: "华山派"
              }
            }
        });
    </script>
</body>
</html>

8.1 v-for的例子

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>

    
</head>
<body>
    <div id="app">
        <input type="text" v-model="msg">

        <button @click="add">增加</button>


        <!-- 
            每次 list 属性发生变化的时候, 都会引起这个v-for循环重新执行一遍 
            我的问题是,当我修改id属性的时候,v-for循环会不会重新执行一遍, 会!!
        -->
        
        <div v-for="item in getList()" :key="item.id">
           <input type="checkbox"> {{item.id}}--{{item.name}}
        </div>
    </div>

    <script>
        let vue = new Vue({
            el: "#app",
            data: {
                list: [
                  {id: 1, name: '关羽'},
                  {id: 2, name: '张飞'},
                  {id: 3, name: '赵云'},
                  {id: 4, name: '马超'},
                  {id: 5, name: '黄忠'},
              ],
              msg:"",
              cnt:"",
            },
            methods: {
                add(){
                    cnt=this.list.length;
                    this.list.unshift({id:++cnt,name:this.msg})
                },
                getList(){
                    console.log("调用了额");
                    return this.list;
                }
            }
        });
    </script>
</body>
</html>

9、v-if与v-show的区别

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>

</head>
<body>
    <div id="app">
        <!-- 
            v-if和v-show的区别? 
            1. v-if是控制整个dom元素是否存在的。
            2. v-show是控制dom元素的display属性的取值。
            如果一个元素经常切换,推荐使用v-show,毕竟v-show的dom操作少。
        -->
        <div v-if="flag">
            你看的见我吗
        </div>
        <div v-show="flag">
            你真的看得见我吗
        </div>
        <button @click="toggle">我点</button>
    </div>
    
    <script>
        let vue =new Vue({
            el: "#app",
            data: {
                flag:true
            },
            methods: {
                toggle(){
                    this.flag=!this.flag;
                }
            }
        });
    </script>
</body>
</html>

10、Vue的过滤器

10.1 vue的全局过滤器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
</head>
<body>
    <div id="app">
        <!-- msg|foo  可以;理解为传值给foo ,下面第24行的代码就是返回给foo -->
        {{msg|foo}} <br>  
        <!-- 这个3是传给29行的那个 n -->
        {{msg|bar(3)}} <br>
    </div>    

    <div id="app2">
        {{msg|foo|bar(10)}}
    </div>

    <script>

        // 定义Vue的全局过滤器,过滤器的名字叫做foo
        Vue.filter("foo", function(data) {
            var n = parseInt(Math.random() * 100 + 1);
            return data + " " + n;
        });

        Vue.filter("bar", function(data, n) {
           var str = "";
           for(var i = 1; i <= n; i++) {
            str += " " + data + " ";
           } 
           return str;
        })

        // 第一个Vue实例
        var app = new Vue({
            el: "#app",
            data: {
                msg:"无崖子"
            }
        });

        // 第二个Vue实例
        var app2 = new Vue({
            el: "#app2",
            data: {
                msg: "丁春秋"
            }
        });
    </script>
</body>
</html>

10.2 vue的私有过滤器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
</head>
<body>
    <div id="app" >
        {{msg|foo|bar('orange')}}
    </div>    

    <div id="app2">
        <!-- foo是第一个Vue实例的私有过滤器,第二个Vue实例是无法使用的 -->
        {{msg|foo}}
    </div>

    <script>

        // 第一个Vue实例
        var app = new Vue({
            el: "#app",
            data: {
                msg:"无崖子"
            },
            filters: {
                "foo": function(data) {
                    return data + " " +new Date().getTime();
                },
                "bar": function(data, color) {
                    return "<font color='"+color+"'>" + data + "</font>";
                }
            }
        });

        // 第二个Vue实例
        var app2 = new Vue({
            el: "#app2",
            data: {
                msg: "丁春秋"
            }
        });
    </script>
</body>
</html>

11、 按键修饰符

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
    
</head>
<body>
    <div id="app">

        <!-- <input type="text" @keyup="f1"> -->
        <!-- 只有按下a或A的时候有效 -->
        <input type="text" @keyup.a="f1">
    </div>

    <script>
        let vue = new Vue({
            el:"#app",
            data: {
            },
            methods: {
                f1(e){
                    console.log(e.keyCode);
                }
            }
        });
    </script>
</body>
</html>

12、Vue自定义指令

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
</head>
<body>
    <!-- Vue全局指令 -->    
    <!-- 需求: 要求一进入,就让以下的输入框,立刻获取到焦点 -->
    <div id="app">
        <input type="text" >
        <input type="text" >
        <input type="text" v-focus v-mycolor="'blue'" >
    </div>
    <script>

        // 定义一个Vue全局指令, 以下的focus(不一定非要是focus,可以是其他的,比如foo 、abc 等)就是本次定义的全局指令的名字
        // 在使用使用指令的时候,必须在指令前加上“v-”
        Vue.directive("focus", {
            // bind函数的执行时机,是元素被绑定上指令之时,就执行。
            // 此时元素并没有加入DOM中。参数el就是使用当前指令的元素,且el代表的元素还是一个原生的DOM对象
            //bind后面的函数一般用于添加样式
            bind: function(el) {
                el.style.backgroundColor = "lightblue";
                console.log("bind...");
            },
            // inserted函数的执行时机,是元素已经被加入到DOM以后,才执行,
            // 比如寻找父类节点,获取焦点,获取兄弟节点。 inserted后面的函数一般用于做一些js的操作
            inserted: function(el) {
                 el.focus();
                console.log("inserted");
            }
        });


        // 总之,bind合适操作元素的样式, inserted函数更适合使用js操作DOM元素
        var app = new Vue({
            el: "#app",
            data: {
                msg: "aaaa"
            },
            // 私有指令
            directives: {
                "mycolor":  {
                    bind(el,binding) {
                        el.style.color = binding.value;
                    }
                }
            }
        });
    </script>

</body>
</html>

13、生命周期钩子函数

image-20220305102626707

code

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>

</head>
<body>
    <div id="app">
        {{msg}}  <br>
        <button type="button" @click="f1">点我更新额</button>  <br>
        <button type="button" @click="f2">点我关闭额</button>
 
    </div>

    <script>
         // Vue的生命周期中的钩子函数,一共有8个。
        // Vue的生命周期函数,必须与el、data和methods平级,不能写在methods里面。
        let vue = new Vue({
            el: "#app",
            data: {
                msg:"哈哈",
            },
             // beforeCreate的执行时机,是在刚刚实例化玩Vue的对象后,就执行。此时Vue实例还没有任何属性
            beforeCreate(){
                console.log("beforeCreated......"+this.msg);
            },
            created(){
                console.log("created......"+this.msg);
            },
            beforeMount(){
                console.log("beforeMount.....");
                let t = document.getElementById("app").innerHTML;
                console.log(t);
            },
            mounted(){
                console.log("mounted.....");
                let t = document.getElementById("app").innerHTML;
                console.log(t);
            },
            beforeUpdate(){
                console.log("beforeUpdate...."+this.msg);
                let t = document.getElementById("app").innerHTML;
                console.log(t);
            },
            updated(){
                console.log("updated...."+this.msg);
                let t = document.getElementById("app").innerHTML;
                console.log(t);
            },
            beforeDestroy(){
                console.log("beforeDestroy..."+this.msg);
                let t = document.getElementById("app").innerHTML;
                console.log(t);
            },
            destroyed(){
                console.log("destroy..."+this.msg);
                let t = document.getElementById("app").innerHTML;
                console.log(t);
            },
            methods: {
                f1(){
                    this.msg="666"
                },
                f2(){
                    this.$destroy();
                }
            }
            
        });
    </script>
</body>
</html>

运行结果

image-20220305111715752

14、SpringBoot-Vue

html页面

优化前版本

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
    <script src="https://cdn.bootcss.com/axios/0.19.2/axios.min.js"></script>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/layer/3.1.1/layer.js"></script>
</head>
<body>
    <div id="app">
        <form>
            <input type="text" name="name" v-model="name"> <br>
            <input type="text" name="time" v-model="time"> <br>
            <input type="button" @click="add" value="添加">
        </form>
        <table>
            <tr>
                <td>Id</td>
                <td>姓名</td>
                <td>生日</td>
                <td>操作</td>
            </tr>
            <tr v-for="item in list">
                <td>{{item.id}}</td>
                <td>{{item.name}}</td>
                <td>{{item.time}}</td>
                <td>
<!--                    这里不要写delete-->
                    <button  @click="del(item.id)">删除</button>
                    |
                    <button @click="updateUI(item)">修改</button>
                </td>
            </tr>

        </table>

        <div id="up" style="display: none">
            <input type="hidden" name="id" v-model="id2"> <br>
            <input type="text" name="name" v-model="name2"> <br>
            <input type="text" name="time" v-model="time2"> <br>
            <button @click="updateContent">修改</button>
        </div>

    </div>



    <script>
        let vue = new Vue({
            el: "#app",
            data: {
                list:[],
                name:"",
                time:"",
                id2:"",
                time2:"",
                name2:"",
                w:""
            },
            created(){
                //这里有个坑: 这里的this才是vue的this     在beforeCreated发起会太早
               this.findAll();
            },
            methods: {
                add(){
                    let obj= {};
                    obj.name=this.name;
                    obj.time=this.time;
                    let json = JSON.stringify(obj);
                    let config = {
                        headers: {
                            "Content-Type":"application/json"
                        }
                    }
                    let self = this;
                    axios.post("http://localhost:8080/users",json,config).then(function (response){
                        self.name=self.time="";//添加后清空那里
                        self.findAll();
                    })
                },
                findAll(){
                    let self = this;
                    axios.get("http://localhost:8080/users").then(function (response){
                        console.log(response);
                        self.list=response.data.data;
                    })
                },
                del(id){
                    // alert("1");
                    let self = this;
                    axios.delete("http://localhost:8080/users/"+id).then(function (response){
                        console.log(response);
                        self.findAll();
                    }).catch(function (response){
                        console.log("异常")
                        console.log(response);
                    })
                },
                updateUI(u){
                    this.id2=u.id;
                    this.name2=u.name;
                    this.time2=u.time;
                    this.w = layer.open({
                        title: "修改用户",
                        type:1,
                        content: $("#up"),
                    });
                },
                updateContent(){
                    obj = {}
                    obj.id=this.id2;
                    obj.name=this.name2;
                    obj.time=this.time2;
                    let json = JSON.stringify(obj);
                    console.log(json+"!!!!!!!");
                    let config = {
                        headers: {
                            "Content-Type":"application/json"
                        }
                    }
                    let self = this;
                    axios.put("http://localhost:8080/users",json,config).then(function (response){
                        self.findAll();
                        self.id2=self.name2=self.time2="";//添加后清空那里
                        layer.close(self.w);
                    })
                }
            }
        });
    </script>
</body>
</html>

优化后版本

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
    <script src="https://cdn.bootcss.com/axios/0.19.2/axios.min.js"></script>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/layer/3.1.1/layer.js"></script>
</head>
<body>
    <div id="app">
        <form>
            <input type="text" name="name" v-model="saveForm.name"> <br>
            <input type="text" name="time" v-model="saveForm.time"> <br>
            <input type="button" @click="add" value="添加">
        </form>
        <table>
            <tr>
                <td>Id</td>
                <td>姓名</td>
                <td>生日</td>
                <td>操作</td>
            </tr>
            <tr v-for="item in list">
                <td>{{item.id}}</td>
                <td>{{item.name}}</td>
                <td>{{item.time}}</td>
                <td>
<!--                    这里不要写delete-->
                    <button  @click="del(item.id)">删除</button>
                    |
                    <button @click="updateUI(item)">修改</button>
                </td>
            </tr>

        </table>

        <div id="up" style="display: none">
            <input type="hidden" name="id" v-model="updateForm.id"> <br>
            <input type="text" name="name" v-model="updateForm.name"> <br>
            <input type="text" name="time" v-model="updateForm.time"> <br>
            <button @click="updateContent">修改</button>
        </div>

    </div>



    <script>
        //在每次发请求之前,会为请求地址加上这个前缀
        axios.defaults.baseURL = "http://localhost:8080/myProject/"

        //在每次发送请求之前,都会执行以下的代码,以下函数还接收一个参数
        //这个参数就是 axios.get(url,data,config) ,其中的第三个参数
        //最终返回什么样的config对象,请求就是用什么config配置
        axios.interceptors.request.use(function (config){
            config.headers.contentType = "application/json";
            return config;
        })
        let vue = new Vue({
            el: "#app",
            data: {
                list:[],
                saveForm:{
                    name:"",
                    time:"",
                },
                updateForm:{
                    id:"",
                    name:"",
                    time:"",
                },
                w:""
            },
            created(){
                //这里有个坑: 这里的this才是vue的this     在beforeCreated发起会太早
               this.findAll();
            },
            methods: {
                add(){
                    // let obj= {};
                    // obj.name=this.name;
                    // obj.time=this.time;
                    // let json = JSON.stringify(obj);
                    // let config = {
                    //     headers: {
                    //         "Content-Type":"application/json"
                    //     }
                    // }
                    let self = this;
                    axios.post("users",this.saveForm).then(function (response){
                        self.saveForm.name=self.saveForm.time="";//添加后清空那里
                        self.findAll();
                    })
                },
                findAll(){
                    let self = this;
                    axios.get("users").then(function (response){
                        // console.log(response);
                        self.list=response.data.data;
                    })
                },
                del(id){
                    let self = this;
                    axios.delete("users/"+id).then(function (response){
                        console.log(response);
                        self.findAll();
                    }).catch(function (response){
                        console.log("异常")
                        console.log(response);
                    })
                },
                updateUI(u){
                    this.updateForm.id=u.id;
                    this.updateForm.name=u.name;
                    this.updateForm.time=u.time;
                    this.w = layer.open({
                        title: "修改用户",
                        type:1,
                        content: $("#up"),
                    });
                },
                updateContent(){
                    // obj = {}
                    // obj.id=this.id2;
                    // obj.name=this.name2;
                    // obj.time=this.time2;
                    // let json = JSON.stringify(obj);
                    // console.log(json+"!!!!!!!");
                    // let config = {
                    //     headers: {
                    //         "Content-Type":"application/json"
                    //     }
                    // }
                    let self = this;
                    axios.put("users",this.updateForm).then(function (response){
                        self.findAll();
                        self.updateForm.id=self.updateForm.name=self.updateForm.time="";//添加后清空那里
                        //关闭窗口
                        layer.close(self.w);
                    })
                }
            }
        });
    </script>
</body>
</html>

15、Vue的组件

15.1 创建Vue组件的三种方式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
</head>
<body>
    <div id="app">
        {{msg}} !!!
        <!-- 若下面采用的驼峰命名的话,这里要改成这种命名 -  -->
        <my-component></my-component>
        <my-component2></my-component2>
        <my-component3></my-component3>
    </div>    
    <script>
        // 模块,就是一个可以重用的后台模块,比如:UserDao UserService
        // 组件,就是一个可以重用的UI零件。比如:登录UI,购物车UI,注册UI,排行榜UI。

        // Vue中,创建组件的三种方式。

        // 方式一:
        // 创建组件对象
        var component = Vue.extend({
            template: "<h3>组件1</h3>"
        });
        // 注册全局组件,注册组件以后,组件就有名字了,如下组件的名字就是myComponent
        // 使用组件的时候,必须把组件名myComponent,改为my-component。
        Vue.component("myComponent", component);


        // 方式二:
        // 直接注册一个全局组件,而不需要使用Vue.extend来创建组件对象
        Vue.component("myComponent2", {
            template: "<h3>组件2</h3>"
        });

    </script>

     <!-- 
        关于创建组件的方式三,要注意的地方:
        1. 在外部html中,定义组件的内容时,必须使用template元素 ,因为template默认情况下是隐藏的。
        只有在通过标记的形式使用组件的时候,template包裹的元素才显示出来!
        2. 作为组件的内容,只能有一个根元素! 以下的根元素不是template,而是div。
    -->
    <template id="t1">
        <div>
            <div>
                <h3>组件3</h3>
            </div>
            <div>
                <h3>hahahah</h3>
            </div>
        </div>
    </template>
    
    <script>

        // 方式三: 推荐使用
        // 注册一个全局组件,内容来自于外部html,而没有硬编码在组件中。
        Vue.component("myComponent3", {
            template: "#t1",
        });

        var app = new Vue({
            el: "#app",
            data: {
                msg: "test"
            }
        });
    </script>

   

</body>
</html>

15.2 Vue组件的属性和方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>

</head>
<body>
    <div id="app">
        {{msg}}
        <fieldset>
            <my-component></my-component>
        </fieldset>
        
    </div>
    
    <template id="t1">
        <div>
            我是子组件
            msg2: {{msg2}}
            <br>
            <button @click="f1">点点</button>
        </div>
    </template>
    <script>
        /*
            我们已经知道,Vue实例,是有属性和方法的
            Vue组件其实也是Vue实例,也就是说,Vue组件也可以拥有属性和方法!

            注意,Vue组件的属性,定义方式与Vue父组件的定义方式是不同的!
            Vue组件的属性,还是需要使用data来定义,但是
            1. data后面必须跟一个funcation
            2. 该function必须返回一个json
            3. 在该json中,写的才是子组件本身的属性!


            Vue组件的方法,定义的方式与父组件一样。没什么特殊的。

            要强调的是:父子组件之间不能直接调用对方的属性或方法。
        */
        Vue.component("myComponent",{
            template:"#t1",
            data(){
                return{
                    msg2:"我是子组件的属性额"
                }
            },
            methods:{
                f1(){
                    console.log("我是子组件的方法");
                }
            }
        })

        let vue = new Vue({
            el: "#app",
            data: {
                msg: "haha "
            }
        });
    </script>
</body>
</html>

15.3 Vue私有组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>

</head>
<body>
    <div id="app">
        父组件
        <fieldset>
             <foo></foo>
        </fieldset>
       
    </div>

    <template id="t1">
        <div>
            子组件 
            msg1: {{msg1}}
            msg2: {{msg2}}
            <br>
            <button @click="f1">点我</button>
        </div>
    </template>
    
    <script>
        let vue = new Vue({
            el:"#app",
            data: {

            },
            methods: {

            },
            components:{// 直接在Vue父组件中,注册Vue子组件。
                "foo": {
                    template:"#t1",
                    data(){
                        return {
                            msg1:"你猜我会不会变化",
                            msg2:"  我是子组件额!"
                        }
                    },
                    methods: {
                        f1(){
                            // 注意,这里的this,代表的是子组件,而不是父组件
                            this.msg1="你猜对了,我变了";
                        }
                    }
                }
            }
        });

    </script>
</body>
</html>

15.4 Vue组件的切换

15.4.1 Vue组件的切换方式1

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>

</head>
<body>
    <div id="app">
        <a @click="flag=true">登录</a>
        <a @click="flag=false">注册</a>
        <login-component v-if="flag"></login-component>
        <reg-component v-if="!flag"></reg-component>
    </div>

    <template id="t1">
        <div>
            msg1: {{msg1}}
        </div>
    </template>

    <template id="t2">
        <div>
            msg2:  {{msg2}}
        </div>
    </template>
    <script>
        let vue = new Vue({
            el: "#app",
            data: {
                flag:true
            },
            methods: {

            },
            components:{
                "loginComponent":{
                    template:"#t1",
                    data(){
                        return {
                            msg1:"我是登录额!!"
                        }
                    }
                },
                "regComponent":{
                    template: "#t2",
                    data(){
                        return {
                            msg2:"我是注册额!!!"
                        }
                    }
                }
            }
        });

    </script>
</body>
</html>

15.4.2 Vue组件的切换方式2

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>

</head>
<body>
    <div id="app">
        我是父组件
        <fieldset>
            <a @click.prevent="cname='loginComponent'">登录</a>
            <a @click.prevent="cname='regComponent'">注册</a>
            <a @click.prevent="cname='menuComponent'">菜单</a>
            <!-- <login-component></login-component>
            <reg-component></reg-component>
            <menu-component></menu-component> -->
             <!-- 
           component元素是Vue中定义好的一个元素 
           该元素的作用,等价于挖了一个坑,我们可以在这个坑中填组件!
           到底填什么组件,就有is属性决定,is属性后面写哪个组件的名字,在component这个位置显示什么组件
        -->
            <component :is="cname"></component>
            <component :is="cname"></component>
            
        </fieldset>
        
    </div>

    <template id="t1">
        <div>
            我是登录额!!
        </div>
    </template>

    <template id="t2">
        <div>
            我是注册额!!!!
        </div>
    </template>

    <template id="t3">
        <div>
            我是菜单额!!!!!!
        </div>
    </template>

    <script>
        let vue  = new Vue({
            el:"#app",
            data: {
                cname:"loginComponent"
            },
            methods: {

            },
            components: {
                "loginComponent":{
                    template:"#t1"
                },
                "regComponent":{
                    template:"#t2"
                },
                "menuComponent":{
                    template:"#t3"
                }
            }

        });
    </script>
</body>
</html>

15.5 Vue的子组件访问父组件

15.5.1 Vue的子组件访问父组件属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>

</head>
<body>
    <div id="app">
        我是父组件额: {{msg1}}
        <fieldset>
            <!-- 这里可以想一下之前 input 中的 :value="msg" -->
             <foo :aa="msg1"></foo>
        </fieldset>
       

    </div>

    <template id="t1">
        <div>
            <!-- msg1:{{msg1}} -->
            msg2:{{msg2}}
            访问父组件的属性: {{aa}}
        </div>
    </template>

    <script>
        /*
            我们已经知道,父子组件直接是不能直接相互访问对方的属性和方法的!
            该例子,就是讲解,子组件如何才能访问到父组件的属性和方法!(这里先不讨论父如何访问字的属性和方法)


            1. 子组件如何访问父组件的属性
                我们已经知道,子组件也是一个Vue的实例,也可以拥有自己的属性和方法。
                子组件的属性有2个来源,其一就是通过data来指定的,其二就是通过props来指定的。
                问题是,data定义的属性,是直接可以指定出属性值的,而props指定的属性,没有值!
                那么props指定的属性,如何才能确定属性值呢? 通过子组件的标记来传! 如果子组件的
                标记中传的是父组件的属性,那么子组件就能使用父组件的属性值了。

            2. 子组件如何访问父组件的方法

        */       
        let vue = new Vue({
            el:"#app",
            data: {
                msg1:"我是父组件额!!"
            },
            methods: {

            },
            components: {
                "foo": {
                    template:"#t1",
                    data(){
                        return {
                            msg2:"我是子组件额!!"
                        }
                    },
                    props:["aa"],
                },
               
            },
            
        });

    </script>
</body>
</html>

15.5.2 Vue的子组件访问父组件方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>

</head>
<body>
    <div id="app">
        我是父组件额: {{msg1}}
        <fieldset>
          <foo @abc="f1"></foo>
        </fieldset>
    </div>

    <template id="t1">
        <div>
            这里是子组件额
            <button @click="f2">点我调用父组件的方法额</button>
        </div>
    </template>

    <script>
        
        let vue = new Vue({
            el:"#app",
            data: {
                msg1:"我是父组件额!!"
            },
            methods: {
                f1(){
                    console.log("我是父组件的方法!!!");
                }
            },
            components: {
                "foo": {
                    template:"#t1",
                    methods: {
                        f2(){
                            console.log("我是子组件的方法!!!");
                            // 这里的this代表的是子组件本身,也可以说代表的就是子组件标记对象(<foo></foo>)
                            // 我们就可以通过这个代表子组件标记的对象,来触发标记上的任何事件
                            // 以下代码就是在触发<foo>标记上的abc事件
                            this.$emit("abc");
                        }
                    }
                },
               
            },
            
        });

    </script>
</body>
</html>

15.6 Vue的父组件访问子组件的属性和方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>

</head>
<body>
    <div id="app">
        我是父组件额
       
        <button @click="f1">查看子组件的属性</button>
        <br>
         {{msg1}}

        <fieldset>
            <foo ref="d1"></foo>
        </fieldset>
    </div>

    <template id="t1">
        <div>
            {{msg2}}
        </div>
    </template>

    <script>
        /*

            子组件访问父组件的属性: 通过子组件的props
            子组件访问父组件的方法: 通过子组件的$emit

            父组件访问子组件的属性:$refs
            父组件访问子组件的方法:$refs


        */
        let vue = new Vue({
            el:"#app",
            data:{
                msg1:"我是父组件!"
            },
            methods: {
                f1(){
                    this.msg1=this.$refs.d1.msg2;
                    this.$refs.d1.f1();
                }
            },
            components:{
                "foo":{
                    template:"#t1",
                    data(){
                        return {
                            msg2:"我是子组件!!!!!!!!!!!!!"
                        }
                    },
                    methods: {
                        f1(){
                            console.log("我是子组件的方法!!!");
                        }
                    }
                }
            }
        });

    </script>
</body>
</html>

15.7 Vue提供的如何获取DOM元素的API

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
</head>
<body>
    <div id="app">
       <div ref="d1">{{msg}}</div>
       <button @click="f1">点我</button>
    </div>    
    <script>
        /*
            我们已经知道,Vue不提倡我们直接进行DOM操作,Vue为我们制作了双向绑定的功能,
            就是为了把程序员从繁琐的DOM操作中解放出来! 
            
            但是,Vue毕竟的底层毕竟是js,我们当然能使用js的方式来操作DOM元素了。

            既然Vue不提倡我们直接使用document.getElementById()来过去一个元素,那么Vue
            一定提供了自己的方式,来获取DOm元素。
        */
        var app = new Vue({
            el: "#app",
            data : {
                msg: "九阴真经"
            },
            methods: {
               f1() {
                    // this.msg = "天之道,损有余而补不足。";

                    // var d1 = document.getElementById("d1");
                    // d1.innerHTML = "天之道,损有余而补不足!!!";


                    // this.$refs表示获取到当前Vue实例中,所有拥有ref属性的元素。
                    
                    this.$refs.d1.innerHTML = "天之道,损有余而补不足~~~";
               }
            }
        });
    </script>
</body>
</html>

总结:

子组件访问父组件的属性: 通过子组件的props

子组件访问父组件的方法: 通过子组件的$emit

父组件访问子组件的属性:$refs

父组件访问子组件的方法:$refs

子组件访问父组件应用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
</head>
<body>
    <div id="app">
        <div v-for="item in userList">
            <user-component :id="item.id" :name="item.name" :photo="item.photo"></user-component>
        </div>
    </div>

    <template id="userDiv">
        <div style="float: left; margin: 5px; width: 200px; border:#abcdef solid 1px">
            <table width="100%">
                <tr>
                    <td>id</td>
                    <td>{{id}}</td>
                </tr>
                <tr>
                    <td>name</td>
                    <td>{{name}}</td>
                </tr>
                <tr>
                    <td>photo</td>
                    <td>
                        <img :src="'img/'+ photo" width="100" height="75" />
                    </td>
                </tr>
            </table>
        </div>
    </template>

    <script>
        var app = new Vue({
            el: "#app",
            data: {
                userList: [
                    {id:1, name:"张三",photo:"1.jpg"},
                    {id:2, name:"李四",photo:"2.jpg"},
                    {id:3, name:"王五",photo:"3.jpg"},
                ]
            },
            components: {
                "userComponent": {
                    template: "#userDiv",
                    props:['id', 'name', 'photo']
                }
            }
        });
    </script>

</body>
</html>

16、Vue路由

16.1 Vue快速起步

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
    <!-- 一旦引入vue-router,在浏览器的内存中,就会多一个构造器:VueRouter-->
    <script src="https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js"></script>
    <style>
        a {
            text-decoration: none;
        }
        .router-link-active {
            background-color: #abcdef;
            color: white;
        }
    </style>
</head>
<body>
    <div id="app">
        <!-- <a href="#/login">去登录</a>
        <a href="#/reg">去注册</a> -->
        <router-link to="login">去登录</router-link>
        <router-link to="reg">去注册</router-link>
        <router-link to="index">去首页</router-link>

        <!-- 
            占位符,该位置专门用来显示,路由对象中注册过的组件 
            究竟显示哪一个组件,就取决于url地址了。
        -->
        <router-view></router-view>
        
    </div>

    <template id="t1">
        <div>
            登录UI
        </div>
    </template>

    <template id="t2">
        <div>
            注册UI
        </div>
    </template>

    <template id="t3">
        <div>
            首页UI
        </div>
    </template>

   
    <script>

        /*
            路由:就是选择的意思。Vue的路由,只是概念上的路由。 
            Vue的路由,就是用来选择组件(切换组件的)。

            有了Vue的路由以后,就不再将组件注册在Vue父组件中了,而是将组件注册给Vue的路由器对象!
            而且是一边注册组件,一边写出组件对应的路径。

            最后,将路由器对象,整个注册给Vue父组件。


            路由运行原理:
            1. 浏览器地址栏发生变化
            2. Vue路由器就会“感知”这个地址的变化,并且拿着新的地址,去与路由中所注册的地址比较
            3. 如果找到匹配的地址了,就能找到对应的组件,就进入下一步。 如果找不到,就不显示任何内容。
            4. 再找到组件的上一级组件,并且在上级组件中找位置,位置就是<router-view>标记,然后就显示。
        */

        // 这里是定义组件
        let loginComponent = {
            template:"#t1"
        }

        let regComponent = {
            template:"#t2"
        }

        let menuComponent = {
            template:"#t3"
        }

        let router = new VueRouter({
            // 在路由器对象中,注册组件
            routes:[
                {component:loginComponent,path:"/login"},
                {component:regComponent,path:"/reg"},
                {component:menuComponent,path:"/index"}
            ]
        });

        var app = new Vue({
            el: "#app",
            router      // 等价于router:router
        });
    </script>

    <marquee>
        飞雪
    </marquee>
</body>
</html>

16.2 Vue二级路由

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
    <script src="https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js"></script>
</head>
<body>
    <div id="app">
        <router-link to="/user">用户管理</router-link>
        <router-link to="/car">汽车管理</router-link>
        <router-view></router-view>
    </div>

    <template id="t1">
        <div>
            用户管理界面 <br>
            <router-link to="/user/add">添加用户</router-link>
            <router-link to="/user/find">查看用户</router-link>
            <router-view></router-view>
        </div>
    </template>

    <template id="t1_1">
        <div>
            添加用户界面:
            name: <input type="text">
            <button>add user</button>
        </div>
    </template>

    <template id="t1_2">
        <div>
            查看用户界面:
            1 -- 张三 -- 22岁 <br>
            2 -- 李四 -- 23岁 <br>
            3 -- 王五 -- 24岁 <br>
        </div>
    </template>


    <template id="t2">
        <div>
            汽车管理界面
        </div>
    </template>

    <script>

        var userComponent = {
            template: "#t1"
        };
        var userAddComponent = {
            template: "#t1_1"
        };
        var userFindComponent = {
            template: "#t1_2"
        };


        var carComponent = {
            template: "#t2"
        }; 

        var router = new VueRouter({
            routes: [
                {
                    component: userComponent, path: "/user",     
                    children: [
                        {component: userAddComponent, path:"/user/add"},    
                        {component: userFindComponent, path:"/user/find"}   
                    ]
                },
                {component: carComponent, path:"/car"} 
            ]
        });

        var app = new Vue({
            el: "#app",
            router
        });
    </script>
</body>
</html>
posted @ 2022-03-05 00:49  后端小知识  阅读(32)  评论(0编辑  收藏  举报
返回顶端