vue笔记

day1

MVVM

MVC是后端的分层开发概念

MVVM是前端视图层的概念,主要关注于视图层分离,也就是说:MVVM把前端的视图层分为了三部分Model、View、VM ViewModel

为什么有了MVC还要有MVVM.

分层处理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y8mTvcIh-1599142789218)(img/1593352884511.png)]

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="vue.js"></script>
    <title>Document</title>
</head>

<body>
    <!-- 将来new的vue实例,会控制这个 元素中的所有内容 -->
    <div id="app">
        <p>{{ msg }}</p>
    </div>
    <script>
        // 2.创建一个Vue的实例
        // 当我们导入包之后,在浏览器的内存中,就多了一个Vue构造函数
        // 注意:我们new出来的这个vm对象,就是我们MVVM中的VM调度者
        var vm = new Vue({
            el: "#app",  //表示,当前我们new的这个Vue实例,要控制页面上的哪个区域
            // 这里的data就是MVVM中的M,专门用来保存每个页面的数据的
            data: {  //data属性存放的是el中要用到的数据
                //通过Vue提供的指令,很方便的就能把数据渲染到页面上,程序员不再手动操作DOM元素了
                // 【前端的Vue之类的框架,不提倡我们去手动操作DOM元素了】
                msg: "欢迎学习vue",

            }




        })
    </script>
</body>

</html>

v-cloak、v-text、v-html基本指令

v-cloak该属性默认都让该元素display为none;

用法

这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none }一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。

v-cloak与v-text比较

1.网速调慢,v-cloak不加类样式会有闪烁问题,而v-text默认没有闪烁问题。同时,v-text是没有写插值表达式。

2.v-text会覆盖元素中原本的内容,但是,插值表达式 只会替换自己的这个占位符,不会把整个元素内容清空

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VhJMkmiC-1599142789223)(img/1593433205696.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-57bUhdPr-1599142789225)(img/1593433244866.png)]

三大指令作用总结

v-cloak:解决闪烁问题

v-text=“msg”:在元素中填充数据(如果数据中有标签元素,不会转义,直接把标签输出)

v-html=“msg”:在元素中填充数据(如果数据中有标签元素,会把该元素转成DOM元素输出

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nuq3nbdA-1599142789228)(img/1593434156579.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RoKycPYk-1599142789230)(img/1593434167243.png)]

v-bind数据绑定

v-bind是vue中,提供的用于绑定属性的指令

注意;

v-bind:指令可以被简写为 :要绑定的属性

v-bind中,可以写合法的JS表达式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3Ydjy1ai-1599142789231)(img/1593434439074.png)]

<!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>
    <!-- 将来new的vue实例,会控制这个 元素中的所有内容 -->
    <div id="app">
        <!-- v-bind是vue中,提供的用于绑定属性的指令 -->
        <!-- <input type="button" value="按钮"v-bind:title="mytitle + '123'"> -->

        <!-- 简写方式,只留个冒号,等同于v-bind: -->
        <input type="button" value="按钮" :title="mytitle + '123'">
    </div>
    <script src="vue.js"></script>
    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                mytitle:"这是一个自己定义的title "
            }
        })
    </script>
</body>

</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5ZqnvShK-1599142789232)(img/1593435095210.png)]

v-on指令定义事件

v-on缩写为 @绑定事件类型

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <!-- 将来new的vue实例,会控制这个 元素中的所有内容 -->
    <div id="app">
        <!-- DOM操作示例 -->
        <!-- <input type="button" value="按钮" :title="mytitle + '123'" id="btn"> -->

        <input type="button" value="按钮" v-on:click="show">
        <input type="button" value="按钮" v-on:mouseover="show">
    </div>
    <script src="vue.js"></script>
    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                mytitle:"这是一个自己定义的title "
            },
            methods:{   //这个methods属性中定义了当前vue实例所有可用的方法
                show:function(){
                    alert("你好啊沙雕!")
                }

            }
        })
        // // DOM操作
        // document.getElementById("btn").οnclick=function(){
        //     alert("hellow")
        // }
    </script>
</body>

</html>

注意:

在vue实例中,如果想要获取data上的数据,或者想要调用methods中的方法,必须通过this.数据属性名 或 this.方法名来进行访问。这里的this就表示我们new出来的VM实例对象

跑马灯案例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>跑马灯效果</title>
</head>

<body>
    <!-- 将来new的vue实例,会控制这个 元素中的所有内容 -->
    <div id="app">
        <input type="button" value="跑起来" @click="show">
        <input type="button" value="停下" @click="stop">

        <h4>{{msg}}</h4>
    </div>
    <script src="vue.js"></script>
    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                msg: "猥琐发育,别浪~~!",
                timeId:null,
            },
            methods: {   //这个methods属性中定义了当前vue实例所有可用的方法
                show() {
                    // var timeId = setInterval(function () {
                    //     var start = this.msg.substring(0, 1);
                    //     var end = this.msg.substring(1);
                    //     this.msg = end + start;
                    // },500)
                    if(this.timeId != null) return;
                    this.timeId = setInterval(() => {
                        var start = this.msg.substring(0, 1);
                        var end = this.msg.substring(1);
                        this.msg = end + start;
                    }, 500);
                },
                stop: function () {
                    clearInterval(this.timeId);
                    this.timeId=null;
                }

            }
        })

    </script>
</body>

</html>

bug存在:采用插值写法即

{{msg}}
数据更新了但在谷歌浏览器中视图不一定会更新。可以采用
写法或者
。亲测有效。

事件修饰符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JoN7mENi-1599142789234)(img/1593517230301.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vEjV43aS-1599142789235)(img/1593447379991.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-24Fn0689-1599142789236)(img/1593447394964.png)]

阻止冒泡案例。通过 .stop的形式阻止冒泡。其他同上。

总结:

使用.stop	阻止冒泡	//冒泡是从内到外
使用 .prevent 阻止默认行为	//例如链接
使用 .capture 实现捕获触发事件的机制	//捕获是从外到内
使用 .self 实现只有点击当前元素的时候,才会触发事件处理函数	//冒泡和捕获都不会触发,但是只会阻止自己身上的冒泡行为的触发,并不会真正阻止冒泡行为 
使用 .once 只触发一次事件函数

系统内置的其他按键修饰符

详情查看官网文档

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IBz1je9y-1599142789237)(img/1593709781425.png)]

自定义全局按键修饰符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YdDKmid4-1599142789239)(img/1593710445732.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ffCdnrtG-1599142789241)(img/1593710470740.png)]

v-model实现表单数据双向绑定

注意:只有这一个指令可以实现数据双向绑定

使用 v-model 指令,可以实现表单元素和 Model 中数据的双向数据绑定

<!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>
    <!-- 将来new的vue实例,会控制这个 元素中的所有内容 -->
    <div id="app">
        <h4> {{msg}} </h4>
        <input style="width:100%" type="text" v-model="msg">
    </div>

    <script src="vue.js"></script>
    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                msg: "大家都是好学生,爱敲代码,爱学习,爱思考,简直就是完美,没瑕疵~!"
            },
            methods: {   //这个methods属性中定义了当前vue实例所有可用的方法

            }
        })

    </script>
</body>

</html>

bug:

测试:谷歌浏览器实现不了表单数据双向绑定。

谷歌浏览器存在bug;从这个角度来说,谷歌浏览器翻译后,Vue双向数据绑定其实并没有失效,只是翻译导致DOM结构发生了变更,Vue找不到原来的节点去更新数据了。

通过属性绑定为元素设置class类样式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-daYXykK9-1599142789242)(img/1593528767642.png)]

使用class类样式有以上四种方式。

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>16.中通过属性绑定为元素设置class类样式</title>
</head>
<style>
    .red{
        color: red;
    }
    .thin{
        font-weight: 200;
    }

    .italic{
        font-style: italic;
    }
    .active{
        letter-spacing: 0.5em;
    }
</style>
<body>
    <div id="app">
        <!-- 普通方式 -->
        <!-- <h1 class=" red thin">这是一个很大很大的标题!!!</h1> -->

        <!-- 数组方式绑定 需要使用v-bind做数据绑定-->
        <!-- <h1 :class="['red' ,'thin','italic']">这是一个很大很大的标题!!!</h1> -->

        <!-- 数组中使用三元表达式写法 -->
        <!-- <h1 :class="['thin','italic',flag?'red':'']">这是一个很大很大的标题!!!</h1> -->

        <!-- 数组中使用对象方式写法代替三元表达式,提高代码可读性 -->
        <h1 :class="['thin','italic',{'red':flag}]">这是一个很大很大的标题!!!</h1>

    </div>

    <script src="./vue.js"></script>
    <script>
        var vm=new Vue({
            el:"#app",
            data:{
                flag:true,
            },
            methods:{}
        })
    </script>
</body>
</html>

通过属性绑定为元素绑定style行内样式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mZUxqwMV-1599142789243)(img/1593530164100.png)]

v-for指令和key属性

主要功能:迭代

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oDdeGOPh-1599142789244)(img/1593531435686.png)]

<!DOCTYPE html>
<html lang="zh">

<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">
        <!-- <p v-cloak v-for="item in list">{{item}}</p> -->
        <p v-cloak v-for="(item,i) in list">索引值:{{i}} === 每一项:{{item}}</p>

        <!-- 循环对象数组 -->
        <p v-for="item in list2">{{item.id}} {{item.name}}</p>

        <p v-for="(val,key) in user">值是:{{val}} === 键是:{{key}}</p>

        

    </div>


    <script src="./vue.js"></script>
    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                list: ["我", "不", 3, 4, 5, 6],
                list2: [
                    { id: 1, name: "zs" },
                    { id: 2, name: "ls" },
                    { id: 3, name: "lmf" },
                    { id: 4, name: "fg" }
                ],
                user:{
                    id:1,
                    name:"托尼*乔巴",
                    gender:"男"
                }
            },
            methods: {}
        })



    </script>
</body>

</html>

    <div id="app">
        <!-- in 后面我们放过 普通数组,对象 ,还可以放数字-->
        <!-- 注意:如果使用v-for迭代数字的话,是从1开始 -->
        <p v-for="count in 10">这是第{{count}}次循环</p>
    </div>

v-for中key的使用注意事项

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-euTAz6xV-1599142789245)(img/1593534138608.png)]

注意:v-for循环的时候,key属性只能使用number或者string

注意:key在使用的时候 必须使用 v-bind 属性绑定的形式,指定 key 的值

在属性中使用v-for循环的时候,或者在一些特殊情况中,如果v-for 有问题,必须在 使用 v-for 的同时,指定唯一的字符串/数字 类型 :key 值

