VUE语法入门

作者: CJ21 | 来源:发表于2021-05-03 23:42 被阅读0次

一、HelloWorld

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
</head>
<body>
    <!--将数据渲染到页面上-->
    <div id="app">
        <p>{{title}}</p>
        {{fn1()}}
        {{age}}
        <p>{{age>18?'成年':'未成年'}}</p>
       
        <button v-on:click="fn3()">按钮</button>
    </div>
    
    <!--引入js  "https://cdn.jsdelivr.net/npm/vue/dist/vue.js"-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    var vm = new Vue({
        el:'#app',
        data: {
            title:'helloworld',
            age:15
        },
        methods:{
            fn1:function(){
                console.log("方法调用成功");
            },
            fn2:function(){
                console.log(this)
            },
            fn3:function(){
                this.age=20
            }
        }
    })

    console.log(vm.title)
    console.log(vm.$data.title)
    console.log(vm)
    vm.fn1()
    vm.fn2()
</script>

</body>
</html>

二、阻止表单提交

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <form  action="save" v-on:submit.prevent="fn1()">
            <input type="text" id="username" v-model="user.username"></input>
            <button type="submit">保存</button>
        </form>
        {{user}}
    </div>
    <script src="vue.js"></script>
    <!-- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> -->
    <script>
        // 创建一个vue对象
        new Vue({
            el: '#app',
            data: {
                user: {username:"CJ",age:28}
            },
            methods:{
                fn1(){
                    if (!this.user.username){
                        alert("请输入用户名")
                    }else{
                        console.log(this.user.username)
                    }
                }
            }
        })
    </script>
</body>
</html>

<!-- 事件修饰符包括 .stop .prevent .capture .self .once .passive -->

三、v-test和v-html

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
</head>
<body>
    <div id="app">
        <!--都可以替换标签的全部内容,区别是v-test不能识别字符串中的标签,v-html可以识别字符串中的标签-->
        <p v-text="alert">123</p>
        <p v-html="alert">321</p>
    </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            title: "替换后的数",
            str: "<span style='color:blue'>替换后的数</span>",
            alert: '<span onclick="alert(1)">span标签</sapn>'
        }

    })
</script>

</body>
</html>

四、v-if和v-show

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
</head>
<body>
    <div id="app">
        <!-- 通过v-if判断条件是否符合,符合则展示标签中的内容 -->
        <p v-if="type ==='A'">{{str1}}</p>
        <p v-else-if="type ==='B'">{{str2}}</p>
        <p v-else>{{str3}}</p>
        <p>{{type}}</p>
        <button @click="fn1()">buttonA</button>
        <button v-on:click="fn2()">buttonB</button>
        <!-- v-show和v-if类似,判断是否符合条件,通过切换标签display属性来展示或隐藏标签 -->
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                str1:"type是A",
                str2:"type是B",
                str3:"type不是AB",
                type:"A"
            },
            methods:{
                fn1(){
                    this.type="B"
                },
                fn2(){
                    this.type="C"
                }
            }
        })
    </script>
</body>
</html>

五、v-on和$event

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
</head>
<body>
    
    <div id="app">
        <!-- $event代表当前事件 -->
        <button @click="fn1($event)">控制台打印事件</button>
        <br>
        <br>
        <!-- @事件名.修饰符="methods中的方法"  once和prevent最常用-->
        <button @click.once="fn2('once,只能调用一次')">打印文本</button>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var vm = new Vue({
            el:'#app',
            data:{

            },
            methods:{
                fn1(e){
                    console.log(e)
                },
                fn2(s){
                    console.log(s)
                }
            }
        })
    </script>

</body>
</html>

六、v-for

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
</head>
<body>
    <div id="app">
        <ul>
            <li v-for="item in list">{{item}}</li>
            <br>
            <!-- list类型数组,可以取到每个元素的值和下标 -->
            <li v-for="(item,index) in list">{{item}}---{{index}}</li>
            <br>
            <!-- per类型键值对数据,其结构为value、(value,key)和(value,key,index) -->
            <li v-for="(v,k,i) in per">{{k}}--{{v}}--{{i}}</li>
        </ul>
        <!--除了表格遍历,也可以用<p>标签-->
        <br>
        <p v-for="(v,k,i) in per">{{k}}--{{v}}--{{i}}</p>
        <br>
        <url>
            <!-- key标签中的值是唯一的,作用是:vue渲染页面的时,根据key的标识找到每个元素,效率更高 -->
            <li v-for="(v,k,i) in per" :key="i">{{v}}</li>
        </url>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var vm = new Vue({
            el: '#app',
            data:{
                list:['查找','增加','修改','删除'],
                per:{
                    id:1,
                    name:'zhangsan',
                    age:'29',
                    gender:'male'
                }
            }
        })
    </script>
</body>
</html>

七、v-bind

7.1 v-bind.html

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
</head>
<body>
    <!-- v-bind
    作用:绑定标签的任何属性
    场景:当标签的属性值是不确定的,可以修改
    语法:v-bind:要绑定的属性名="data中的数据"
    简写:去掉v-bind,直接 :src 即可
    -->
    <div id="app">
        <p v-bind:id="ID">内容</p>
        <img :src="SRC" alt="蒸虾">

        <!-- 特殊情况是class和style属性,可以有多个值 -->
        <!-- 绑定class方式一:如果为类名为true则生效,类名为false则失效 -->
        <p :class="{name1:a,name2:b}">判断类名是否有效</p>
        <!-- 绑定class方式二:通过给类名变量赋值,传入类名 -->
        <p :class="[n1,n2]">为类名变量赋值</p>
        <!-- 绑定class方式三:整合上两种方式,给类名变量赋值,参数类型为tuple,为true则生效,为false则失效 -->
        <p :class="[nObj1,nObj2]"></p>

        <!-- 绑定style方式一 通过变量为syle属性赋值 -->
        <p :style="{fontSize:f,color:c}">style方式一</p>
        <!-- 绑定style方式二  -->
        <p :style="[d,e]">style方式二</p>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var vm = new Vue({
            el: "#app",
            data:{
                ID:'newID',
                SRC:"http://116.62.148.11:81/menulist/zhengxia/zhengxia.png",
                a:true,
                b:false,
                n1:"name1",
                n2:"name2",
                nObj1:{
                    name1:false
                },
                nObj2:{
                    name2:true
                },

                f:'30px',
                c:'red',
                d:{
                    fontSize:'30px'
                },
                e:{
                    color:'pink'
                }
            }
        })
    </script>
</body>
</html>

7.2 v-bind_exam

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
</head>
<style>
    .name{
        color:tomato
    }