v-if和v-show的使用和特点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yUUd9LD4-1599142789246)(img/1593534974263.png)]

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=`, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <input type="button" value="toggle" @click="flag=!flag">

        <!-- v-if的特点:每次都会重新删除或创建元素 -->
        <h3 v-if="flag">这是用v-if控制的元素</h3>

        <!-- v-show的特点:每次不会重新进行DOM的删除和创建操作,只是切换了元素的display:none样式 -->
        <h3 v-show="flag">这是用v-show控制的元素</h3>
    </div>

    <script src="./vue.js"></script>
    <script>
        var vm=new Vue({
            el:"#app",
            data:{
                flag:true,
            },
            methods:{
                // toggle(){
                //    this.flag=!this.flag;
                // }
            }
        })
    </script>
</body>
</html>

v-if有较高的切换性能消耗;v-show有较高的初始渲染消耗

如果元素涉及到频繁的切换,最好不要使用v-if,推荐v-show;如果元素可能永远也不会显示出来,则推荐使用v-if

day1总结:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e1YmqLSZ-1599142789248)(img/1593536607184.png)]

day2

Vue-devtools的两种安装方式

谷歌对于Vue的调试工具

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vrl7j0oC-1599142789249)(img/1593616310135.png)]

品牌案例

注意:

forEach		some	filter		findIndex	
//这些都属于数组的新方法,都会对数组中的每一项进行遍历,执行相关的操作。
注意:ES6中,为字符提供了一个新方法,叫做String.prototype.includes("要包含的字符串")
//如果包含。则返回true,否则返回false

全局过滤器:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wuRTqfg4-1599142789250)(img/1593619808097.png)]

案例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../vue.js"></script>
</head>

<body>

    <div id="app">
        <p>{{ msg | msgFormat }}</p>
    </div>

    <script>
        // 定义一个Vue全局的过滤器,名字叫做msgFormat
        Vue.filter("msgFormat",msg=>{
            return msg.replace(/单纯/g,"邪恶")
        })

        // 创建vue实例vm
        var vm = new Vue({
            el: "#app",
            data: {
                msg: "曾经,我也是一个单纯的少年,傻傻的问谁是世界上最单纯的人"
            },
            methods: {}
        })
    </script>

</body>

</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EiMwk6km-1599142789252)(img/1593693971953.png)]

私有过滤器

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../vue.js"></script>
</head>

<body>
    <div id="app">
        <p>{{ msg | dateFormat}}</p>
    </div>

    <div id="app2">
        {{msg | dateFormat()}}
    </div>


    <script>
        // // 定义全局过滤器
        // Vue.filter(dataFormat, (msg,dataFormat) => {

        // })""

        // 全局过滤器,进行格式化时间
        Vue.filter("dateFormat", (dateStr, pattern = "") => {
            // 根据给定的时间字符串,得到特定的时间
            var dt = new Date(dateStr)

            //yyyy-mm-dd
            var y = dt.getFullYear();
            var m = dt.getMonth() + 1
            var d = dt.getDate()

            if (pattern.toLowerCase() === "yyyy-mm-dd") {
                return `${y}-${m}-${d}`
            } else {
                var hh = dt.getHours()
                var mm = dt.getMinutes()
                var ss = dt.getSeconds()

                return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
            }

        })


        // 创建Vue实例
        var vm = new Vue({
            el: "#app",
            data: {
                msg: "我一定可以的",
                dt:new Date()
            },
            methods: {},
        })


        var vm2 = new Vue({
            el: "#app2",
            data: {
                msg:"nishishabima",
                dt: new Date(),
            },
            methods: {},

            // 过滤器调用的时候,采用的时候是就近原则,如果私有过滤器和全局过滤器名称一致了,这时候 优先调用私有过滤器
            filters: {   //定义私有过滤器 过滤器有两个条件 【过滤器名称 和 处理函数】
                dateFormat: function (dateStr, pattern = "") {
                    // 根据给定的时间字符串,得到特定的时间
                    var dt = new Date(dateStr)

                    //yyyy-mm-dd
                    var y = dt.getFullYear();
                    var m = dt.getMonth() + 1
                    var d = dt.getDate()

                    if (pattern.toLowerCase() === "yyyy-mm-dd") {
                        return `${y}-${m}-${d}`
                    } else {
                        var hh = dt.getHours()
                        var mm = dt.getMinutes()
                        var ss = dt.getSeconds()

                        return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
                    }
                }
            }

        })
    </script>
</body>

</html>

自定义全局指令

注意;Vue中所有的指令,在调用的时候,都以 v- 开头

        // 使用Vue.directive()定义全局指令
        // 其中参数1:指令名称 注意:在定义的时候,指令的名称前面不需要加v-前缀
        // 在调用的时候,必须在前面加上v-前缀
        // 参数2:是一个对象,这个对象身上,有一些指令相关的函数,这些函数可以在特定的阶段执行相关的操作
        Vue.directive("focus",{
            //样式设置,和样式相关的操作,一般都可以在bind中执行
            bind:function(el){    //每当指令绑定到元素上的时候,会立即执行这个函数 只执行一次
                // 注意:在每个函数中,第一个参数永远是el,表示被绑定了指令的
                // 那个元素,这个el参数,是一个原生的JS对象。
                // 在元素 刚绑定指令的时候,还没有插入到DOM中去,这时候,调用focus方法没有作用
                // 因为一个元素只有插入DOM元素之后,才能获取焦点
                // el.focus()
            },
            
            //行为设置,和JS行为有关的操作,最好在inserted中执行,防止JS行为不生效
            inserted:function(el){    //inserted表示元素 插入到DOM中的时候,会执行inserted函数 触发一次
                
                el.focus()
            },
            updated:function(el){     //当VNode更新的时候,会执行updated,可能会触发多次

            }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NM6Qln70-1599142789253)(img/1593883419769.png)]

钩子函数:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ErUjDuWb-1599142789254)(img/1593886133013.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IDkXKhPH-1599142789255)(img/1593886147759.png)]

根据以上参数设置:

//元素部分:
<p v-color="'blue'"></p>
        
        
        
        // 自定义一个设置字体颜色的指令
        Vue.directive("color",{
            // 样式,只要通过指令绑定给了元素,不管这个元素有没有被插入到页面中去,这个元素肯定有了一个内联样式
            // 将来元素肯定会显示到页面中去,这时候,浏览器的渲染引擎必然会解析样式,应用给这个元素
            bind:function(el,binding){
                el.style.color=binding.value
            }
        })

定义私有指令

        // 创建Vue实例
        var vm=new Vue({
            el:"#app2",
            data:{
                dt:"你怎么这么傻逼啊!"
            },
            methods:{},
            directives:{     //定义私有指令
                'fontweight':{
                    bind:function(el,binding){
                        el.style.fontWeight=binding.value
                    }
                }
            }
        })

注意:directive定义私有时,带s的。

指令函数的简写形式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cp8BYNI4-1599142789256)(img/1593923258802.png)]

实例:

        // 创建Vue实例
        var vm=new Vue({
            el:"#app2",
            data:{
                dt:"你怎么这么傻逼啊!"
            },
            methods:{},
            directives:{     //定义私有指令
                'fontweight':{      //设置字体粗细
                    bind:function(el,binding){
                        el.style.fontWeight=binding.value
                    }
                },
                //简写方式:
                'fontsize':function(el,binding){    //注意:这个function等同于把代码写到bind和updata中去
                    el.style.fontSize=parseInt(binding.value)+"px"
                }
            }

生命周期函数-组件创建期的4个钩子函数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wRGTnBvq-1599142789257)(img/1593923854280.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RxWIgc7U-1599142789259)(img/1593924335651.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-twSSc7gc-1599142789260)(img/lifecycle.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CIkcHwNM-1599142789261)(img/1593928427429.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NR30pJYu-1599142789262)(img/1593928709910.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IjCBePhb-1599142789263)(img/1593928969279.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bIhziV5i-1599142789265)(img/1593928917148.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bxfgh0Da-1599142789266)(img/1593929205774.png)]

生命周期函数-组件运行和销毁阶段的钩子函数

运行:

两个函数:

//运行中的两个事件
beforeUpdate(){	//这时候,表示,我们的界面还没有被更新【数据更新了么? 数据肯定更新了】
    
}
updated(){
    
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5wHvfDwP-1599142789267)(img/1593930779384.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xDhzhHga-1599142789268)(img/1593930900775.png)]

销毁:

来给你个函数:
beforeDestroy()
destroyed()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fY7mF4Ii-1599142789270)(img/1593931321761.png)]

vue-resource发起get、post、jsonp请求

vue-resource是和vue高度集成的第三方包

除了vue-resource,还可以实使用axios的第三方包实现数据的请求。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jKLZqINp-1599142789271)(img/1593931678828.png)]

使用文档:

https://github.com/pagekit/vue-resource/blob/develop/docs/http.md

vue下跨域设置

vue-resource请求示例:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UvAUCb8x-1599142789273)(img/1593937111638.png)]

结合Node手写JSONP服务器剖析JSONP原理

// 导入http内置模块
const http = require("http");
const urlModule = require("url")

//创建一个http服务器
const server = http.createServer();
// 监听http服务器的request请求
server.on("request", (req, res) => {

    if (url = '/getscript') {
        // 拼接一个合法的JS脚本,这里拼接的是一个方法的调用
        var scriptStr = '${query.callback}()'
        res.end(scriptStr)
    }else{
        res.end('404')
    }

})


// 指定端口号并启动服务器监听
server.listen(3000, () => {
    console.log("server listen at http://127.0.0.1:3000")
})

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hiDn8bW6-1599142789275)(img/1593940250816.png)]

day3

全局配置数据接口得根域名

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qThmqbJC-1599142789276)(img/1594046939752.png)]

实例:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V5ON0gyG-1599142789277)(img/1594047717923.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iHssZVaX-1599142789279)(img/1594047745595.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XBGZ7OM7-1599142789281)(img/1594049034131.png)]

Vue.http.options.emulateJSON = true;

vue中得动画

使用过渡类名实现动画

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8UtEgXGW-1599142789282)(img/1594049133152.png)]

实例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../vue.js"></script>
    <!-- 自定义两组样式,来控制transition内部元素实现动画 -->
    <style>
        /* v-enter【这是一个时间点】,是进入之前,元素的起始状态,此时还没有开始进入 */
        /* v-leave-to【这是一个时间点】是动画离开之后,离开的终止状态,此时,元素 动画已经结束 */
        .v-enter,
        .v-leave-to {
            opacity: 0;
            transform: translateX(150px);
        }

        /* 入场动画时间段*/
        /* 离场动画时间段 */
        .v-enter-active,
        .v-leave-active {
            transition: all .8s ease;
        }
    </style>
</head>

<body>

    <div id="app">
        <input type="button" value="toggle" @click='flag=!flag'>
        <!-- 需求:点击按钮,让h3显示,再点击,让h3隐藏 -->
        <!-- 1。使用transition元素,把需要被动画控制得元素,包裹起来 -->
        <!-- transition元素是Vue官方提的 -->
        <transition>
            <h3 v-if="flag">这是一个h3标签</h3>
        </transition>
    </div>

    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                flag: false,
            },
            methods: {}
        })
    </script>
</body>

</html>
自定义前缀
        <transition name="vshow">
            <h3 v-if="flag">自定义前缀</h3>
        </transition>

注意:transition中的name值就是定义前缀,替换样式中的 “.v-” ;同时也是防止冲突

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../vue.js"></script>
    <!-- 自定义两组样式,来控制transition内部元素实现动画 -->
    <style>
        /* v-enter【这是一个时间点】,是进入之前,元素的起始状态,此时还没有开始进入 */
        /* v-leave-to【这是一个时间点】是动画离开之后,离开的终止状态,此时,元素 动画已经结束 */
        .v-enter,
        .v-leave-to {
            opacity: 0;
            transform: translateX(150px);
        }

        /* 入场动画时间段*/
        /* 离场动画时间段 */
        .v-enter-active,
        .v-leave-active {
            transition: all .8s ease;
        }

        
        /* 自定义前缀*/
        .vshow-enter,
        .vshow-leave-to {
            opacity: 0;
            transform: translateX(150px);
        }

        /* 入场动画时间段*/
        /* 离场动画时间段 */
        .vshow-enter-active,
        .vshow-leave-active {
            transition: all .8s ease;
        }
    </style>
</head>

<body>

    <div id="app">
        <input type="button" value="toggle" @click='flag=!flag'>
        <!-- 需求:点击按钮,让h3显示,再点击,让h3隐藏 -->
        <!-- 1。使用transition元素,把需要被动画控制得元素,包裹起来 -->
        <!-- transition元素是Vue官方提的 -->
        <transition>
            <h3 v-if="flag">这是一个h3标签</h3>
        </transition>
        <transition name="vshow">
            <h3 v-if="flag">自定义前缀</h3>
        </transition>
    </div>

    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                flag: false,
            },
            methods: {}
        })
    </script>
</body>

</html>

使用第三方类实现动画

使用animate.css类库实现动画

CSDN链接:

https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.0.0/animate.min.css

官网链接:https://animate.style/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WgWd5q4e-1599142789283)(img/1594130180311.png)]

基本实例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../vue.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.0.0/animate.min.css">

    <!-- 入场:bounceIn      离场:bounceOut -->

</head>

<body>

    <div id="app">
        <input type="button" value="toggle" @click='flag=!flag'>
        <!-- 需求:点击按钮,让h3显示,再点击,让h3隐藏 -->

        <transition enter-active-class="animate__animated animate__bounceIn"
         leave-active-class="animate__animated animate__bounceOut">
            <h3 v-if="flag">这是一个h3标签</h3>
        </transition>

    </div>

    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                flag: false,
            },
            methods: {}
        })
    </script>
</body>

</html>

钩子函数实现半场动画

JavaScript 钩子

可以在 attribute 中声明 JavaScript 钩子

<transition
	//入场钩子函数
  v-on:before-enter="beforeEnter"
  v-on:enter="enter"
  v-on:after-enter="afterEnter"
  v-on:enter-cancelled="enterCancelled"
	
	//离场钩子函数
  v-on:before-leave="beforeLeave"
  v-on:leave="leave"
  v-on:after-leave="afterLeave"
  v-on:leave-cancelled="leaveCancelled"
>
  <!-- ... -->

methods里对应函数写法

// ...
methods: {
  // --------
  // 进入中
  // --------

  beforeEnter: function (el) {
    // ...
  },
  // 当与 CSS 结合使用时
  // 回调函数 done 是可选的
  enter: function (el, done) {
    // ...
      //这里的done其实就是afterEnter函数
    done()
  },
  afterEnter: function (el) {
    // ...
  },
  enterCancelled: function (el) {
    // ...
  },

  // --------
  // 离开时
  // --------

  beforeLeave: function (el) {
    // ...
  },
  // 当与 CSS 结合使用时
  // 回调函数 done 是可选的
  leave: function (el, done) {
    // ...
      
    done()
  },
  afterLeave: function (el) {
    // ...
  },
  // leaveCancelled 只用于 v-show 中
  leaveCancelled: function (el) {
    // ...
  }
}

实例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../vue.js"></script>
    <style>
        .ball {
            width: 15px;
            height: 15px;
            border-radius: 50%;
            background-color: red;
        }
    </style>
</head>

<body>


    <div id="app">
        <input type="button" value="快到碗里来" @click="flag=!flag">
        <!-- 使用transition把小球包裹起来 -->
        <transition @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter">
            <div class="ball" v-if="flag"></div>

        </transition>
    </div>

    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                flag: 'false'
            },
            methods: {
                // 注意:动画钩子函数的第一个参数:el ,表示要执行动画的那个DOM元素,是个原生的JS DOM对象
                beforeEnter(el) {
                    // 动画入场之前,动画尚未开始,可以设置起始样式
                    el.style.transform = "translate(0,0)"
                },
                enter(el,done) { 
                    // 这句话,没有实际的作用,但是,如果不写,出不来动画效果
                    // 可以认为 el.offsetWidth 会强制动画刷新
                    el.offsetWidth
                    // 表示动画开始之后的样式,这里,可以设置小球动画完成之后的,结束状态
                    el.style.transform = "translate(150px,450px)"
                    el.style.transition="all 1s ease"
                    done()
                },
                afterEnter(el) { 
                    console.log("this ok")
                    this.flag=!this.flag
                }
            }
        })
    </script>
</body>

</html>

注意:当只用 JavaScript 过渡的时候,在 enter 和 leave 中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成。

列表过渡

那么怎么同时渲染整个列表,比如使用 v-for?在这种场景中,使用 `` 组件。在我们深入例子之前,先了解关于这个组件的几个特点:

  • 不同于 ,它会以一个真实元素呈现:默认为一个。你也可以通过 tag attribute 更换为其他元素。
  • 过渡模式不可用,因为我们不再相互切换特有的元素。
  • 内部元素总是需要提供唯一的 key attribute 值。
  • CSS 过渡的类将会应用在内部的元素中,而不是这个组/容器本身。

实例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../vue.js"></script>
    <style>
        li {
            border: 1px solid #999;
            margin: 9px;
            padding-left: 5px;
            line-height: 35px;
            font-size: 12px;
        }
        li:hover{
            background-color: hotpink;
            transition: all .5 ease;
        }


        .v-enter-,
        .v-leave-to {
            opacity: 0;
            transform: translateY(80px);
        }

        .v-enter-active,
        .v-leave-avtive {
            transition: all .6s ease;
        }
    </style>
</head>

<body>

    <div id="app">
        <label>
            Id:
            <input type="text" v-model='id'>
        </label>
        <label>
            Name:
            <input type="text" v-model='name'>
        </label>

        <input type="button" @click='add' value="添加">
        <ul>
            <!-- 在实现列表过渡的时候,如果需要过渡的元素,是通过v-for循环渲染出来的 -->
            <!-- 不能使用transition包裹,需要使用transitionGroup -->
            <!-- 如果要为v-for循环创建的元素设置动画,必须为每一个元素设置:key属性 -->
            <transition-group name="list" tag="p">
                <li v-for="item in list" :key="item.id">
                    {{item.id}}---{{item.name}}
                </li>
            </transition-group>
        </ul>

    </div>

    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                id: '',
                name: '',
                list: [{
                        id: 1,
                        name: '赵高'
                    },
                    {
                        id: 2,
                        name: '秦晖'
                    },
                    {
                        id: 3,
                        name: '严嵩'
                    },
                    {
                        id: 4,
                        name: '魏忠贤'
                    }
                ],

            },
            methods: {
                add() {
                    this.list.push({
                        id: this.list.length + 1,
                        name: this.name
                    })
                }
            }
        })
    </script>

</body>

</html>

appear和tag属性的作用

appear:给transition-group添加appear属性,实现入场时候的效果

tag:指定哪个元素应该被渲染

具体

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1gCBcGZj-1599142789285)(image/image-20200708172021580.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VCb9oQOg-1599142789286)(image/image-20200708172055831.png)]

组件化和模块化的区别

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M4T0IWvm-1599142789287)(img/1594207871167.png)]

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

组件化和模块化的不同:

  • 模块化是代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一
  • 组件化是从界面的角度进行划分的;

创建组件的方式

创建组件的第一种方式:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../vue.js"></script>
</head>

<body>
    <div id="app">
        <!-- 如果要使用组件。直接把组件的名称,以HTML标签的形式,引入到页面中,即可 -->
        <!-- 在使用的时候需要用"-"代替驼峰写法 -->
        <!-- 错误写法 -->
        <!-- <myCom1></myCom1> -->
        <!-- 正确写法 -->
        <my-com1></my-com1>

    </div>


    <script>

        // 1.1使用Vue.extend来创建全局的Vue组件
        var com1 = Vue.extend({
            // 通过template属性,指定了组件要展示的HTML结构
            template: '<h3>这是使用Vue.extend 创建的组件</h3>'
        })

        // 1.2使用Vue.component('组件的名称',创建出来的组件模板对象);com1表示要展示的模板里的内容
        // 在注册的时候可以驼峰命名;如果没用驼峰命名,上面则不需要"-"代替,直接写就行
        Vue.component('myCom1', com1)


        var vm = new Vue({
            el: '#app',
            data: {},
            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>
    <script src="../vue.js"></script>
</head>

<body>
    <div id="app">
        <!-- 如果要使用组件。直接把组件的名称,以HTML标签的形式,引入到页面中,即可 -->
        <mycom1></mycom1>
    </div>


    <script>
        // // 1.1使用Vue.extend来创建全局的Vue组件
        // var com1 = Vue.extend({
        //     // 通过template属性,指定了组件要展示的HTML结构
        //     template: '<h3>这是使用Vue.extend 创建的组件</h3>'
        // })

        // 1.2使用Vue.component('组件的名称',创建出来的组件模板对象);com1表示要展示的模板里的内容
        // 在注册的时候可以驼峰命名;如果没用驼峰命名,上面则不需要"-"代替,直接写就行


        Vue.component('mycom1', Vue.extend({
            template: '<h3>这是使用Vue.extend 创建的组件</h3>'
        }))


        var vm = new Vue({
            el: '#app',
            data: {},
            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>
    <script src="../vue.js"></script>
</head>

<body>
    <div id="app">
        <mycom1></mycom1>

        <!-- 在被控制的#app外面,使用template元素,定义组件的HTML模板结构 -->
        <template id="tmp1">
            <div>
                <h1>这是通过template元素,在外部定义的组件结构,这个方式,有代码的只能提示和高亮</h1>
                <h4>好用,不错!</h4>
            </div>
        </template>
    </div>


    <script>

        Vue.component('mycom1',{
            template: 'tmp1'
        })


        var vm = new Vue({
            el: '#app',
            data: {},
            methods: {}
        })
    </script>
</body>

</html>

定义私有组件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1QAplUPs-1599142789288)(img/1594214593774.png)]

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../vue.js"></script>
</head>

<body>
    <div id="app2">
        <!-- <mycom1></mycom1> -->

        <!-- 在被控制的#app外面,使用template元素,定义组件的HTML模板结构 -->
        <login></login>

    </div>


    <template id="tmpl2">
        <div>
            <h1>这是定义的私有组件</h1>
        </div>
    </template>

    <script>


        var vm = new Vue({
            el: '#app2',
            data: {},
            methods: {},
            components: {
                login: {
                    template: '#tmpl2'
                }
            }
        })
    </script>
</body>

</html>

组件中的data

语法&写法

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

    <script>
        // 1.组件可以有自己的数据
        // 2.组件的data和实例的data有点不一样,实例中的data可以为一个对象,但是组件中的data必须是一个方法
        // 3.组件中的data除了必须为一个方法外,这个方法内部,还必须返回一个对象才行
        Vue.component('mycom1',{
            template:'<h1 @click="counts++">这是全局组件:{{counts}}</h1>',
            data:function(){
                return {
                    counts:0
                }
            }
        })

        
        var vm=new Vue({
            el:'#app',
            data:{},
            methods:{}
        })
    </script>
</body>
</html>

注意:

​ 1.组件可以有自己的数据和方法,即data:{ }和methods:{ }

​ 2.组件的data和实例的data有点不一样,实例中的data可以为一个对象,但是组件中的data必须是一个方法

​ 3.组件中的data除了必须为一个方法外,这个方法内部,还必须返回一个对象才行

为什么组件的data必须是一个function?

return出{ 属性名:属性值},每次调用函数等于新开辟了一个对象空间,防止数据共享。但是如果在外面定了了个对象数据,函数内部return了该对象,就会数据同时发生改变。

例子:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qyPR1zhI-1599142789290)(img/1594219573671.png)]

组件切换

第一种方式(v-if和v-else)

v-if和v-else结合使用flag切换组件;案例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../vue.js"></script>
</head>

<body>
    <!-- v-if和v-else结合使用切换组件 -->

    <div id="app">
        <a href="" @click.prevent='flag=true'>登录</a>
        <a href="" @click.prevent='flag=false'>注册</a>

        <login v-if='flag'></login>
        <register v-else='flag'></register>
    </div>

    <script>
        // 注册组件
        Vue.component('login',{
            template: '<h3>登录组件</h3>',
        })

        Vue.component('register',{
            template: '<h3>注册组件</h3>',
        })

        new Vue({ 
            el: '#app', 
            data:{
                flag:true
            }
        })
    </script>
</body>

</html>

第二种方式(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>
    <script src="../vue.js"></script>
</head>
<body>
    <div id="app">

        <a href="" @click.prevent="comName='login'">登录</a>
        <a href="" @click.prevent="comName='register'">注册</a>
        <!-- Vue提供了 component ,来展示对应名称的组件 -->
        <!-- component是一个占位符, :is 属性,可以用来指定要展示的组件的名称 -->
        <!-- 不加单引号会当作表达式来解析,不会看作是字符串 -->
        <component :is="comName"></component>

    </div>

    <script>

        // 登录组件
        Vue.component('login',{
            template: '<h3>登录组件</h3>',
        })
        // 注册组件
        Vue.component('register',{
            template: '<h3>注册组件</h3>',
        })



        new Vue({el:'#app',data:{
            comName:'login'
        }})



    </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>
    <script src="../vue.js"></script>
    <style>
        .v-enter,
        .v-leave-to{
            opacity: 0;
            transform: translateX(150px);
        }

        .v-enter-active,
        .v-leave-active{
            transition: all .5s ease;
        }
    </style>
</head>

<body>
    <div id="app">
        <a href="" @click.prevent="comName='login'">登录</a>
        <a href="" @click.prevent="comName='register'">注册</a>

        <!-- 通过model属性,设置组件切换时候的 模式 -->
        <transition mode='out-in'>
            <component :is="comName"></component>
        </transition>
    </div>

    <script>

        // 登录组件
        Vue.component('login', {
            template: '<h3>登录组件</h3>',
        })
        // 注册组件
        Vue.component('register', {
            template: '<h3>注册组件</h3>',
        })



        new Vue({
            el: '#app', data: {
                comName: 'login'
            }
        })
    </script>
</body>

</html>

day4

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i5Vp1ynb-1599142789291)(img/1594296065971.png)]

组件传值

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

案例演示:(错误演示)

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

    <script>

        new Vue({
            el:'#app',
            data:{
                msg:'123 啊-父组件中的数据'
            },
            methods:{},
            components:{
                // 结论:经过演示,发现,子组件中,默认无法访问到 父组件中的data 上的数据和methods中的方法
                com1:{
                    template:"<h1>这是子组件---{{msg}}</h1>"
                }
            }
        })
    </script>
</body>
</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0xKBoZrV-1599142789293)(img/1594300909121.png)]

想要成功父组件向子组件传值,还需要以下两步:

1.给子组件标签用"v-bind:"绑定父组件数据
2.在绑定好了数据后,需要在定义的子组件中设置props(该属性为数组形式)。在props中定义下绑定的属性(相当于注册),才能使用

实例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../vue.js"></script>
</head>

<body>
    <div id="app">

        <!-- 父组件可以在引用子组件的时候,通过属性绑定(v-bind:)的形式,把需要
        传递给子组件的数据,以属性绑定的形式,传递到子组件内部,供子组件使用 -->
        <com1 :parentmsg='msg'></com1>
    </div>

    <script>

        new Vue({
            el: '#app',
            data: {
                msg: '123 啊-父组件中的数据'
            },
            methods: {

            },
            components: {
                // 结论:经过演示,发现,子组件中,默认无法访问到 父组件中的data 上的数据和methods中的方法
                com1: {
                    data() {
                        //注意:
                        // 1.子组件中的data数据,并不是父组件传递过来的,
                        // 而是自身私有的,比如:子组件通过Ajax,请求回来的数据,都
                        // 可以放到data身上
                        // 2.子组件中data中数据都是可读可写的
                        return {
                            title: '1234',
                            content: 'qqq'
                        }
                    },
                    template: "<h1>这是子组件---{{parentmsg}}</h1>",
                    // 把父组件传递过来的parentmsg属性,先在props数组中,定义一下,这样,才能使用这个数据
                    // 注意::
                    // 1.props中的数据,都是只读的,无法重新赋值
                    props: ['parentmsg'],

                    methods: { },
                },


            }



        })
    </script>
</body>

</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KOubgNXT-1599142789294)(img/1594302213099.png)]

父组件传递方法给子组件调用

利用绑定事件函数和$emit去触发

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../vue.js"></script>
    <link rel="stylesheet" href="../bootstrap-3.3.7/dist/css/bootstrap.min.css">
</head>

<body>

    <div id="app">
        <cmt-box @func="localComments"></cmt-box>
        <ul class="list-group">
            <li class="list-group-item" v-for="item in list" :keys="item.id">
                <span class="badge">评论人:{{item.user}}</span>
                {{item.content}}
            </li>
        </ul>
    </div>

    <template id="tmpl1">
        <div>
            <div class="form-group">
                <label>评论人:</label>
                <input type="text" class="form-control" v-model="user">
            </div>

            <div class="form-group">
                <label>评论内容:</label>
                <input type="text" class="form-control" v-model="content">
            </div>

            <div class="form-group">
                <input type="button" value="发表评论" class="btn btn-primary" @click="postComment">
            </div>
        </div>
    </template>







    <script>

        // 评论盒子
        var commentBox = {
            template: "#tmpl1",
            data() {
                return {
                    user: "",
                    content: ""
                }
            },
            methods: {
                postComment() {  //发表评论的方法
                    // 分析:发表评论的业务逻辑
                    // 1.评论数据存到哪里去?存放到了localStorage中
                    // 2.先组织一个最新的评论数据对象
                    // 3.想办法,把第二步中,得到的评论对象,保存到localStorage中
                    // 3.1localStorage只支持存放字符串数据,要先调用JSON.stringify
                    // 3.2在保存最新的评论数据之前,要先从localStorage获取到之前的评论数据(string)
                    // ,转换为一个数组对象,然后,把最新的评论push进去
                    // 3.3如果获取到的localStorage中的评论字符串,为空不存在,则可以返回一个'[]' 
                    // 让JSON.parse去转换,保证不会报错
                    // 3.4把最新的评论列表数组,再次调用JSON.stringify转为数组字符串,然后
                    // 调用localStorage.setItem()

                    var comment = { id: Date.now(), user: this.user, content: this.content }

                    // 从localStorage中获取所有的评论
                    var list=JSON.parse(localStorage.getItem("cmts")||"[]")
                    list.unshift(comment)
                    // 重新保存最新的评论数据
                    localStorage.setItem("cmts",JSON.stringify(list))
                    this.user=this.content=''

                    

                    this.$emit('func')

                }
            }
        }

        var vm = new Vue({
            el: '#app',
            data: {
                list: [
                    { id: Date.now(), user: '李白', content: '天生我才必有用' },
                    { id: Date.now(), user: '江小白', content: '劝君更进一杯酒' },
                    { id: Date.now(), user: '夫子', content: '天不生夫子,万古如长夜' },
                    { id: Date.now(), user: '李慢慢', content: '我已经学会了打架' },

                ]
            },    
            beforeCreate() {    //注意:这里不能调用localStorage方法,因为在执行这个钩子
            //函数的时候,data和methods都还没有被初始化
                
            },
            created() {
                // 不能直接访问调用,需要用this来进去访问
                this.localComments();
                
            },
            methods: {
                // 从本地的localStorage中,加载评论列表
                localComments(){
                    var list=JSON.parse(localStorage.getItem('cmts')||'[]')
                    this.list=list
                }
            },
            components: {
                "cmt-box": commentBox
            }
        })
    </script>
</body>

</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZF0Q60hs-1599142789295)(img/1594311898654.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OKvIQK06-1599142789297)(img/1594311917150.png)]

ref获取DOM信息

vm.$refs

案例:

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

    <div id="app">
        <input type="button" value="获取DON元素" @click='getDOM' ref="mybtn">
        <p id="RT" ref="getEle">我就是那个DOM</p>

        <hr>
        <login ref="mylogin"></login>
    </div>

    <script>

        var login={
            template:'<h1>登录组件</h1>',
            data(){
                return {
                    msg:"李荣浩你妈的"
                }
            },
            methods: {
                show(){
                    console.log("子组件的方法")
                }
            },
        }

        var vm=new Vue({
            el:'#app',
            data:{},
            methods: {
                getDOM(){
                    console.log(this.$refs.mylogin.msg)
                }
            },
            components:{
                login:login
            }
        })
    </script>
    
</body>
</html>

路由

前端路由和后端路由的概念

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FuEcPtNu-1599142789298)(img/1594384422863.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iWY6mlAc-1599142789299)(img/1594384642089.png)]

安装vue-router的两种方式

1.CDN引用或者下载安装包引入

2.npm下载模块引入

地址:https://router.vuejs.org/installation.html#direct-download-cdn

vue-router基本使用

基本写法(与官网文档稍微不同),但简易理解

<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../vue.js"></script>
    <!-- 1.安装路由模块 -->
    <script src="../vue-router.js"></script>
</head>

<body>
    <div id="app">
        <a href="#/login">登录</a>
        <a href="#/register">注册</a>

        <!-- 这是vue-router提供的元素,专门当作占位符的,将来,路由规则,匹配到的组件, -->
        <!-- 就会展示到这个router-view中去 -->
        <!-- 所以我们可以把它认为是一个占位符 -->
        <router-view></router-view>
    </div>


    <script>

        // 组件的模板对象
        var login = {
            template: "<h1>登录组件</h1>"
        };
        var register = {
            template: "<h1>注册组件</h1>"
        };


        // 路由列表
        //2. 创建一个路由对象,当导入vue-router包之后,在window全局对象
        // 中,就有了一个路由的构造函数,叫做VueRouter
        // 在new 路由对象的时候,可以为构造函数,传递一个配置对象
        var routerObj = new VueRouter({
            //route//这个配置中的route表示【路由匹配规则】的意思
            routes: [
                // 每个路由规则,都是一个对象,这个规则对象,身上,有两个必须的属性
                //属性1:是path ,表示监听哪个路由链接地址;
                //属性2:是component,表示,如果路由时前面匹配到的path,则展示component属性对应的那个组件

                // 注意:component的属性值,必须是一个组件的模板对象,不能是组件的引用名称
                { path: '/login', component: login },
                { path: '/register', component: register }

            ]
        });

        // 使用插件
        // //调用 `MyPlugin.install(Vue)`
        // Vue.use(MyPlugin)

        var vm = new Vue({
            el: "#app",
            data: {},
            methods: {},
            //将路由规则对象,注册到vm实例上,用来监听URL地址的变化,然后展示对应的组件
            router: routerObj

        })



    </script>

</body>

</html>

重定向

                //重定向:redirect;  这里的redirect和node中的redirect完全是两码事
                { path: '/', redirect: "/login" },
                { path: '/login', component: login },
                { path: '/register', component: register }

路由router-link的使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lWXCcsk8-1599142789300)(img/1594399718296.png)]

修改默认类

示例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../vue.js"></script>
    <script src="../vue-router.js"></script>
    <style>
        .router-link-active,
        .myactive{
            color: red;
            font-weight: 700;
            font-style: italic;
            font-size: 60px;
            text-decoration: underline;
        }
    </style>
</head>

<body>

    <div id="app">
        <router-link to="/login">登录</router-link>
        <router-link to="/register">注册</router-link>

        <!-- 占位符 -->
        <router-view></router-view>
    </div>


    <script>
        // 组件模板
        var login={
            template:"<h1>登录组件</h1>"
        }

        var register={
            template:"<h1>注册组件</h1>"
        }


        // 创建路由实例
        var routerObj = new VueRouter({
            // 配置路由列表及组件
            routes: [
                { path: "/login", component: login },
                { path: "/register", component: register }
            ],
            // 该属性可以把该默认类名改成自己设定的类
            linkActiveClass:"myactive",
            // linkExactActiveClass:"linkClass"
        })


        var vm = new Vue({
            el: '#app',
            data: {},
            methods: {},
            // 注册路由实例
            router: routerObj
        })
    </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>
    <script src="../vue.js"></script>
    <script src="../vue-router.js"></script>
    <style>
        .router-link-active,
        .myactive {
            color: red;
            font-weight: 700;
            font-style: italic;
            font-size: 60px;
            text-decoration: underline;
        }


        .v-enter,
        .v-leave-to{
            opacity: 0;
            transform: translateX(140px);
        }

        .v-enter-active,
        .v-leave-active{
            transition: all 0.5s ease;
        }
    </style>
</head>

<body>

    <div id="app">
        <router-link to="/login">登录</router-link>
        <router-link to="/register">注册</router-link>

        
        <transition mode="out-in">
            <!-- 占位符 -->
            <router-view></router-view>
        </transition>
    </div>


    <script>
        // 组件模板
        var login = {
            template: "<h1>登录组件</h1>"
        }

        var register = {
            template: "<h1>注册组件</h1>"
        }


        // 创建路由实例
        var routerObj = new VueRouter({
            // 配置路由列表及组件
            routes: [
                { path: "/login", component: login },
                { path: "/register", component: register }
            ],
            // 该属性可以把该默认类名改成自己设定的类
            // linkActiveClass: "myactive",
            // linkExactActiveClass:"linkClass"
        })


        var vm = new Vue({
            el: '#app',
            data: {},
            methods: {},
            // 注册路由实例
            router: routerObj
        })
    </script>



</body>

</html>

路由传参

使用query方式传递参数

$route的含义及传参方式

r o u t e 和 route和 routerefs差不多,都是vue的实例。打印出来都是一个对象。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../vue.js"></script>
    <script src="../vue-router.js"></script>
</head>

<body>

    <div id="app">
        <router-link to="/login?id=10&name=张三">登录</router-link>
        <router-link to="/register">注册</router-link>

        <!-- 占位 -->
        <router-view></router-view>
    </div>

    <script>
        // 组件模板
        var login = {
            // template里的this可以省略直接写$route.query.id
            template: "<h1>登录---{{$route.query.id}}---{{$route.query.name}}</h1>",
            created() {     //组件的生命周期 钩子函数

                // 该$route和该$refs差不多,也是个实例
                console.log(this.$route)
            },
        }

        var register = {
            template: "<h1>注册</h1>"
        }

        // 实例化路由
        const routerObj = new VueRouter({
            // 配置路由参数及列表
            routes: [
                { path: "/login", component: login },
                { path: "/register", component: register }
            ]
        })


        var vm = new Vue({
            el: '#app',
            data: {},
            methods: {},
            // 注册路由实例
            router: routerObj

        })
    </script>

</body>

</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-avO9UiXZ-1599142789301)(img/1594476154076.png)]

使用params方式传递路由参数

路由参数匹配的第二种形式params

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../vue.js"></script>
    <script src="../vue-router.js"></script>
</head>

<body>

    <div id="app">
        <router-link to="/login/12/张三">登录</router-link>
        <router-link to="/register">注册</router-link>

        <!-- 占位 -->
        <router-view></router-view>
    </div>

    <script>
        // 组件模板
        var login = {
            // template里的this可以省略直接写$route.query.id
            template: "<h1>登录---{{$route.params.id}}---{{$route.params.name}}</h1>",
            created() {     //组件的生命周期 钩子函数

                // 该$route和该$refs差不多,也是个实例
                console.log(this.$route)
            },
        }

        var register = {
            template: "<h1>注册</h1>"
        }

        // 实例化路由
        const routerObj = new VueRouter({
            // 配置路由参数及列表
            routes: [
                { path: "/login/:id/:name", component: login },
                { path: "/register", component: register }
            ]
        })


        var vm = new Vue({
            el: '#app',
            data: {},
            methods: {},
            // 注册路由实例
            router: routerObj

        })
    </script>

</body>

</html>

写法区别:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GIxq2HpP-1599142789303)(img/1594476740351.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3gxuJ55i-1599142789304)(img/1594476756173.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tC1qNK4f-1599142789305)(img/1594476801502.png)]

路由嵌套

使用children属性实现路由嵌套

示例:(嵌套写法)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../vue.js"></script>
    <script src="../vue-router.js"></script>
</head>

<body>

    <div id="app">

        <router-link to="/account">展示Account</router-link>

        <router-view></router-view>
    </div>

    <template id="tmpl">
        <div>
            <h1>这是Account 组件</h1>

            <router-link to="/account/login">登录</router-link>
            <router-link to="/account/register">注册</router-link>
            <router-view></router-view>
        </div>
    </template>

    <script>

        // 组件模板
        const account = {
            template: "#tmpl"
        }
        const login = {
            template: "<h3>登录</h3>"
        }
        const register = {
            template: "<h3>注册</h3>"
        }

        // 创建路由模块
        const router = new VueRouter({
            routes: [
                {
                    path: '/account',
                    component: account,
                    //使用children属性,实现子路由,同时,子路由的path前面,不要带/ ,
                    // 否则永远以根路径开始请求,这样不方便我们用户去理解url地址
                    children: [
                        { path: 'login', component: login },
                        { path: 'register', component: register }
                    ]
                },

            ]
        })

        const vm = new Vue({
            el: '#app',
            data: {},
            methods: {},
            router: router
        })
    </script>
</body>

</html>

使用命名视图实现经典布局

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iGGWaFzz-1599142789306)(img/1594483354062.png)]

利用router-view中的name属性和创建路由时配置路由的命名路由名字联系,实现经典布局

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../vue.js"></script>
    <script src="../vue-router.js"></script>
    <style>
        html,body{
            margin: 0;
            padding: 0;
        }

        .header{
            background-color: orange;
            height: 80px;
        }
        h1{
            margin: 0;
            padding: 0;
            font-size: 16px;
        }

        .container{
            display: flex;
            height: 600px;
        }
        .left{
            background-color: lightgreen;
            flex: 2;
        }

        .main{
            background-color: lightpink;
            flex: 8;
        }
    </style>
</head>

<body>
    <div id="app">

        <router-view></router-view>
        <div class="container">
            <router-view name="left"></router-view>
            <router-view name="main"></router-view>
        </div>
    </div>


    <script>
        var header = {
            template: "<h1 class='header'>Header头部区域</h1>"
        }

        var leftBox = {
            template: "<h1 class='left'>侧边栏区域</h1>"
        }

        var mainBox = {
            template: "<h1 class='main'>主体区域</h1>"
        }

        // 创建路由
        const router = new VueRouter({
            routes: [
                {   //利用name属性来匹配路由,实现视图布局
                    path: '/', components: {
                        default: header,
                        left: leftBox,
                        main: mainBox
                    }
                },

            ]
        })



        var vm = new Vue({
            el: "#app",
            data: {},
            methods: {},
            router
        })



    </script>
</body>

</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8IpHK3Qi-1599142789307)(img/1594732225005.png)]

关于命名视图的名称到底是变量还是字符串的说明

举例:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wXFn2cTD-1599142789309)(img/1594732392697.png)]

例如在name属性前加冒号了,说明等号后面的是变量,如果不加的话,永远都是个值。

watch

名称案例-使用keyup事件实现

案例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../vue.js"></script>
    <script src="../vue-router.js"></script>
</head>

<body>
    <div id="app">
        <!-- 分析: -->
        <!-- 1.我们要监听到 文本框数据的改变,这样才知道 什么时候去拼接 出一个 fullname -->
        <!-- 2.如何监听到 文本框的数据改变呢??? -->
        <input type="text" v-model="firstname" @keyup="getFullname"> +
        <input type="text" v-model="lastname" @keyup="getFullname"> =
        <input type="text" v-model="fullname">
    </div>


    <script>
        const vm = new Vue({
            el: "#app",
            data: {
                firstname: '',
                lastname: '',
                fullname: ''
            },
            methods: {
                getFullname() {
                    this.fullname = this.firstname + "-" + this.lastname
                }
            }
        })
    </script>
</body>

</html>

名称案例-使用watch监听事件

利用watch代替监听事件。

使用这个属性,可以监视data中指定数据的变化,然后触发这个watch中对应的 function处理函数

案例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../vue.js"></script>
    <script src="../vue-router.js"></script>
</head>

<body>
    <div id="app">

        <input type="text" v-model="firstname"> +
        <input type="text" v-model="lastname"> =
        <input type="text" v-model="fullname">
    </div>


    <script>
        const vm = new Vue({
            el: "#app",
            data: {
                firstname: ''||0,
                lastname: ''||0,
                fullname: ''
            },
            methods: {},
            watch: { //使用这个属性,可以监视data中指定数据的变化,然后触发这个watch中对应的
                // function处理函数
                //这样写代表要监视firstname这个属性,数据改变了就会触发后面的这个处理函数
                // 注意:firstname需不需要加引号的问题:有横线的时候(first-name),需要加引号,没有横线的时候可加可不加
                firstname: function () {
                    this.fullname=parseInt(this.firstname)+parseInt(this.lastname)
                },
                lastname: function () {
                    // console.log("监听到了fastname的变化")
                    this.fullname=parseInt(this.firstname)+parseInt(this.lastname)
                }
            },
        })
    </script>
</body>

</html>

watch-监视路由地址的改变

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>
    <script src="../vue.js"></script>
    <script src="../vue-router.js"></script>
</head>

<body>

    <div id="app">
        <router-link to="/login">登录</router-link>
        <router-link to="/register">注册</router-link>
        
        <router-view></router-view>
    </div>

    <script>
        // 创建子组件
        var login = {
            template: "<h3>这是登录子组件</h3>"
        }

        var register = {
            template: "<h3>这是登录父组件</h3>"
        }

        // 创建并配置路由
        const router = new VueRouter({
            routes: [ //
                {
                    path: "/",
                    redirect: "/login"
                },
                {
                    path: "/login",
                    component: login
                },
                {
                    path: "/register",
                    component: register
                }
            ]
        })

        const vm = new Vue({
            el: "#app",
            data: {},
            methods: {},
            router,
            watch: {
                //this.$route.path
                "$route.path":function(newVal,oldVal){
                    // console.log(newVal+"--"+oldVal)
                    if(newVal=="/login"){
                        console.log("欢迎进入登录页面")
                    }else if(newVal=="/register"){
                        console.log("欢迎进入注册页面")
                    }
                }
            },
        })
    </script>
</body>

</html>

computed

computed-计算属性的使用和三个特点

具体用法查示例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../vue.js"></script>
    <script src="../vue-router.js"></script>
</head>

<body>
    <div id="app">

        <input type="text" v-model="firstname"> +
        <input type="text" v-model="lastname"> +
        <input type="text" v-model="middlename"> =
        <input type="text" v-model="fullname">

        <p>{{fullname}}</p>
        <p>{{fullname}}</p>
        <p>{{fullname}}</p>
    </div>


    <script>
        const vm = new Vue({
            el: "#app",
            data: {
                firstname: '',
                lastname: '',
                middlename: ''
            },
            methods: {},
            computed: { //在computed中可以定义一些属性,这些属性,叫做【计算属性】。
                //计算属性的本质,就是一个方法,只不过,我们在使用这些计算属性的时候,
                //是把它们的名称,直接当作属性来使用的,并不会把计算属性当作方法去调用

                // 注意1:计算属性,在引用的时候,一定不要加小括号去调用,直接把它当作普通属性去使用就好
                // 注意2:只要计算属性,这个function内部,所用到的任何data中的数据发生了变化,就会
                //触发这个属性立即重新计算这个 计算属性的值
                // 注意3:计算属性的求值结果,会被缓存起来,方便下次直接使用,如果 计算属性方法中,所以来的
                // 任何数据,都没有发生变化,则不会重新对 计算属性求值,比如ok只打印了一次
                "fullname": function () {
                    console.log("ok")
                    return this.firstname + this.middlename + this.lastname
                }

            },
        })
    </script>
</body>

</html>

nrm

nrm的使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mvGPQjs7-1599142789311)(img/1594816273965.png)]

注意:nrm只是单纯的提供了几个常用的下载包的URL地址,在这几个地址之间,很方便的进行切换,但是,我们每次装包的时候,使用的装包工具,都是npm

webpack

概念的引入

官网地址:https://webpack.js.org/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LimCdQ8n-1599142789312)(img/1594827785496.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gaC0B8SM-1599142789314)(img/1594827673528.png)]

最基本的使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zv9zpIO0-1599142789315)(img/1594828282937.png)]

webpack4.0+入门使用教程:(输入输出及配置)

https://www.jianshu.com/p/b30cf56a431f

总结:

1.创建package.json文件	npm init -y
2.安装webpack4和webpack-cli	//注意:webpack4及以上需要同时安装webpack-cli
3.删除package.json中 "main": "index.js" 项,加上 "private": true4.在src文件夹下创建 index.js 文件 和 index.html 文件
5.在index.html文件中body下面引用script标签,导入文件st/main.js (此时main.js文件还未生成)
6.配置webpack的config,创建webpack.config.js文件,配置内容如下:
	const path = require('path');
	module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'main.js',
        path: path.resolve(__dirname, 'dist')
    	}
	};
	
7.修改package.json文件中 "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  }该项为
  "scripts": {
    "build": "webpack"
  },
8.运行打包命令	npm run build

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zx8Q9yf2-1599142789316)(image/image-20200716153534955.png)]

webpack-dev-server

工具:webpack-dev-server

配置命令的第一种方式

webpack-dev-server的基本使用[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A1b8ysbT-1599142789317)(image/image-20200716155016010.png)]

webpack-dev-server相当于nodemon这类工具,自动监听原文件代码的改变自动运行执行同步更改后的打包文件

使用webpack-dev-server这个工具,来实现自动打包编译的功能

1.运行npm i webpack-dev-server -D 把这个工具安装到项目的本地开发依赖
2.安装完毕后,这个工具的用法,和webpack命令的用法,完全一样
3.由于,我们市在项目中,本地安装的webpack-dev-server,所以,无法把它当作脚本命令,在powershell终端直接运行,(只有那些 安装到全局 -g 的工具,才能在终端中正常执行)
解决方式:
在package.json中的"script":{
    "dev":"webpack-dev-server"
}项配置运行命令
执行npm run dev 即可运行该工具
配置命令的第二种方式

不常用,了解就行(案例未能实现,以后查阅)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YdrRifHk-1599142789319)(img/1594907285271.png)]

html-webpack-plugin

webpack插件2:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3d1G24pi-1599142789320)(img/1594909893992.png)]

这个插件的两个作用:

  1. 自动在内存中根据指定的页面生成一个内存的页面
  2. 自动把打包好的bundle.js引用追加到页面中去

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jb1GdoyB-1599142789322)(img/1594912129141.png)]

loader

配置处理css样式表的第三方loader
    <!-- // css会发起二次请求,不推荐这么搞 -->
    <!-- <link rel="stylesheet" href="./css/index.css"> -->

用import语法,导入css样式表

import "./css/index.css"

注意:webpack默认只能打包处理JS类型的文件,无法处理其他非JS类型的文件

如果要处理非 JS 类型的文件,我们需要手动安装一些 合适的第三方loader 加载器

安装笔记:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dgzn9CsP-1599142789323)(img/1594912890767.png)]

第一步:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3XYGIg16-1599142789324)(img/1594913652486.png)]

总结:两个文件需要针对配置

1.webpack.config.js

1.下载安装该两个插件	//npm i style-loader css-loader
2.节点配置,规则匹配	//表示启用哪些模块来进行处理匹配

节点配置,规则匹配:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kMCVnNOV-1599142789325)(img/1594914745527.png)]

2.入口编译文件index.js

调用import语法引入css文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MOnT1gue-1599142789326)(img/1594914888767.png)]

3.命令刷新页面:

npm run dev

注意:webpack处理第三方文件类型的过程:

1。发现这个 要处理的文件不是js文件,然后就去 配置文件中,查找有没有对应的第三方 loader 处理 这种文件类型
2.如果能找到对应的规则,就会调用 对应的 loader 处理 这种文件类型
3.在调用loader 的时候,是从后往前 调用的;
4.当最后的一个loader 调用完毕后,会把 处理的结果,直接交给 webpack 进行 打包合并,最终输出到bundle.js中去
配置处理less文件的loader

安装:

npm i less-loader -D
npm i less -D

配置步骤与配置css文件规则一致,正则匹配几乎一致

配置处理sass文件的loader

安装

npm i sass-loader -D
npm i node-sass -D

入口文件引入scss文件,配置规则

day6

url-loader

url-loader的使用

默认情况下,webpack是无法处理css文件中的url地址,不管是图片还是字体库,只要是url地址,都处理不了

安装:

npm i url-loader file-loader -D

注意:url-loader同时也依赖于内部的一个file-loader模块,配置文件中不必配置file-loader

传参方式:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-38fRJdqw-1599142789327)(img/1595019162094.png)]

limit是给定的值,是图片的大小,单位是byute,如果我们引用的图片,大于或等于给定的limit值,则不会被转为base64格式的字符串,如果图片小于给定的limit值,则会被转为base64的字符串

如果不想改变图片名称:则可以传参为:

use:"url-loader?limit=7631&name=[name].[ext]"

注:name传参为固定写法

也可以利用hash值拼接原图片名,写法如下:展示的是:hash值前八位-原图片名称

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6UUmbym4-1599142789328)(img/1595022559833.png)]

url-loader处理字体文件

百度或者查阅文档

关于webpack和npm中几个问题的说明

1.json中不能写注释

babel的配置

前提:

//class 关键字,是ES6中提供的新语法,是用来实现ES6面向对象编程的方式
class Person {
	//使用static关键字,可以定义静态属性
    //所谓的静态属性,就是 可以直接通过 类名,直接访问的属性:例如Person.info
    //实例属性:只能通过类的实例,来访问的属性,叫做实例属性
	static info = {name:"zs",age:20}
}

//访问Person类身上的 info 静态属性
console.log(Person.info)


注: 在webpack中,默认只能处理一部分ES6的新语法,一些更高级的ES6语法或者ES7语法,webpack是处理不了的;这时候,就需要 借助于第三方的 loader ,来帮助webpack 处理这些高级的语法,当第三方loader把高级语法转为低级语法之后,会把结果交给webpack去打包到bundle.js中

//通过Babel,可以帮我们将高级的语法转换为 低级的语法
//在webpack中,可以运行如下两套命令,安装两套包,去安装Babel 相关的loader功能:

//第一步:	babel-loader是加载器
第一套包:npm i babel-core babel-loader babel-plugin-transform-runtime -D
第二套包:npm i babel-preset-env babel-preset-stage-0 -D

//第二步:
打开webpack的配置文件,在module节点下的rules数组中,添加一个新的 匹配规则:
{test:/\.js$/,use:"babel-loader",exclude:/node_modules/}
//注意1:exclude是排除的意思,排除node_modules这个文件夹里的Js文件。
//注意2:在配置babel的loader规则时候,必须把node_modules目录,通过exclude选项排除掉,原因有俩:
	//2.1:如果不排除node_modules,则Babel会把node_modules中所有的第三方JS文件,都打包编译,这样,会非常消耗CPU,同时,打包速度非慢;
	//2.2:哪怕最终,Babel 把所有 node_modules 中JS转换完毕了,但是,项目也无法正常运行!

//第三步:
在项目的 根目录中,新建一个 叫做 .babelrc 的Babel 配置文件,这个配置文件,属于JSON格式,所以,在写 .babelrc配置的时候,必须符合JSON语法规范;不能写注释,字符串必须用双引号。
//配置入下:	//大家可以把preset翻译成语法的意思
{
    "presets":["env","stage-0"],
    "plugins":["transform-runtime"]
}


注释:babel在webpack中配置更新很快,简易网络查询,笔记中配置可能会出差错(具体差错原因可能包被废弃或者少包,目前正常),同时,加载器babel-loader的版本对应babel-core核心包的版本相差一个版本(例如:babel-core@6,对应的是babel-loader@7版本)

packag.json第三方模块安装图如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7HdF7xT8-1599142789330)(img/1595155180550.png)]

关于Babel的几点说明

//第四步
了解:目前我们安装的 babel-preset-env,是比较新的ES语法,之前,我们安装的是babel-preset-es2015

render

使用vue实例的render方法渲染组件

render函数会渲染组件,但是只会渲染单个组件。

原理:render函数会把挂载的 el容器替换掉为组件。原先的容器直接会被删除掉。

实例:

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

    <script>
        // 组件模板对象
        var login={
            template:"<h1>这是登录组件</h1>"
        }

        var vm = new Vue({
            el:"#app",
            data:{},
            methods:{},
            render:function(createElement){
                return createElement(login);
            }
        })


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

components注册的组件相当于插值表达式,只替换当前位置,不会把容器清空。

区分webpack中导入vue和普通网页使用script导入Vue的区别

//如何在webpack 构建的项目中,使用vue进行开发

// 在wwebpack中,使用import Vue from "vue" 导入的Vue构造函数,功能不完善,只提
// 供了runtime-only的方式,并没有提供像网页中那样的使用方式


//如何在webpack 构建的项目中,使用vue进行开发

// 在wwebpack中,使用import Vue from "vue" 导入的Vue构造函数,功能不完善,只提
// 供了runtime-only的方式,并没有提供像网页中那样的使用方式
// import Vue from "vue"    //错误示范

//第一种方式
import Vue from "../node_modules/vue/dist/vue.js"

var vm =new Vue({
    el:"#app",
    data:{
        msg:"123"
    }
})



//第二种方式		还是直接导入vue,但是在webpack.config.js中做一些配置。写法如下:
//入口文件-index.js:
import Vue from "vue"
var vm =new Vue({
    el:"#app",
    data:{
        msg:"123"
    }
})

//配置文件-webpack.config.js
module.exports={
	resolve:{
		alias:{ //修改Vue被导入时候的包的路径
			"vue$":"vue/dist/vue.js"
		}
	}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9MW3bRK2-1599142789332)(image/image-20200720172347940.png)]

在vue中结合render函数渲染指定的组件到容器中

入口文件:

// 第二种引入方式,在webpack里加一个节点,跟modules平级
import Vue from 'vue'


// 导入login组件
import login from "./login.vue"
// 默认 webpack 无法打包 .vue文件,需要安装 相关的loader加载器:
// 1. vue-loader 内部依赖 vue-template-compiler
// npm i vue-loader vue-template-compiler -D
// 2. 在配置文件中新增一个配置项,{test:/\.vue$/,use:"vue-loader"}

var vm =new Vue({
    el:"#app",
    data:{
        msg:"123"
    },
    // components:{
    //     login
    // }
    render:function(createElement){
        return createElement(login)
    }
})

login.vue文件:

<template>
    <div>
        <h1>这是登录组件,使用 .vue 文件定义出来的</h1>
    </div>
</template>

配置文件webpack.config.js:

const path = require('path');
// 导入在内存中生成的HTML页面的插件
// 只要是插件,都一定要放到plugins节点中去
const htmlWebpackPlugin = require("html-webpack-plugin");
const VueLoaderPlugin = require('vue-loader/lib/plugin')



module.exports = {
    // entry: path.join(__dirname, './src/index.js'),
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    devServer: {
        port: 3000,
        contentBase: path.join(__dirname, 'dist'),
        open: true
    },
    plugins: [ //配置插件的节点
        new htmlWebpackPlugin({ //创建一个 在内存中生成的 HTML 页面的插件

            //指定 模板页面,将来会根据指定的页面路径,去生成内存中的页面
            template: path.join(__dirname, "./src/index.html"),
            filename: "index.html" //指定生成的页面的名称
        }),
        new VueLoaderPlugin(),
    ],
    module: { //这个节点,用于配置 所有 第三方模块 加载器
        rules: [ //所有第三方模块匹配规则
            {
                test: /\.css$/,
                //配置处理 .css文件第三方的第三方loader规则
                use: ["style-loader", "css-loader"]
            }, 
            {
                test: /\.less$/,
                //配置处理 .less文件的第三方loader规则
                use: ["style-loader", "css-loader", "less-loader"]
            },
            {
                test:/\.scss$/,use:["style-loader","css-loader","sass-loader"]
            },
            {
                test:/\.(jpg|png|gif|bmp|jpeg)$/,use:"url-loader?limit=7631&name=[name].[ext]"
            },
            {
               test:/\.(ttf|eot|svg|woff|woff2)$/,use:"url-loader" 
            },
            // babel配置来转换高级的ES语法
            {
                test:/\.js$/,use:"babel-loader",exclude:/node_modules/
            },
            // vue-loader配置项
            {test:/\.vue$/,use:"vue-loader"}
        ]

    },

    resolve:{
        alias:{ //修改Vue被导入时候的包的路径
            "vue$":"vue/dist/vue.js"
        }
    }

}

配置坑一

配置 vue-loader 和 vue-template-compiler 巨坑之一:

Webpack+Vue+Vue-loader+Vue-template-compiler的坑1

注意:具体错误形式我也懒得写了,心累死了。

就是一定要注意在配置Webpack+Vue的时候,版本的依赖问题!

如果Vue是什么版本,Vue-loader也要是什么版本,以此减少错误。

还有就是如果使用了Vue-template-compiler的15x以上的版本,还要在Webpack.config.js中添加:

const VueLoaderPlugin = require('vue-loader/lib/plugin')
在下面的plugins中添加 new VueLoaderPlugin(),

这里有一个坑,如果使用的不是15x版本的话,则不需要添加后面的/lib/plugin,但是如果使用了这个版本的话,一定要记得添加上,否则就会出现cannot find plugin的错误。
————————————————
版权声明:本文为CSDN博主「西大野」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_39339233/java/article/details/84857035

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c2cu1n08-1599142789333)(img/1595260230967.png)]

export default 和 export的使用方式

// 这是 Node 中向外暴露成员的形式
module.exports = { }


// 在ES6中,也通过规范的形式,规定了ES6中如何 导入 和导出 模块
// ES6中导入模块,使用 import 模块名称 from "模块标识符"       import "表示路径"

//在ES6中,使用export default 和 export 向外暴露成员:
//export default 方式:
暴露文件:
export default {
    name:"zhangsan",
    age:20
}
引入文件:
import m1 from "./test.js"
console.log(m1)
//注意1:在一个模块中,export default 只允许向外暴露一次
//注意2:在一个模块中,可以同时使用 export default 和 export 向外暴露成员
//注意3:export default 向外暴露的成员,可以使用任意的变量来接收

//export 方式:
暴露文件:
export var title = "小星星"

引入文件:
import m1,{title} from ".test.js"
console.log(m1,title)

关键字as:
import m1,{title as title123} from ".test.js"
console.log(m1,title123)

//注意1:使用export向外暴露的成员,只能使用 { } 的形式来接受,这种形式,叫做【按需导出】
//注意2:export 可以向外暴露多个成员,同时,如果某些成员,我们在import 的时候不需要,则可以不在 {} 中定义
//注意3:使用export 导出的成员,必须严格按照 导出时候的名称,来使用 {} 按需接收;
//注意4:使用export 导出的成员,如果就想 换个 名称 来接收,可以使用 as 来起别名;






//在Node中 使用 var 名称 = require("模块标识符")
//module.exports 和 exports 来暴露成员

注意:Node暴露成员和引入方式 与 ES6暴露成员和引入方式 不要混用

其他写法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E7RpgnHT-1599142789334)(image/image-20200721093039973.png)]

webpack + vue-router

vue-router

(模块化工具)

官网:https://router.vugejs.org/zh/installation.html

实例:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L4vnwB7u-1599142789335)(image/image-20200721160032322.png)]

入口文件:Index.js

import Vue from "vue"

// 1.导入vue-router
import VueRouter from "vue-router"
// 2.手动安装VueRouter
Vue.use(VueRouter)

// 导入app组件
import app from "./app.vue"
// 导入Account,goodslist组件
import account from "./main/Account.vue"
import goodslist from "./main/Goodslist.vue"

// 3.创建路由对象
const router = new VueRouter({
    routes: [
        // account goodslist
        {path:"/account",component:account},
        {path:"/goodslist",component:goodslist}
    ]
})

var vm = new Vue({
    el: "#app",
    render: c => c(app),
    //4.将路由对象挂载到vue实例上
    router
})

app.vue组件:

<template>
  <div>
    <h1>这是 App 组件</h1>

    <router-link to="/account">Account</router-link>
    <router-link to="/goodslist">Goodslist</router-link>

    <router-view></router-view>
  </div>
</template>

<script>
export default {};
</script>

<style lang="">
</style>

Account.vue组件:

<template>
    <div>
        <h1>这是 Account 组件</h1>
    </div>
</template>

<script>
export default {
    
}
</script>

<style lang="">
    
</style>

Goodslist.vue组件:

<template>
    <div>
        <h1>这是 Goodslist 组件</h1>
    </div>
</template>

<script>
export default {
    
}
</script>

<style lang="">
    
</style>

vscode扩展包:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1BqlZhHR-1599142789336)(image/image-20200721161716021.png)]

实现路由嵌套

实例:

import Vue from "vue"

// 1.导入vue-router
import VueRouter from "vue-router"
// 2.手动安装VueRouter
Vue.use(VueRouter)

// 导入app组件
import app from "./app.vue"
// 导入Account,goodslist组件
import account from "./main/Account.vue"
import goodslist from "./main/Goodslist.vue"

// 导入Account的登录子组件
import login from "./subcom/login.vue"
import register from "./subcom/register.vue"


// 3.创建路由对象
const router = new VueRouter({
    routes: [
        // account goodslist
        {
            path: "/account",
            component: account,
            children: [{
                    path: "login",
                    component: login
                },
                {
                    path: "register",
                    component: register
                }
            ]
        },
        {
            path: "/goodslist",
            component: goodslist
        }
    ]
})

var vm = new Vue({
    el: "#app",
    render: c => c(app),
    //4.将路由对象挂载到vue实例上
    router
})

嵌套路由写法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bXZibT6P-1599142789337)(image/image-20200721172518547.png)]

组件中style标签

style标签中lang属性和scoped属性得介绍

vue 单文件组件中样式加载

在写单文件组件时,一般都是把标签、脚本、样式写到一起,这样写个人感觉有点不够简洁,所以就想着把样式分离出去。

采用import加载样式

在局部作用域(scoped)采用**@import加载进来的样式文件,想法是美好的。以为这样加载进来的样式文件也只对当前组件有效;可现实是残酷的,这样加载进来的样式无法限制作用域**。

<style scoped>
    @import "样式文件";
</style>

解决方案

采用 src属性加载样式。

<style src="样式路径" scoped></style>

单个子组件示例:

<template>
  <div>
    <h3>这是Account的登录子组件</h3>
  </div>
</template>

<script>
export default {};
</script>

<style lang="less" scoped>
// 普通得style标签只支持 普通得样式,
// 如果想要启用scss或less,需要为style元素,设置lang属性

// 只要咱们的style标签,是在 .vue 组件中定义的,那么,推荐都为style开启scoped

body {
  div {
    color: red;
  }
}
</style>

抽离路由模块

新建一个inde,js平级中新建一个router.js。把创建路由对象部分抽离出去,再把路由对象通过export default {}暴露出来,在index.js中引入router.js模块

router.js文件:

// 1.导入vue-router
import VueRouter from "vue-router"

// 导入Account,goodslist组件
import account from "./main/Account.vue"
import goodslist from "./main/Goodslist.vue"

// 导入Account的登录子组件
import login from "./subcom/login.vue"
import register from "./subcom/register.vue"


// 3.创建路由对象
const router = new VueRouter({
    routes: [
        // account goodslist
        {
            path: "/account",
            component: account,
            children: [{
                    path: "login",
                    component: login
                },
                {
                    path: "register",
                    component: register
                }
            ]
        },
        {
            path: "/goodslist",
            component: goodslist
        }
    ]
})


export default router

入口文件index.js:

import Vue from "vue"

// 导入app组件
import app from "./app.vue"

// 2.手动安装VueRouter
Vue.use(VueRouter)

// 导入 自定义路由模块
import router from "./router.js"



var vm = new Vue({
    el: "#app",
    render: c => c(app),
    //4.将路由对象挂载到vue实例上
    router
})


scoped属性选择器的实现原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pxck14PH-1599142789339)(image/image-20200722102046222.png)]

组件中样式的scoped是通过 css 的属性选择器实现的,scoped会为添加了样式的容器自动添加一个自定义属性,转换的 css中再利用属性选择器选中该容器为其添加样式。

day7

Mint UI

Mint UI :基于Vue.js的移动端组件库

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kfShgQfD-1599142789340)(image/image-20200722104042268.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pHU0lbaH-1599142789341)(image/image-20200722104253438.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B8TSrjAL-1599142789343)(image/image-20200722104314465.png)]

官网:http://mint-ui.github.io/docs/#/zh-cn2/button

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m7xEKTgW-1599142789344)(image/image-20200722112340981.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SEgzBEJE-1599142789346)(image/image-20200722112414994.png)]

两种形式:

  • 1.完整引入
    • 完整导入下,CSS Components中的css部分就不需要再进行引入了,直接拿标签过去用就行了
  • 2.按需导入
    • 按需导入下,css部分都需要进行相关引入

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FtazmlwB-1599142789348)(image/image-20200722112237333.png)]

建议直接浏览官方文档

Button组件的使用

Toast组件的使用 //js组件一般都需要引入

实例:

<template>
  <div>
    <h1>这是 App 组件</h1>

    <!-- 为什么这里叫做 mt-button 的 button 直接就能用  因为已经被注册为全局组件了-->
    <mt-button type="primary" icon="more" @click="show">default</mt-button>
    <mt-button type="danger" size="large" plain>danger</mt-button>

    <router-link to="/account">Account</router-link>
    <router-link to="/goodslist">Goodslist</router-link>

    <router-view></router-view>
  </div>
</template>

<script>
import { Toast } from "mint-ui";

export default {
  data() {
    return {};
  },
  methods: {
    show() {
      Toast("提示信息");
    }
  }
};
</script>

<style lang="">
</style>

MUI

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-17aJj6iZ-1599142789349)(img/1595430940120.png)]

官网:https://dev.dcloud.net.cn/mui/

MUI是一套好用的代码片段,里面提供了配套的样式,配套的HTML代码段,类似于Bootstrap,而Mint-UI,是真正的组件库,是使用Vue技术封装出来的成套的组件,可以无缝的和VUE项目进行集成开发。

注意:mui并不能使用 npm 去下载,需要自己手动从 github 上,下载现成的包,自己解压出来,然后手动拷贝到项目中

把本地项目托管到git中

LICENSE文件:开源协议

开源协议:https://zhuanlan.zhihu.com/p/31881162

前后端分离

mock.js

官网文档:http://mockjs.com/

官网模板案例:http://mockjs.com/examples.html

哔哩哔哩视频教程

案例查看请移步至https://github.com/RNGboy/vue-project

day8

Promise

Promise-关于Promise要解决回调地狱的问题的说明

需求:你要封装一个方法,我给你一个要读取的文件的路径,你这个方法能帮我读取文件,并把内容返回给我

const fs = require("fs")
const path = require("path")

function getFileByPath(fpath,succCb,errCb){
	fs.readFile(fpath,"utf-8",(err,dataStr)=>{
		if(err) return errCb(err)
		succCb(dataStr)
	})
}


//嵌套回调
getFileByPath(path.join(__dirname,"./files/1.txt"),function(data){
    console.log(data)
    getFileByPath(path.join(__dirname,"./files/1.txt"),function(data){
    	console.log(data)
        getFileByPath(path.join(__dirname,"./files/1.txt"),function(data){
    		console.log(data)
		})
	})
})

概念介绍

1.Promise是一个构造函数,既然是构造函数,那么 我们就可以 new Promise() 得到一个Promise实例
2.在Promise上,有两个函数,分别叫做 resolve(成功之后的回调函数)reject(失败之后的回调函数)
3.在Promise 构造函数的Prototype 属性上, 有一个 .then()方法,也就是说,只要是Promise 构造函数创建的实例,都可以访问到 .then() 方法
4.Promise表示一个异步操作,每当我们new 一个Promise的实例,就表示一个具体的异步操作
5.既然Promise 创建的实例,是一个异步操作,那么,这个 异步操作的结果,只能有两种状态:
5.1状态1:异步执行成功了。需要在内部调用 成功的回调函数 resolve 把结果返回给调用者
5.2状态2:异步执行失败了。同上
5.3由于Promise 的实例,是一个异步操作,所以,内部拿到 操作的结果后,无法使用return把操作的结果返回给调用者,这时候,只能使用回调函数的形式。


//注意:这里的new 出来的 promise ,只是代表【形式上的】一个异步操作;
//什么形式上的异步操作:就是说,我们只知道它是一个异步操作,但是做什么具体的异步事情,目前还不清除
var promise = new Promise()


//这是一个具体的异步操作,其中 function 指定一个具体的异步操作
var promise = new Promise(function(){
    //这个function 内部写的就是具体的异步操作!!!
})


const fs = require("fs")
//每当new 一个 Promise 实例的时候,就会立即执行这个 异步操作中的代码
//也就是说,new 除了能够得到一个 promise实例之外,还会立即调用 我们为 Promise构造函数传递的哪个 function ,执行这个 function 中的异步操作代码;
var promises = new Promise(function(){
    fs.readFile("./files/2.txt","utf-8",(err,dataStr)=>{
        if(err) throw err
        console.log(dataStr)
    })
})



Promise通过.then指定成功和失败的回调

//初衷:给路径,返回读取到的内容
function getFileByPath(fpath){
    var promise = new Promise(function(resolve,reject){
        fs.readFile(fpath,"utf-8",(err,dataStr)=>{
            if(err) return reject(err)
            resolve(dataStr)
        })
    })
    
    return promise
}

var p = getFileByPath("./files/1.txt")
p.then(function(data){
    console.log(data+"---")
},function(err){
    console.log(err.message)
})

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3yMhJWZA-1599142789350)(img/1595860810735.png)]

当 我们有这样的需求时:哪怕前面大的 Promise 执行失败了,但是,不要影响后续 promise 的正常执行,此时,我们可以单独为每个 promise ,通过.then 指定一下失败的回调;

有问题,我们有这样的需求,上面的的需求刚好相反:如果 后续的 Promise 执行,依赖于 前面 Promise 执行的结果,如果前面的失败了,则后面就没有继续执行下去的意义了,此时,我们想要实现,一旦有报错,则立即终止所有的 Promise 的执行;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6aLxHrUF-1599142789352)(img/1595861479241.png)]

catch作用:如果上面任何一个.then失败了,立即终止执行都会进入catch捕获处理。

也可以单独为每一个指定失败的回调。都可以 。

jQuery中Promise

jQuery中的Ajax也提供了 Promise 操作:

$(function(){
    $("#btn").on("click",function(){
        $.ajax({
            url:"./data.json",
            type:"get",
            dataType:"json"
        })
        //利用.then代替success回调函数输出数据
        .then(function(data){
            console.log(data)
        })
    })
})

vue-preview

一个Vue集成PhotoSwipe图片预览插件,可以实现图片预览

官网:https://github.com/LS1231/vue-preview

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZtKvlpBh-1599142789353)(img/1596550285486.png)]

``vue

这是 App 组件

<!-- 为什么这里叫做 mt-button 的 button 直接就能用  因为已经被注册为全局组件了-->
<mt-button type="primary" icon="more" @click="show">default</mt-button>
<mt-button type="danger" size="large" plain>danger</mt-button>

<router-link to="/account">Account</router-link>
<router-link to="/goodslist">Goodslist</router-link>

<router-view></router-view>





## MUI

[外链图片转存中...(img-17aJj6iZ-1599142789349)]

官网:https://dev.dcloud.net.cn/mui/

MUI是一套好用的代码片段,里面提供了配套的样式,配套的HTML代码段,类似于Bootstrap,而Mint-UI,是真正的组件库,是使用Vue技术封装出来的成套的组件,可以无缝的和VUE项目进行集成开发。

注意:mui并不能使用 npm 去下载,需要自己手动从 github 上,下载现成的包,自己解压出来,然后手动拷贝到项目中



## 把本地项目托管到git中

LICENSE文件:开源协议

开源协议:https://zhuanlan.zhihu.com/p/31881162





## 前后端分离

### mock.js

官网文档:http://mockjs.com/

官网模板案例:http://mockjs.com/examples.html

哔哩哔哩视频教程



案例查看请移步至https://github.com/RNGboy/vue-project

# day8

## Promise

Promise-关于Promise要解决回调地狱的问题的说明

```js
需求:你要封装一个方法,我给你一个要读取的文件的路径,你这个方法能帮我读取文件,并把内容返回给我