</style>
<body>
    <div id="app">
        <p :class="{name:a}">内容</p>
        <button v-on:click="reverseBool()">按钮</button>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        new Vue({
            el:'#app',
            data:{
                a:true
            },
            methods:{
                reverseBool(){
                    this.a = !this.a
                }
            }
        })
    </script>

</body>
</html>

<!--
    动态切换class名:
    1.通过v-bind指令给标签绑定类名,在data中指定变量类型。
    2.设置按钮绑定事件,如果点击按钮会改变类名
    3.如果类名匹配上style中的类名,字体颜色发生改变。

    技巧:可以直接用@click="a=!a" 在指令中设置取反,而不用再写函数。
-->

八、v-model

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
</head>
<body>
    <!-- v-model用于表单元素的绑定,表单中元素变化会导致v-model绑定的变量变化 -->
<div id="app">
    {{name}}:
    <input type="text" v-model="name">
    <br>
    <!-- 其他表单元素,多行、单选、复选、下拉等等 -->
    <!-- 多行表单 -->
    {{msg}}
    <textarea v-model="msg"></textarea>
    <br>
    <!-- 单个复选框,绑定bool值 -->
    {{check}}
    <input type="checkbox" v-model="check">
    <br>
    <!-- 多个复选框,绑定数组,数组中会放入选中框的value值 -->
    {{checklist}}
    <input type="checkbox" value="male" v-model="checklist">M
    <input type="checkbox" value="female" v-model="checklist">F
    <input type="checkbox" value="other" v-model="checklist">O
    <br>
    <!-- 单选框,绑定字符串,字符串会被赋值选定的框的value值 -->
    {{picked}}
    <input type="radio" value="查找" v-model="picked">A
    <input type="radio" value="删除" v-model="picked">B
    <br>
    <!-- 下拉框,绑定字符串,字符串会被赋值选定的框的value值 -->
    {{select}}
    <select v-model="select">
        <!-- disabled表示无法选中,select和value为一样都为空,则显示该标签的内容 -->
        <option disabled value="">请选择</option>
        <option value="北京">北京</option>
        <option value="上海">上海</option>
        <option value="杭州">杭州</option>
    </select>

</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    var vm = new Vue({
        el: "#app",
        data:{
            name: 'name',
            msg: '多行输入框',
            check: true,
            checklist: ["female"],
            picked:'',
            select:''
        }
    })
</script>

</body>
</html>

九、v-cloak和v-once

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
    <style>
        [v-cloak]{
            display: none;
        }
    </style>
</head>
<body>
    <div id="app">
        <!-- 解决插值表达式{{}}页面闪烁的问题 
        1.给闪烁的标签设置v-clock
        2.在style样式中指定display为none
        备注:可以直接给div标签添加v-clock属性,即<div id="app" v-cloak>,标签的内容都不会闪烁
        -->
        <p v-cloak>{{msg}}</p>

        <!-- 标签只需要渲染一次,添加v-once指令。那么msg值改变也不会重新渲染 -->
        <p v-once>{{msg}}</p>
        <input type="text" v-model="msg">

    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        new Vue({
            el:"#app",
            data:{
                msg:'解决插值表达式{{}}页面闪烁的问题'
            }
        })
    </script>
</body>
</html>

十、example

10.1 example.html

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale">
    <!-- border-collapse有两个属性separate/collapse,决定表格的边框是分开的还是合并的 -->
    <style>
        #app {
            width: 600xp;
            margin: 10px auto;
        }

        .tb {
            border-collapse: collapse;
            width: 100%;
        }

        .tb th {
            background-color: #0094ff;
            color: white;
        }

        .tb td,
        .tb th {
            padding: 5px;
            border: 1px solid black;
            text-align: center;
        }

        .add {
            padding: 5px;
            border: 1px solid black;
            margin-bottom: 20px;
        }
    </style>
</head>
<body>
    <!-- <div id="app"> -->
        <div class="add">
            品牌名称:
            <input type="text">
            <input type="button" value="添加">
        </div>

        <div class="add">
            品牌名称:
            <!-- placeholder是占位符 -->
            <input type="text" placeholder="请输入搜索条件">
        </div>

        <div>
            <table class="tb">
                <tr>
                    <!-- th标签会将文本加粗显示 -->
                    <th>编号</th>
                    <th>品牌名称</th>
                    <th>创立时间</th>
                    <th>操作</th>
                </tr>
                <tr>
                    <td>1</td>
                    <td>LV</td>
                    <td>2020-1-1</td>
                    <td>
                        <!-- href是超链接属性,#是无意义的,但是会将文本以超链接的形式展示 -->
                        <a href="#">删除</a>
                    </td>
                </tr>
                <tr>
                    <!-- colspan合并四个单元格 -->
                    <td colspan="4">没有品牌数据</td>
                </tr>
            </table>
        </div>

  <!--  </div>
     <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>

    </script> -->

</body>
</html>

10.2 example_with_vue.html

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale">
    <!-- border-collapse有两个属性separate/collapse,决定表格的边框是分开的还是合并的 -->
    <style>
        #app {
            width: 600xp;
            margin: 10px auto;
        }

        .tb {
            border-collapse: collapse;
            width: 100%;
        }

        .tb th {
            background-color: #0094ff;
            color: white;
        }

        .tb td,
        .tb th {
            padding: 5px;
            border: 1px solid black;
            text-align: center;
        }

        .add {
            padding: 5px;
            border: 1px solid black;
            margin-bottom: 20px;
        }
    </style>
</head>
<body>
    <div id="app">
        <div class="add">
            品牌名称:
            <input type="text" v-model="itemname">
            <input type="button" value="添加" v-on:click="addItem()">
        </div>

        <div class="add">
            品牌名称:
            <!-- placeholder是占位符 -->
            <input type="text" placeholder="请输入搜索条件" v-model="keyword">
        </div>

        <div>
            <table class="tb">
                <tr>
                    <!-- th标签会将文本加粗显示 -->
                    <th>编号</th>
                    <th>品牌名称</th>
                    <th>创立时间</th>
                    <th>操作</th>
                </tr>
                <tr v-for="(item,index) in newlist">
                    <td>{{index+1}}</td>
                    <td>{{item.name}}</td>
                    <td>{{item.date}}</td>
                    <td>
                        <!-- href是超链接属性,#是无意义的,但是会将文本以超链接的形式展示 -->
                        <a href="#" v-on:click.prevent="deleteItem(index)">删除</a>
                    </td>
                </tr>
                <tr v-if="list.length === 0">
                    <!-- colspan合并四个单元格 -->
                    <td colspan="4">没有品牌数据</td>
                </tr>
            </table>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        //模拟ajax返回的数据
        var list = [
            {
                name:'TCL',date:new Date()
            },{
                name:'huawei',date:new Date()
            },{
                name:'xiaomi',date:new Date()
            }
            ]

        var vm = new Vue({
            el: "#app",
            data: {
                list,
                itemname:'',
                keyword:''
            },
            methods:{
                addItem(){
                    //向数组中添加数据
                    this.list.unshift({
                        name:this.itemname,
                        date:new Date()
                        })
                },
                deleteItem(index){
                    if(confirm("确认删除?")){
                        //从数组中删除数据,传参为(索引,长度)
                        this.list.splice(index,1)
                    }
                }
            },
            computed:{
                newlist(){
                    return this.list.filter(item => {
                        return item.name.startsWith(this.keyword)
                    })
                }
            }
        })
    </script>

</body>
</html>

<!--
    整合vue步骤:
    1.在视图中添加div#app
    2.引入vue.js
    3.new Vue({})
    4.Vue实例的选项:el data
    5.在视图中 通过{{}}使用data中的数据
-->
<!--
    渲染步骤:
    1.在data中定义数据
    2.通过v-for指令插入到表格中
    3.在视图中通过插值表达式{{}}使用数据
    4.通过v-if指令判断数据是否存在,如果不存在则显示没有品牌数据
-->
<!--
    添加商品功能:
    1.找到输入框标签,添加v-model="itemname"指令,绑定data中的itemname变量
    2.找到添加按钮 绑定事件 @click="addItem()",在methods中提供addItem方法,
    向list添加接收到的数据
-->
<!--
    商品删除功能:
    1.找到商品删除标签,添加绑定事件@click.prevent="deleteItem()",
    prevent组织默认行为,此处为跳转连接,仅执行click绑定的方法;
    在methods中提供deleteItem()方法,从list中删除指定的数据,
    可以调用confirm方法弹出确认框。
-->
<!--
    商品搜索功能(输入一个搜索词直接响应结果):
    1.定义变量通过v-model指令接受输入的搜索词
    2.设置计算属性,通过filter()方法对原数组的元素进行筛选,返回筛选后的数组
    3.通过v-for指令遍历数据渲染到页面
-->

10.3 example_with_axios.html

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale">
    <!-- border-collapse有两个属性separate/collapse,决定表格的边框是分开的还是合并的 -->
    <style>
        #app {
            width: 600xp;
            margin: 10px auto;
        }

        .tb {
            border-collapse: collapse;
            width: 100%;
        }

        .tb th {
            background-color: #0094ff;
            color: white;
        }

        .tb td,
        .tb th {
            padding: 5px;
            border: 1px solid black;
            text-align: center;
        }

        .add {
            padding: 5px;
            border: 1px solid black;
            margin-bottom: 20px;
        }

        [v-cloak]{
            display: none;
        }
    </style>
</head>
<body>
    <div id="app" v-cloak>
        <div class="add">
            品牌名称:
            <input type="text" v-model="itemname">
            <input type="button" value="添加" v-on:click="addItem()">
            <br>
            {{itemname}}
        </div>

        <div class="add">
            品牌名称:
            <!-- placeholder是占位符 -->
            <input type="text" placeholder="请输入搜索条件" v-model="keyword">
        </div>

        <div>
            <table class="tb">
                <tr>
                    <!-- th标签会将文本加粗显示 -->
                    <th>id</th>
                    <th>view_url</th>
                    <th>view_link</th>
                    <th>sequence</th>
                    <th>publish_status</th>
                    <th>create_time</th>
                    <th>update_time</th>
                </tr>
                <tr v-for="(item,index) in newlist">
                    <td>{{item.id}}</td>
                    <td>{{item.viewUrl}}</td>
                    <td>{{item.viewLink}}</td>
                    <td>{{item.sequence}}</td>
                    <td>{{item.publishStatus}}</td>
                    <td>{{item.createTime}}</td>
                    <td>{{item.updateTime}}</td>
                    <td>
                        <!-- href是超链接属性,#是无意义的,但是会将文本以超链接的形式展示 -->
                        <a href="#" v-on:click.prevent="deleteItem(item.id)">删除</a>
                    </td>
                </tr>
                <tr v-if="newlist.length === 0">
                    <!-- colspan合并四个单元格 -->
                    <td colspan="8">没有品牌数据</td>
                </tr>
            </table>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                list:[],
                itemname:'',
                keyword:'',
                viewpager:[]
            },
            methods:{
                addItem(){
                    //发送添加数据请求
                    axios.post("http://192.168.32.223:8002/menu/addViewPager/",this.itemname)
                        .then((res)=>{
                            const{status,data} = res
                            if(status === 200){
                                alert(this.itemname+"---添加成功")
                                this.findAllViewPager()
                            }
                        })
                        .catch((err)=>{

                        })                    
                },
                deleteItem(id){
                    if(confirm("确认删除?")){
                        //发送删除数据请求,传参为(索引,长度),并重新获取数据
                        axios.delete("http://192.168.32.223:8002/menu/deleteViewPager?viewPagerId="+id)
                        .then((res)=>{
                            const{status,data} = res
                            if(status === 200){
                                alert("删除成功")
                                this.findAllViewPager()
                            }
                        })
                        .catch((err)=>{

                        })
                    }
                },
                //通过axios获取后台数据
                findAllViewPager(){
                    axios.get("http://192.168.32.223:8002/menu/findAllViewPager")
                        .then((res)=>{
                            const{status,data} = res
                            console.log(data)
                            if(status === 200){
                                this.viewpager=data.data
                            }
                        })
                        .catch((err)=>{
                            console.log(err)
                        })
                }
            },
            computed:{
                newlist(){
                    return this.viewpager.filter(item => {
                        return item.viewLink.startsWith(this.keyword)
                    })
                }
            },
            created(){
            // mounted(){
                this.findAllViewPager()
            }
        })
    </script>

</body>
</html>

<!--
    整合vue步骤:
    1.在视图中添加div#app
    2.引入vue.js
    3.new Vue({})
    4.Vue实例的选项:el data
    5.在视图中 通过{{}}使用data中的数据
-->
<!--
    渲染步骤:
    1.在data中定义数据
    2.通过v-for指令插入到表格中
    3.在视图中通过插值表达式{{}}使用数据
    4.通过v-if指令判断数据是否存在,如果不存在则显示没有品牌数据
-->
<!--
    添加商品功能:
    1.找到输入框标签,添加v-model="itemname"指令,绑定data中的itemname变量
    2.找到添加按钮 绑定事件 @click="addItem()",在methods中提供addItem方法,
    向list添加接收到的数据