const fs = require("fs")
const path = require("path")

function getFileByPath(fpath,succCb,errCb){
	fs.readFile(fpath,"utf-8",(err,dataStr)=>{
		if(err) return errCb(err)
		succCb(dataStr)
	})
}


//嵌套回调
getFileByPath(path.join(__dirname,"./files/1.txt"),function(data){
    console.log(data)
    getFileByPath(path.join(__dirname,"./files/1.txt"),function(data){
    	console.log(data)
        getFileByPath(path.join(__dirname,"./files/1.txt"),function(data){
    		console.log(data)
		})
	})
})

概念介绍

1.Promise是一个构造函数,既然是构造函数,那么 我们就可以 new Promise() 得到一个Promise实例
2.在Promise上,有两个函数,分别叫做 resolve(成功之后的回调函数)reject(失败之后的回调函数)
3.在Promise 构造函数的Prototype 属性上, 有一个 .then()方法,也就是说,只要是Promise 构造函数创建的实例,都可以访问到 .then() 方法
4.Promise表示一个异步操作,每当我们new 一个Promise的实例,就表示一个具体的异步操作
5.既然Promise 创建的实例,是一个异步操作,那么,这个 异步操作的结果,只能有两种状态:
5.1状态1:异步执行成功了。需要在内部调用 成功的回调函数 resolve 把结果返回给调用者
5.2状态2:异步执行失败了。同上
5.3由于Promise 的实例,是一个异步操作,所以,内部拿到 操作的结果后,无法使用return把操作的结果返回给调用者,这时候,只能使用回调函数的形式。