-->
<!--
    商品删除功能:
    1.找到商品删除标签,添加绑定事件@click.prevent="deleteItem()",
    prevent组织默认行为,此处为跳转连接,仅执行click绑定的方法;
    在methods中提供deleteItem()方法,从list中删除指定的数据,
    可以调用confirm方法弹出确认框。
-->
<!--
    商品搜索功能(输入一个搜索词直接响应结果):
    1.定义变量通过v-model指令接受输入的搜索词
    2.设置计算属性,通过filter()方法对原数组的元素进行筛选,返回筛选后的数组
    3.通过v-for指令遍历数据渲染到页面
-->
<!-- 
    通过axios对viewpager进行增删改查操作:
    ①查:创建axios请求方法,将结果赋值给变量,通过mounted调用该方法,将结果进行遍历
    ②增:
 -->

十一、mounted自动获取焦点

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <!-- 需要给dom元素设置ref属性,mounted方法可以更加ref属性拿到对应的dom -->
        <input type="text" ref="foc">        
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        new Vue({
            el: "#app",
            data:{

            },
            methods:{

            },
            //该方法会在页面渲染完成后调用,取到对应名字的dom,调用focus方法完成自动聚焦
            mounted(){
                console.log(this.$refs.foc)
                this.$refs.foc.focus()
            }
        })
    </script>
</body>
</html>

十二、插件

12.1 自定义插件

定义插件

(function (window)){
  const MyPlugin = {}
  MyPlugin.install = function(Vue) {
    //1.定义一个全局方法
    Vue.myGlobalMethod = function(){
      console.log('全局的方法')
    }
    //2.定义一个指令
    Vue.directive('upper',function(el,binding){
      console.log('哈哈')
    })
    //3.定义一个实例方法
    Vue.prototype.$myMethod = function(){
      console.log('我是一个实例方法')
    }
  }

  //暴露出
  window.MyPlugin = MyPlugin
}(window)

使用插件

<body>
  <div id="app">
    <p v-upper="msg"></p>
  </div>

  <script src="./vue-myPlugin.js"></script>
  <script type="text/javascript">
    //Vue.use 内部会安装插件,内部调用install
    Vue.use(MyPlugin)
    //可以调用全局的方法
    Vue.myGlobalMethod()
    //局部方法的调用
    const vm = new Vue({
      el: "#app",
      data: {
        msg: ''
      }
    })
    vm.$myMethod()
  </script>

12.2 directives自定义focus指令_全局

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <input type="text" v-focus>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        //全局自定义指令(设置自定义聚焦指令v-focus)
        //1.在new Vue之前,Vue.directive('指令名',{inserted(el){}})
        //2.inserted(el){自定义指令具体功能}
        //使用该指令的dom元素被插入到页面汇中时,会自动触发inserted
        //3.在视图中v-指令名
        //获取焦点
        Vue.directive('focus',{
                inserted(el){
                    console.log(el)
                    el.focus()
                }
        })
        new Vue({
            el: "#app"
        })
    </script>
</body>
</html>

12.3 directives自定义focus指令_局部

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <input type="text" v-focus>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        new Vue({
            el:"#app",
            data:{

            },
            directives:{
                focus:{
                    inserted(el){
                        console.log(el)
                        el.focus()
                    }
                }
            }
        })
    </script>
</body>
</html>

<!-- 局部指令只能在绑定的DOM中使用,全局指令可以在任何DOM中使用 -->

十三、过滤器

13.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>
    <style>
        [v-cloak]{
            display: none;
        }
    </style>
</head>
<body>
    <div id="app" v-cloak>
        <p>{{msg | toUpper}}</p>
        <p>{{date | fmtDate("日期:")}}</p>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/moment"></script>
    <script>
        //全局过滤器,可以使用在插值{{}}和v-bind中
        //需要定义在new Vue之前
        Vue.filter('toUpper',(v)=>{
            return v.toUpperCase()
        })
        Vue.filter('fmtDate',(v,k)=>{
            return k + moment(v).format('YYYY-MM-DD hh:mm:ss')
            // return dateFormat("YYYY-MM-DD hh:mm:ss",this.date)
        })

        new Vue({
            el:"#app",
            data:{
                msg:"abc",
                date:new Date()
            }
        })
    </script>
</body>
</html>

13.2 过滤器_局部

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        [v-cloak]{
            display: none;
        }
    </style>
</head>
<body>
    <div id="app" v-cloak>
        <p>{{date | fmtDate("date:")}}</p>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/moment"></script>
    <script>
        new Vue({
            el:"#app",
            data:{
                date:new Date()
            },
            filters:{
                //第一个参数是传入的值,后续是自定义参数
                fmtDate(v,k){
                    return k + moment(v).format('YYYY-MM-DD hh:mm:ss')
                }
            }
        })
    </script>
</body>
</html>

十四、计算属性和watch监视

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <!-- 调用计算属性 -->
        <p>{{reverseMessage}}</p>
        <input type="text" placeholder="显示计算后的结果" v-model="reverseMessage"></input>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        new Vue({
            el:"#app",
            data:{
                msg:"hello world !",
                reverseMessage1,
                reverseMessage2
            },
            //如果没有依赖data中的数据,第一次使用计算属性时,会把第一次的结果进行缓存。
            computed:{
                //定义计算方法
                reverseMessage(){
                    //this是指当前的vue对象,此处表示计算属性的get方法
                    return this.msg.split(' ').reverse().join(' ')
                },
                reverseMessage1(){
                    //计算属性包括get和set方法
                    get(){
                        return this.msg.split(' ').reverse().join(' ') 
                    },
                    set(val){
                        //val就是传入的reverseMessage1的值,当改变计算属性的值时,会调用该方法处理逻辑。
                        const m=val.split(' ')
                        this.msg=m.reverse().join(' ')
                    }
                }
            },
            //监视:监视msg,如果msg改变,则调用该方法处理逻辑
            watch: {
              msg(val){
                  this.reverseMessage1=val.split(' ').reverse().join(' ')
              }
            }
        })
        //通过vm实例对象来调用watch方法进行监视。$watch是vue的一个实例属性,vue有许多实例属性和实例方法。如果没有$符号,说明是全局属性方法。
        vm.$watch('msg',function(val){
            this.reverseMessage2=val.split(' ').reverse().join(' ')
        })
    </script>

</body>
</html>
<!-- 计算属性:当某个属性的值改变,何其相关联的属性的值也会自动发生改变 -->
<!-- 使用Object.defineProperty(obj, prop, descriptor)可以为已经定义的对象类添加计算属性,设置set和get方法,当属性发生变化时, -->
<!-- 搜索MDN网站可以查询到所有的前端方法的使用 -->
<!-- 计算属性和监视都可以实现某属性发生改变,另一个属性也发生变化的情况。 -->

十五、axios

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">

    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script>
        //get请求
        axios.get("http://192.168.32.223:8002/menu/findViewPager")
            .then((res)=>{
                //console.log(res)
                const{status,data} = res
                if(status===200){
                    console.log(data)
                }
            })
            .catch((err)=>{})
        // post请求
        // axios.post("http://192.168.32.223:8002/menu/addViewPager/",{
        //             "viewUrl": "https://192.168.32.223/hxr.png",
        //             "viewLink": "https://www.marssenger.com/welcome.html",
        //             "sequence": "7",
        //             "publishStatus": "1"
        //         })
        //         .then((res)=>{
        //             const{status,data} = res
        //             if(status===200){
        //                 console.log("添加成功")
        //             }
        //         })
        //         .catch((err)=>{
                    
        //         })
        
        //delete请求
        // axios.delete("http://192.168.32.223:8002/menu/deleteViewPager?viewPagerId=74")
        //         .then((res)=>{
        //             const{status,data} = res
        //             if(status === 200){
        //                 console.log("删除成功")
        //             }
        //         })
        //         .catch((err)=>{

        //         })

        new Vue({
            el: "#app",
            data:{

            }
        })
    </script>

</body>
</html>

十六、异步操作和watch

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <input type="text" v-model="msg">
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        new Vue({ 
            el: "#app",
            data: {
                msg: ''
            },
            //watch可以监测已经存在的属性,记录新值和旧值
            //使用场景:当需要在数据变化时执行异步或开销比较大的操作时使用(如进行关键字搜索时,就需要watch监控输入的关键字变化,检测到关键字变化就通过关键字发送请求)
            watch: {
                msg(newVal,oldVal){
                    console.log(newVal,oldVal);
                }
            }
        })
    </script>
</body>
</html>

<!--
    异步操作包括1.ajax 2.定时器 3.click事件 4.数据库操作
-->

十七、component组件

17.1 component组件_全局

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <span-btn></span-btn>
        <span-btn></span-btn>
        <span-btn></span-btn>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        //全局组件:1.在newVue之前定义 2.命名规范:xxx-xx 3.全局组件可以用在局部组件中
        //将共同的结构提取出来创建组件,组件可以复用,组件之间相互独立
        //组件可以让我们复用已有的html、css、js
        Vue.component('span-btn',{
            template:
                //要求有一个根元素
                `
                <div>
                <span>{{count}}</span> 
                <button v-on:click="changeCount">按钮</button>
                <br>
                </div>
                `
                ,
            //data数据必须是一个函数且只有一个返回值,这样每个组件的数据都有自己的作用域
            data(){
                return{
                    count:0
                }
            },
            methods:{
                changeCount(){
                    this.count++
                }
            }
        });

        new Vue({
            el:"#app"
        })
    </script>
</body>
</html>

17.2 component组件_局部

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <span-btn></span-btn>
        <span-btn></span-btn>
        <span-btn></span-btn>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
    
        new Vue({
            el:"#app",
            data:{

            },
            components:{
                //局部组件:1.在newVue之内定义 2.命名规范:xxx-xx 3.可以在局部组件中调用全局组件
                //将共同的结构提取出来创建组件,组件可以复用,组件之间相互独立
                //组件可以让我们复用已有的html、css、js
                'span-btn':{
                    template:
                        //要求有一个根元素
                        `
                        <div>
                            <span>{{count}}</span> 
                            <button v-on:click="changeCount">button</button>
                            <br>
                        </div>
                        `
                        ,
                    //data数据必须是一个函数且只有一个返回值,这样每个组件的数据都有自己的作用域
                    data(){
                        return{
                            count:0
                        }
                    },
                    methods:{
                        changeCount(){
                            this.count++
                        }
                    }
                }
            }
        })
    </script>
</body>
</html>

十八、父子组件数据传递

18.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>
</head>
<body>
    <div id="app">
        <child-a v-bind:a="msg"></child-a>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        //情况一:父组件传值给子组件,自组价为全局组件
        Vue.component("child-a",{
            template:
            `
                <div>我是childa子组件--{{a}}</div>
            `,
            //通过data函数定义的值的作用域在自己对象中
            //props选项设置标签的属性,可以在标签中传值
            //props中的属性可以在组件中使用
            props:['a']
        })

        //Vue相当于所有组件的父组件
        new Vue({
            el:"#app",
            data:{
                msg:"父组件传值给全局子组件成功"
            }
        })
    </script>    
</body>
</html>

<!--
    在子组件中使用父组件的值:
    1.在自组件中定义props属性,为组件标签设置属性变量。在组件内就可以使用这个变量。
    2.在父组件中定义变量的值,通过v-bind指令将值赋值给属性。
-->