//注意:这里的new 出来的 promise ,只是代表【形式上的】一个异步操作;
//什么形式上的异步操作:就是说,我们只知道它是一个异步操作,但是做什么具体的异步事情,目前还不清除
var promise = new Promise()


//这是一个具体的异步操作,其中 function 指定一个具体的异步操作
var promise = new Promise(function(){
    //这个function 内部写的就是具体的异步操作!!!
})


const fs = require("fs")
//每当new 一个 Promise 实例的时候,就会立即执行这个 异步操作中的代码
//也就是说,new 除了能够得到一个 promise实例之外,还会立即调用 我们为 Promise构造函数传递的哪个 function ,执行这个 function 中的异步操作代码;
var promises = new Promise(function(){
    fs.readFile("./files/2.txt","utf-8",(err,dataStr)=>{
        if(err) throw err
        console.log(dataStr)
    })
})



Promise通过.then指定成功和失败的回调

//初衷:给路径,返回读取到的内容
function getFileByPath(fpath){
    var promise = new Promise(function(resolve,reject){
        fs.readFile(fpath,"utf-8",(err,dataStr)=>{
            if(err) return reject(err)
            resolve(dataStr)
        })
    })
    
    return promise
}

var p = getFileByPath("./files/1.txt")
p.then(function(data){
    console.log(data+"---")
},function(err){
    console.log(err.message)
})

[外链图片转存中…(img-3yMhJWZA-1599142789350)]

当 我们有这样的需求时:哪怕前面大的 Promise 执行失败了,但是,不要影响后续 promise 的正常执行,此时,我们可以单独为每个 promise ,通过.then 指定一下失败的回调;

有问题,我们有这样的需求,上面的的需求刚好相反:如果 后续的 Promise 执行,依赖于 前面 Promise 执行的结果,如果前面的失败了,则后面就没有继续执行下去的意义了,此时,我们想要实现,一旦有报错,则立即终止所有的 Promise 的执行;

[外链图片转存中…(img-6aLxHrUF-1599142789352)]

catch作用:如果上面任何一个.then失败了,立即终止执行都会进入catch捕获处理。

也可以单独为每一个指定失败的回调。都可以 。

jQuery中Promise

jQuery中的Ajax也提供了 Promise 操作:

$(function(){
    $("#btn").on("click",function(){
        $.ajax({
            url:"./data.json",
            type:"get",
            dataType:"json"
        })
        //利用.then代替success回调函数输出数据
        .then(function(data){
            console.log(data)
        })
    })
})

vue-preview

一个Vue集成PhotoSwipe图片预览插件,可以实现图片预览

官网:https://github.com/LS1231/vue-preview

[外链图片转存中…(img-ZtKvlpBh-1599142789353)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值