18.2 父子组件数据传递_局部

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <child-a v-bind:a="msg"></child-a>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        //Vue相当于所有组件的父组件
        new Vue({
            el:"#app",
            data:{
                msg:"父组件传值给局部子组件成功"
            },
            //情况二:父组件传值给子组件,子组件为局部组件
            components:{
                "child-a":{
                    template:
                    `
                    <div>我是child-a子组件--{{a}}</div>
                    `
                    ,
                    props:['a']
                }
            }

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

<!--
    在子组件中使用父组件的值:
    1.在自组件中定义props属性,为组件标签设置属性变量。在组件内就可以使用这个变量。
    2.在父组件中定义变量的值,通过v-bind指令将值赋值给属性。
-->

十九、动态路由

19.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>
</head>
<body>
    <div id="app">
        <router-link to="/basketball">篮球</router-link>
        <router-link to="/football">足球</router-link>
        <router-link to="/tennis">网球</router-link>

        <router-view></router-view>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <script>
        var Ball = {
            template: `<div>球类运动:{{$route.params.content}}</div>`
        }

        var router = new VueRouter({
            routes:[
                {
                    //动态路由,匹配/:前面的路径并将传参到/:后面的变量
                    path:'/:content',
                    component: Ball
                }
            ]
        })

        new Vue({
            el:"#app",
            router:router
        })
    </script>
    
</body>
</html>

<!-- 
    动态路由使用场景:如"/:id",id处是传入的参数,所有id都会加载同一个组件,
    但是会根据id不同展示不同的内容。如知乎页面中点击不同的详情页,组件相同,
    但是展示不同的内容。
    1.通过<router-link to="/aaa">AAA</router-link>绑定跳转
    2.<router-view></router-view>即是组件的位置
    3.路由实例化,将哈希路径和自定义的组件绑定在一起,一旦哈希变化,就会渲染为哈希对应的组件
    4.在vue中挂载创建的路由对象
-->

19.2 路由vue-router-to属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <!-- 通过不同的to属性写法匹配组件 -->
        <!-- 写死路径进行匹配 -->
        <router-link to="/aaa">AAA</router-link>
        <!-- 通过v-bind传入参数 -->
        <router-link :to="user">BBB</router-link>
        <!-- 传入对象,通过path匹配可以省略#和/ -->
        <router-link :to="{path:'ccc'}">CCC</router-link>
        <!-- 传入对象,通过name进行匹配(#和/不能省略) -->
        <router-link :to="{name:'xxx'}">DDD</router-link>

        <router-view></router-view>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <script>
        var comA = {
            template:`<div>AAAAA</div>`
        }
        var comB = {
            template:`<div>BBBBB</div>`
        }
        var comC = {
            template:`<div>CCCCC</div>`
        }
        var comD = {
            template:`<div>DDDDD</div>`
        }

        var router = new VueRouter({
            routes:[
                {
                    path: '/aaa',
                    component: comA                
                },
                {
                    path: '/bbb',
                    component: comB
                },
                {
                    path: '/ccc',
                    component: comC
                },
                {
                    name: 'xxx',
                    path: '/dd',
                    component: comD
                }
            ]
        })

        new Vue({
            el:"#app",
            router:router,
            data:{
                user:'bbb'
            }
        })

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

19.3 路由-view-router

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
    <!-- <ul>
        <li><a href="#/aaa">AAA</a></li>
        <li><a href="#/bbb">BBB</a></li>
        <li><a href="#/ccc">CCC</a></li>
    </ul>
    <div id="container"> -->
        <!-- 通过router提供的标签实现路由 -->
        <router-link to="/aaa">AAA</router-link>
        <router-link to="/bbb">BBB</router-link>
        <router-link to="/ccc">CCC</router-link>

        <!-- <div id="container">
        </div> -->
        <!-- 通过router提供的标签设置组件容器 -->
        <router-view></router-view>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <script>
        //提供组件(也可以直接写到router中)
        var comA = {
            template: `<div>AAAAA</div>`
        }
        var comB = {
            template: `<div>BBBBB</div>`
        }
        var comC = {
            template: `<div>CCCCC</div>`
        }
        //路由的实例化
        var router = new VueRouter({
            routes:[
                {
                    //配置路由,根据路径配置不同的路由
                    path:'/aaa',
                    component:comA
                },
                {
                    //配置路由
                    path:'/bbb',
                    component:comB
                },
                {
                    //配置路由
                    path:'/ccc',
                    component:comC
                }
            ]
        })
        //在vue对象中挂载路由
        new Vue({
            el:"#app",
            router:router
        })

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

<!--
    通过vue-router.js模块提供的标签实现路由(引入vue-router的CDN路径):
    1.通过<router-link to="/aaa">AAA</router-link>绑定跳转
    2.<router-view></router-view>即是组件的位置
    3.路由实例化,将哈希路径和自定义的组件绑定在一起,一旦哈希变化,就会渲染为哈希对应的组件
    4.在vue中挂载创建的路由对象
-->

19.4 原生命令实现前端路由

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <ul>
            <!-- #aaa表示location中的哈希路由,会在原路径下添加#aaa -->
            <li><a href="#/aaa">AAA</a></li>
            <li><a href="#/bbb">BBB</a></li>
            <li><a href="#/ccc">CCC</a></li>
        </ul>
        <div id="container">
        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        //获取标签元素
        var div = document.getElementById('container')
        //监听窗口的hash值是否改变,如果发生改变,会触发方法
        window.onhashchange = function(){
            var hash = location.hash
            console.log(hash)

            hash = hash.replace("#","")
            console.info(hash)
            switch(hash){
                case '/aaa':
                    div.innerText = "AAAAA"
                    break;
                case '/bbb':
                    div.innerText = "BBBBB"
                    break;
                case '/ccc':
                    div.innerText = "CCCCC"
                    break;
                default:
                    break;
            }
        }

      
    </script>

</body>
</html>

<!--
    过程:
    1.点击超链接后改变url的标识 
    2.通过window.onhashchange监听标识变化,发生变化则回调函数进行处理
    3.函数中根据location.hash获取hash值,渲染对应的组件或内容
-->

二十、路由

20.1 路由vue-router-重定向

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <router-link to="/aaa">首页</router-link>
        <router-link to="/bbb">热点</router-link>
        <router-link to="/ccc">简讯</router-link>
        <br>
        <router-view></router-view>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <script>
        var comA = {
            template:`<dev>comA</dev>`
        }
        var comB = {
            template:`<dev>comB</dev>`
        }
        var comC = {
            template:`<dev>comC</dev>`
        }

        var router = new VueRouter({
            routes:[
                //对请求路径的哈希为'/'的所有请求都重定向到'/aaa'
                //通过path属性进行绑定
                {
                    path:'/',
                    redirect:{
                        path:'/aaa'
                    }
                },
                //通过name属性进行绑定
                {
                    path:'/aaa',
                    redirect:{
                        name:'bbb'
                    }
                },

                {
                    path: '/aaa',
                    component: comA
                },
                {
                    name: 'bbb',
                    path: '/bbb',
                    component: comB,
                    //redirect也可以写在这里
                    redirect:{
                        path: '/ccc'
                    }
                },
                {
                    path: '/ccc',
                    component: comC
                },
                //如果用户输入的路由有误,那么直接重定向到主页
                //需要注意放置的顺序,从上到下进行匹配,重定向后重新走一遍匹配规则
                {
                    path: '*',
                    redirect: {
                        path: '/aaa'
                    }
                }
            ]
        })

        new Vue({
            el: "#app",
            router:router
        })
    </script>
</body>
</html>

<!-- 
    重定向:强制修改url标识,重新发起请求
    1.在路由的实例化中将需要重定向的路径redirect到目标路径
-->

20.2 不通过router-link改变标识

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 为选中的标签添加样式 -->
    <style>
        .router-link-exact-active.router-link-active{
            color:blue;
        }
    </style>
</head>
<body>
    <div id="app">
        <!-- 将最终的默认的标签<a></a>改为<span></span> -->
        <router-link to="/aaa" tag="span">AAA</router-link>
        <router-link to="/bbb">BBB</router-link>
        <button @click="changeUrl()">音乐</button>
        <br>
        <router-view></router-view>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <script>
        var comA = {
            template: `<div>comA组件</div>`
        }
        var comB = {
            template: `<div>comB组件</div>`
        }
        var comC = {
            template: `<div>comC组件</div>`
        }

        var router = new VueRouter({
            routes:[
                {
                    path:"/aaa",
                    component:comA
                },
                {
                    path:"/bbb",
                    component:comB
                },
                {
                    path:"/ccc",
                    component:comC
                }
            ]
        })

        new Vue({
            el: "#app",
            router:router,
            methods:{
                changeUrl(){
                    //获取路由对象,改变路由的标识,并渲染对应的组件
                    this.$router.push("/ccc")
                }
            }
        })
    </script>
    
</body>
</html>

<!--
    1.可以通过设置事件调用this.$router.push("")方法,改变路由的标识,并渲染对应的组件。
    2.<router-link to=""><router-link>标签在前端页面中最终会变成<a></a>标签,
    可以设置tag属性<router-link to="/aaa" tag="span">AAA</router-link>改为<span></span>标签,
    如果选中了标签,会自动设置类名,变成<a href="#/aaa" class="router-link-exact-active router-link-active"></a>
    可以通过类名来锁定点击的标签,通过style样式进行渲染。   
-->

二十一、路由的嵌套_二级路由

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .router-link-exact-active.router-link-active{
            color: crimson;
        }
        /*float: left标签显示在一行;list-style: none去掉文字前的圆点*/
        li{
            float: left;
            list-style: none;
        }
        /*text-decoration: none去掉下划线*/
        a{
            text-decoration: none;
        }
        .container{
            height: 100px;
            border: 1px solid black;
        }
        /*clear: both清除前面设置的float:left*/
        .container-sub{
            clear: both;
            height: 50px;
            border: 1px solid green
        }
        *{
            padding: 0;
            margin: 0;
        }
    </style>
</head>
<body>
    <div id="app">
        <ul>
            <router-link to="/home" tag="li"><a>首页</a></router-link>
            <router-link to="/hot" tag="li"><a>热点</a></router-link>
            <router-link to="/music" tag="li"><a>音乐</a></router-link>
        </ul>
        <br>
        <!--给组件设置样式-->
        <router-view class="container"></router-view>


    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <script>
        //一级组件的渲染
        var home = {
            template: `<div>首页首页</div>`
        }
        var hot = {
            template: `<div>热点热点</div>`
        }
        var music = {
            template: 
            `<div>
                <router-link to="/music/classic" tag="li"><a>古典</a></router-link>
                <router-link to="/music/pop" tag="li"><a>流行</a></router-link>
                <router-link to="/music/jazz" tag="li"><a>爵士</a></router-link> 
                <br>
                <router-view class="container-sub"></router-view>
            </div>`
        }
        //二级组件的渲染
        var musicsub = {
            template:
            `
            <div>musicsub:{{this.$route.params.id}}</div>
            `
        }

        var router = new VueRouter({
            routes:[
                {
                    name:'home',
                    path:'/home',
                    component:home
                },
                {
                    name:'hot',
                    path:'/hot',
                    component:hot
                },
                {
                    name:'music',
                    path:'/music',
                    component:music,
                    //children用法和routes是一样的
                    children:[
                        {
                            path:'/music/:id',
                            component:musicsub
                        }
                    ]
                }
            ]
        })


        new Vue({
            el: "#app",
            router:router
        })
    </script>
</body>
</html>

<!--
    将一级路由中的组件中再添加一个组件。
    在路由对象中添加children属性,绑定二级路由的路径和组件。
-->

二十二、动画

22.1 过渡和动画

transition是Vue的内置组件

<head>
  <title></titile>
  <link rel"stylesheet" href="">
  <script type="text/javascript" src="../js/vue.js"></script>
  <style type="text/css">
     /*淡入淡出效果*/
    .fade-enter-active,.fade-leave-active{
      transition: opacity .5s;
    }
    .fade-enter,.fade-leave-to{
      opaicty: .5s;
    }
  </style>
</head>

<div id="app">
  <button @click="isOk=!isOk">切换效果</button>
  <transition name="fade">
    <p v-show="isOk">过渡效果演示</p>
  </transition>
</div>

<script type="text/javascript">
  const vm = new Vue({
    el: "#app",
    data: {
      isOk: false  
    }
  })
</script>

从无到有:本身是隐藏的,点击按钮显示出来
.fade-enter 一开始进入的状态
.fade-enter-active 从无到有的时候的效果
.fade-enter-to 从无到有的结束的效果

.fade-leave 最开始有的时候的状态
.fade-leave-active 从有到无的过渡的效果
.fade-leave-to 没有的时候的效果

image.png
/*平移效果*/
p {
  background-color: green;
  width: 100px;
  text-align: center;
}
.myFade-enter-active{
  transition: all 2s;
}
.myFade-leave-active{
  transition: all 3s;
}
.myFade-enter,.myFade-leave-to{
  transform: translateX(20px)
}

/*动画效果*/
p {
  background-color: green;
  width: 100px;
  text-align: center;
}
/*显示状态效果*/
.bound-enter-active{
  animation: bounce-in .5s
}
/*隐藏状态效果*/
.bounce-leave-active{
  animation: bounce-in .5s reverse;
}
/*动画,scale表示缩放倍数*/
@keyframe bounce-in{
  0%{
    transform: scale(0)
  }
  50%{
    transform: scale(2)
  }
  100%{
    transform: scale(1)
  }
}

22.2 过渡动画

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!--<link rel="stylesheet" href="https://unpkg.com/animate.css@3.5.2/animate.min.css">
    -->   <style>
        /*设置从右侧模糊进入和从右侧模糊退出的动画*/
        * {
            padding: 0;
            margin: 0;
        }
        .test{
            width: 100px;
            height: 100px;
            background-color: coral;
            position: absolute;
            left: 0;
        }
        .v-enter,.v-leave-to{
            opacity:0;
            left:300px;
        }
        .v-enter-to,.v-leave{
            opacity:1;
            left:0px;
        }
        .v-enter-active,.v-leave-active{
            transition: all 1s;
        }
    </style>
</head>
<body>
    <div id="app">
        <button @click="isShow = !isShow">按钮</button>
        <!-- 给需要过渡效果的元素(插入或移除的元素)外层包裹组件 transition -->
        <transition>
            <div class="test" v-if="isShow">content</div>
        </transition>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <!--<script src="https://unpkg.com/animate.css@3.5.2/animate.min.css"></script>-->
    <script>
        new Vue({
            el: "#app",
            data: {
                isShow:false
            },
            methods:{

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

22.3 第三库的过度动画

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引入第三方库Animate -->
    <link rel="stylesheet" href="https://unpkg.com/animate.css@3.5.2/animate.min.css">
    <style>
        * {
            margin: 15px;
            padding: 0px;
        }
    </style>
</head>
<body>
    <div id="app">
        <button @click="isShow = !isShow">按钮</button>
        <!-- 给需要过渡效果的元素(插入或移除的元素)外层包裹组件 transition -->
        <transition
            enter-active-class="animated tada"
            leave-active-class="animated bounceOutRight"
        >
            <div class="test" v-if="isShow">content</div>
        </transition>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        new Vue({
            el: "#app",
            data: {
                isShow:false
            },
            methods:{

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

二十三、钩子函数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                message: "vue的生命周期",
            },
            beforeCreate: function(){
                console.group('--beforeCreate创建前的状态---');
                console.log("%c%s","color:red","el  :"+this.$el);//el未定义
                console.log("%c%s","color:red","data:"+this.$data);//data未定义
                console.log("%c%s","color:red","message:"+this.message);
            },
            created: function(){
                console.group('--create创建后的状态---');
                console.log("%c%s","color:red","el  :"+this.$el);//el未定义
                console.log("%c%s","color:red","data:"+this.$data);//data未定义
                console.log("%c%s","color:red","message:"+this.message);
            },
            beforeMount: function(){
                console.group('--beforeMount挂载前的状态---');
                console.log("%c%s","color:red","el  :"+this.$el);//el未定义
                console.log("%c%s","color:red","data:"+this.$data);//data未定义
                console.log("%c%s","color:red","message:"+this.message);
            },
            mounted: function(){
                console.group('--mounted挂载后的状态---');
                console.log("%c%s","color:red","el  :"+this.$el);//el未定义
                console.log("%c%s","color:red","data:"+this.$data);//data未定义
                console.log("%c%s","color:red","message:"+this.message);
            },
            beforeUpdate: function(){
                console.group('--beforeUpdate更新前的状态---');
                console.log("%c%s","color:red","el  :"+this.$el);//el未定义
                console.log("%c%s","color:red","data:"+this.$data);//data未定义
                console.log("%c%s","color:red","message:"+this.message);
            },
            updated: function(){
                console.group('--updated更新后的状态---');
                console.log("%c%s","color:red","el  :"+this.$el);//el未定义
                console.log("%c%s","color:red","data:"+this.$data);//data未定义
                console.log("%c%s","color:red","message:"+this.message);
            },
            beforeDestroy: function(){
                console.group('--beforeDestroy销毁前的状态---');
                console.log("%c%s","color:red","el  :"+this.$el);//el未定义
                console.log("%c%s","color:red","data:"+this.$data);//data未定义
                console.log("%c%s","color:red","message:"+this.message);
            },
            destroyed: function(){
                console.group('--destroyed销毁后的状态---');
                console.log("%c%s","color:red","el  :"+this.$el);//el未定义
                console.log("%c%s","color:red","data:"+this.$data);//data未定义
                console.log("%c%s","color:red","message:"+this.message);
            }
        })
    </script>
    
</body>
</html>
image.png

分为四个阶段:开始、结束、界面加载、数据更新
created之后vue对象初始化完成,mounted之前在虚拟dom中完成对展示页面的内容解析替换,mounted之后完成虚拟dom放入真实标签页中。

二十四、 按键修饰符

<div id="app">
  <input type="text" value="" v-model="msg" @keyup="handle1">
  <input type="text" value="" v-model="msg" @keyup.enter="handle2">
  <input type="text" value="" v-model="msg" @keyup.13="handle3">
</div>

const vm = new Vue({
  el: '#app',
  data: {
    msg: '请输入'
  },
  methods: {
    handle1(e) {
      if (e.keyCode === 13) {
        console.log('按下回车了')
      }
    },
    handle2(e) {
      console.log('按下回车了')
    },
    handle3(e) {
      console.log('按下回车了')
    },
  }
})

<!-- 按键修饰符用于判断用户输入的按键  .enter   .tab   .delete(捕获删除和退格键)   .esc   .space   .up   .down   .left   .right -->

二十五、定时器

const vm = new Vue({
  el: '#app',
  data: {
    isOk: false
  }
  //界面加载后有定时器,,操作isOk的状态值,定时为1s
  mounted(){
    setInterval(()=>{
      this.isOk = !this.isOk
    },1000);  
  },
  //销毁实例对象之前调用
  beforeDestroy(){
    //销毁定时器
    clearInterval(this.timeId)
  }
  methods: {
    clear(){
      //销毁实例对象
      this.$destroy()
    }  
  }
})

定时器是window中的方法,与vm实例无关。
所以需要在销毁实例之前将定时器清除,在beforeDestroy()生命周期函数中调用clearInterval()方法。

vm.$destroy()
完全销毁一个实例。清理它与其它实例的连接,解绑它的全部指令及事件监听器。

https://cn.vuejs.org/v2/api/

相关文章

  • Vue学习 Vue SSR + Vuex

    github 项目地址 预览 说明 vue学习整理 未严格按照Vue风格指南 旨在学习与交流vue语法以及基本入门...

  • 标准前端化工程 Vue-cli

    知识回顾 在学习Vue-cli之前,我们已经学习了前端体系、前后端分离的演变、Vue入门、Vue的基本语法、Vue...

  • 01Vue基本使用与模板语法

    Vue基本使用与模板语法 一. 基本使用 Hello World快速入门 二. 模板语法 指令 概述 指令的本质就...

  • VUE语法入门

    一、HelloWorld 二、阻止表单提交 三、v-test和v-html 四、v-if和v-show 五、v-o...

  • Vue.js基础入门

    今天,给大家分享下Vue.js基础入门,我主要由了解Vue.js、开始起步、语法三个部分简单的写了基础入门知识,希...

  • Vue.js基础入门

    今天,给大家分享下Vue.js基础入门,我主要由了解Vue.js、开始起步、语法三个部分简单的写了基础入门知识,希...

  • Python 高端课程培训,CMDB自动化运维培训!

    1、入门小基础(8个课时): 1、沙盒环境,py环境安装使用 2、vue 基础语法与组件学习 3、vue + el...

  • 自学vue

    Vue 入门(声明与渲染) Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统...

  • Vue-element-admin 对接后端数据 django

    前端: VUE 语法:js后端: django 语法:python Vue-element-...

  • vue入门教程之基础语法

    vue入门教程之基础语法 欢迎关注博主公众号「java大师」, 专注于分享Java领域干货文章, 关注回复「资源」...

网友评论

    本文标题:VUE语法入门

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