Vue study 入门前端万字笔记

Vue study 入门前端万字笔记

什么是vue js

  1. vue.js 是前端的主流框架之一,和Angular.js React.js ,前端的三大框架
  2. Vue.js是一套构建用户界面的框架,只关注视屏层,
  3. 主要负责 M(数据)V(视图)C(业务逻辑) 中的V这一层,主要工作就是和界面打交道
  4. 让开发人员只需要关注业务逻辑,不再化很多的精力关心DOM操作,提高开发效率
  5. 官网:https://cn.vuejs.org/v2/guide/transitions.html

框架和库的区别

  1. 框架,是一套完整的解决方案,对项目的倾入性较大,项目如果需要更换框架,则需要重新j架构整个项目
  2. 库(插件):提供某个小的功能,对项目的倾入性较少,如果某个项目无法完成某些需求,可以很容易切换

后端MVC和前端MVVM

  1. 后端MVC
  2. 前端MVVM

Vue 实例

  1. helloVUe

    <body>
        <div id="app">
            <p>{{massage}}</p>
        </div>
        <script src='../js/vue.js'></script>
        <script>
            var vm = new Vue({
                el:'#app',
                data:{
                    massage:"hello 小毅"
                }
            })
        </script>
    </body>
    
  2. M 层:数据操作层

    data:{
        massage:"hello 小毅"
    }
    
  3. V 层:视图展示{{massage}}

    <div id="app">
       <p>{{massage}}</p>
    </div
    
  4. VM:数据处理:

    var vm = new Vue({
       el:'#app',
       data:{
           massage:"hello 小毅",
           text:"我是小毅",
           html:'<h4>这是一个标题</h4>'
       }
    })
    
  5. 在差值表达式是,数据没事下载完之前出现{{massage}}的闪烁问题

  6. v-cloak,可以解决差值闪烁的问题,在数据没有加载完之前,p 加载之前:display:none,加载完之后display:block

    <p v-cloak>--{{massage}}--</p> 	//输出:--hello 小毅--
    
  7. v-text,可以将msssage,绑定在一个标签中展示,默认没有闪烁问题,会覆盖掉以前的内容

    <p v-text='text'>who are you</p> 	//输出:我是小毅
    
  8. v-html,可以将内容解析成HTML格式

    <p v-html='html'>这是一个html</p> 	//输出:这是一个标题
    
  9. 总结

闪烁问题是否替换掉以前的内容是否转义输出
差值表达式有(用 v-cloak解决)否,只是在占位的地方显示否,原文输出
v-text是,v-text会覆盖以前的内容否,原文输出
v-html是,v-html会覆盖以前的内容是,如果有标签

v-bind

  1. v-bind属性告诉浏览器,这个一个变量,

    <input type="button" v-bind:value="title"> 
    <input type="button" :value="'hello'+title">//简写模式,既然是变量,就可以进行变量的增加
    

v-on

  1. v-on 邦定事件,在data,同级的methods下声明函数

    <input type="button" v-bind:value="title" v-on:click='show'>
    <input type="button" v-bind:value="title" v-on:mouseover='show'>
    <input type="button" :value="'hello'+title" v-on:click = 'show()'>
    
    methods:{
        show:function(){
            alert("hello 小毅")
        }
    }
    
  2. 做一个实例,把字符串最前的一个字,放到字符串尾部,不停循环,

    //html
    <div id="app">
        <input type="button" value="runing" v-on:click="run">
        <input type="button" value="stop" v-on:click="stop">
        <!-- <input type="button" value="stop" > -->
        <h4>{{message}}</h4>
    </div>  
    
    <script>
            var vm = new Vue({
                el: "#app",
                data: {
                    message: "家强牛逼,家强牛!",
                    intervalId:null
                },
                methods: {
                    run() {
                        if(this.intervalId != null){return;}
    						//箭头函数,这样解决普通函数this指向问题
                        this.intervalId = setInterval(()=>{   
                            var start = this.message.substring(0, 1)//截取第一个字符
                            var end = this.message.substring(1)//截取第一个字符到最后的一个字符
                            this.message = end + start  //把最后的字符和第一字符相加
                        } ,300)
                    },
                    
                    stop(){
                        clearInterval(this.intervalId)//停止定时函数
                        this.intervalId=null
                    }
                }
            })
        </script>
    

v-model 双向数据绑定

  1. v-bing 只能实现数据的单向绑定

  2. v-model 可以实现数据的双向绑定,实现的用户的交互

    <div id="app">
        <p>{{message}}</p>
        <input type="text" v-model:value="message">
    </div>
    
  3. v-model 只能运用在表单元素中

    input(radio,text,address,emaill)
    select
    checkbox
    textarea
    
  4. 例子

    <div id="app">
        <input type="text" v-model='number1'> //数字1
        <select v-model="option">   //选择操作符
            <option value="+">+</option>
            <option value="-">-</option>
            <option value="*">*</option>
            <option value="/">/</option>
        </select>
        <input type="text" v-model="number2"> //数字1
        <input type="button" value="=" @click="conputer"> //计算
        <input type="text" v-model="result">  //显示结果
        <p>number1:{{number1}}</p>
        <p>number2:{{number2}}</p>
        <p>结果:{{result}}</p>
    </div>
    
    // javascript 
    <script>
            var vm = new Vue({
                el: "#app",
                data: {
                    number1: 0,
                    number2: 0,
                    result: 0,
                    option: '+',
                },
                methods: {
                    conputer() {
                        switch (this.option) {
                            case '+':
                                this.result = parseInt(this.number1) + parseInt(this.number2)
                                break;
                            case '-':
                                this.result = parseInt(this.number1) - parseInt(this.number2)
                                break;
                            case '*':
                                this.result = parseInt(this.number1) * parseInt(this.number2)
                                break;
                            case '/':
                                this.result = parseInt(this.number1) / parseInt(this.number2)
                                break;
                        }
                    }
                }
    
            })
        </script>
    
  5. 对以上计算函数进行改进,利用 eval()方法对字符串解析执行

    conputer() {
      var codestr = 'parseInt(this.number1) ' + this.option + 'parseInt(this.number2)'
       this.result = eval(codestr)
    }
    
  6. 在对以上例子进行改进,要求如下:

    1、在鼠标进入输入框,清空默认数字 0,
    2、当两个输入框改变或者操作符改变,自动输出结果
    

v-on的缩写和事件修饰符

  1. 事件修饰符

    1、.stop	阻止冒泡
    2、.prevent	阻止默认事件
    3、.capture	添加2020年7月9日14:56:13侦听器时使用事件捕获模式
    4、.selt 	只当事件在该元素(比如不是子元素)触发时触发回调
    5、.once		事件只触发一次
    
  2. 先定义几个函数,和简单的html代码

    methods:{
                div1Handler(){
                    console.log("触发了 inner div 的点击事件")
                },
                btnHandler(){
                    console.log("触发了 btn 按钮 的点击事件")
                },
                linkClick(){
                    console.log('触发了连接的点击事件')
                }
            }
    
  3. 事件的冒泡机制,点击button,会触发button 的事件,再冒泡触发父级元素的div 的事件

    <div id="app">
        <div class="inner" @click="div1Handler">
            <input type="button" value="按钮" @click="btnHandler">
        </div>
    </div>
    
  4. 使用.stop阻止冒泡,只触发 button 的事件,div的事件没有触发

    <div class="inner" @click="div1Handler">
        <input type="button" value="按钮" @click.stop="btnHandler">
    </div>
    
  5. 使用.self 实现只有点击当前元素(div)的时候,才会触发事件的处理函数(通过冒泡和捕获不会再触发事件),点击button 是不会触发的事件的 div 的事件的。

    <div class="inner" @click.self="div1Handler">
        <input type="button" value="按钮" @click.stop="btnHandler">
    </div>
    
  6. 使用.prevent阻止默认事件,只触发绑定的事件,阻止了跳转,from表单也可以使用这个方法

    <a href="http://www.baidu.com" @click.prevent='linkClick'>百度一下</a>
    
  7. 使用.capture捕获机制,点击按钮时,先触发 div的事件,在触发button 的事件,由外而内

    <div class="inner" @click.capture="div1Handler">
        <input type="button" value="按钮" @click.stop="btnHandler">
    </div>
    
  8. 使用.once,只触发一次事件

    <a href="http://www.baidu.com" @click.prevent.once='linkClick'>百度一下</a>
    

通过属性绑定设置样式class

  1. 定义几个样式

    <style>
        .color {
            color: brown;
        }
        .thin{
            font-weight: 200;
        }
        .italic{
            font-style: italic;
        }
        .active{
            letter-spacing: 0.5em;
        }
    </style>
    
  2. 数组,利用v-bind数据绑定,不需要在data{}里面声明class Name

    <h2 v-bind:class="['color','active','thin']">这是一个标题</h2>
    <h2 :class="['color','active','thin']">这是一个标题</h2>
    
  3. 数组中使用三元表达式

    <h2 :class="[1<2?'color':'']">这是一个标题</h2>
    
  4. 数组中嵌套对象

    <h2 :class="['color',{'active':true}]">这是一个标题</h2>
    <h2 :class="['color',{'active':flase}]">这是一个标题</h2>
    
  5. 直接使用对象

    <h2 v-bind:class="{color:false,thin:true,italic:'true',active:true}">这是一个标题</h2>
    <h2 v-bind:class="calssObj">这是一个标题</h2>
    
    data: {//在data声明一个对象
      calssObj:{color:false,thin:true,italic:'true',active:true}
    }
    

绑定style行内样式

  1. 直接在元素上通过 :style 的形式,书写样式对象

    <h2 v-bind:style="{'font-style':'italic','font-weight':200}">行内样式style</h2>
    <h2 :style="{'font-style':'italic','font-weight':200}">行内样式style</h2>
    
  2. 将样式对象,定义到data中,并直接引用:style中

    <h2 :style='H2Style'>行内样式style</h2>
    
    data: {
        H2Style: {
            color: 'pink',
            'font-style': 'italic',
        },
        H2Style2: {
            'font-weight': 200
        },
    }
    
  3. 在:style 中,引用多个data上的样式

    <h2 :style="[H2Style,H2Style2]">行内样式style</h2>
    

v-for

  1. 迭代数字

    <p v-for = "(i,index,b) in 10"> {{index}}这是第{{i}}次循环</p>
    
  2. 循环普通数组

    <p v-for="(item,index) in list">{{index}}号索引:{{item}}</p>
    
    data: {
    	list: [1, 2, 3, 4, 5]
    }
    
  3. 循环对象数组

    <p v-for="(user,index) in list">{{index}}---{{user.id}}----{{user.name}}</p>
    
    data: {
       list:[
           {id:1,name:'小毅'},
           {id:2,name:'小花'},
           {id:3,name:'小狗'},
           {id:4,name:'小猫'}
       ]
    }
    
  4. 循环对象

    <p v-for="(value,key) in user">{{key}}:{{value}}</p>
    
    data: {
       user:{
           id:1,
           name:"小毅",
           gender:'男',
           age:18
       }  
    }
    
  5. 循环嵌套对象

    
    data: {
       users:{
           小毅:{
               height:170,
               love:'running'
           },
           小猫:{
               height:20,
               love:'sleep'
           },
           小狗:{
               height:40,
               love:"抓老鼠"
           }
       }  
    }
    
  6. 案列,如果没有指定 :key ,那么选定的框只是选中第 N个,意思就是说,当添加的一个对象的还是,还是选中第N个,那么如果,在对象数组前面添加的时候,就会出现问题。

    <div id="app">
        <div>
            <label>Id<input type="text" v-model="id"></label>
            <label>Name<input type="text" v-model="name"></label>
            <input type="button" value="添加" @click='add'>
        </div>
    		//如果没有:key 在数组前面添加元素的是好会有bug
      		 <p v-for="item in list"  :key="item.id">
                {{item.id}}---{{item.name}}
                <input type="checkbox">
            </p>
        </p>
    </div>
    
    data: {
        id: '',
        name: '',
        list: [
            {id: 1, name: "小毅"},
            {id: 2, name: "小花"},
            {id: 3, name: "小猫"},
            {id: 4, name: "小狗"}
        ]
    },
    methods: {
        add() {
            // this.list.push({id:this.id,name:this.name})
            this.list.unshift({id:this.id,name:this.name})
        }
    }
    

v-if 和 v-show

  1. 如果为ture: v-show 和v-if 都是display:block

    <div id="app">
        <p v-show="true">这是v-show</p>
        <p v-if = "true">这是v-if</p>
    </div>
    
  2. 如果为false: v-show 状态是:display:none ,v-if 是直接删掉元素

    <div id="app">
        <p v-show="false">这是v-show</p>
        <p v-if = "false">这是v-if</p>
    </div>
    
  3. v-show 的特点:不会每次重新进行DOM的元素删除和创建,知识切换了元素的display:none样式,有较高的初始渲染消耗

  4. v-if的特点:每次直接删除和创建DOM元素,有较高的切换消耗

定义全局过滤器

  1. 定义一个全局过滤器

    Vue.filter('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}` 
        }
    })
    Vue.filter('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}` 
        }
    })
    
    

字符串填充:padStar()

  1. String.prototype.padStart(maxLength, fillString=’’)

  2. String.prototype.padEnd(maxLength, fillString=’’)

  3. 第一个参数是填充完之后的最大长度,第二个参数是用什么来填充

    <div id="app">
        <input type="button" value="填充" @click='test'>
        <p v-for="item in list">{{item}}</p>
        <p v-for="item in newList">{{item}}</p>
    </div>
    
    <script>
        var vm =  new Vue({
            el:"#app",
            data:{
                list:[
                    1,3,5,69
                ],
                newList:[]
            },
            methods:{
                test(){
                this.list.forEach(item=>{
                    this.newList.push(item.toString().padStart(2,'0'))
                })
                }                
            }
        })
    </script>
    

键盘事件和自定义按键修饰符

  1. 系统自带的按键修饰符

    .enter
    .tab
    .delete
    .esc
    .up
    .down
    .left
    .right
    
  2. 注册键盘事件

    <input type="button" value="添加" @keyup.enter= "add"></input>
    <input type="button" value="添加" @keyup.113= "add"></input>
    
  3. 自定义全局按键修饰符

    Vue.config.keyCodes.f2 =113 //配置f2按键修饰符
    //如果没有配置,那么就不会触发事件,因为没有系统没有这个按键修饰符
    <input type="button" value="添加" @keyup.f2= "add"></input>
    
  4. 键盘弹起事件,如果没有指定那个键或者键盘码,那么随便按哪个键盘,都会触发事件

    <input type="button" value="添加" @keyup= "add"></input>
    

自定义指令

  1. 使用 Vue.directive() 定义全局指令, v-focus

  2. 参数1:指令的名称,在定义的时候不用加上前缀 v- ,直接focus,但是在调用搞定时候,一定要加 v-

  3. 参数2:是一个对象,这个对象身上,有一些 指令相关的函数,这些函数可以在特定的阶段,执行相关的操作

  4. 自定义全局指令案例,可以在两个地放定义指令,一个是在一个新的script标签里(不是和new Vue 在同一个script),另一地方是,在创建Vue实例的new Vue 同一个script 标签里面,全局定义的

    <div id='app'>
        <input type="text" v-model="value" v-focus v-model="value">
    </div>
    <div id='app2'>
        <!-- <input type="text" v-model="value" v-focus v-model="value"> -->
    </div>
    //自定义全局指令,不是和创建Vue实例同一个script
    <script>
         Vue.directive('focus',{
            bind:function(el){ 
                console.log(el)
            },
            inserted:function(el){
                el.focus()
            },
            update:function(el){
                console.log("数据更新了")
            }      
        })
    </script>
    //自定义全局指令,和创建Vue实例同一个script
    <script>//自定义全局指令
         Vue.directive('focus',{
            bind:function(el){
                console.log(el)
            },
            inserted:function(el){
                el.focus()
            },
            update:function(){//当数据更新时触发
                console.log("数据更新了")
            }      
        }) 
    var vm = new Vue({
        el:'#app',
        data: {
            value:"哈哈"
        },
     })
     var vm = new Vue({
        el:'#app2',
        data: {
            value:"嘿嘿"
        }
     })
    </script>
    
  5. 自定义字体颜色指令

    <div id='app'>
        <input type="text"  v-model="message" v-color>
    </div>
    
    <script>
      Vue.directive('color',{
          bind:function(el){
            el.style.color='red'
          },
          inserted:function(el){
            el.style.color='red'
        }
      })  
    </script>
    
  6. 钩子函数,一个指令定义对象可以提供如下几个钩子函数 (均为可选):

    Vue.directive('focus',{
        bind:function(el){//只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置
            console.log(el)
        },
        inserted:function(el){//被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)
            el.focus()
        },
        update:function(){//所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有
            console.log("数据更新了")
        }      
    }) 
    
  7. 钩子函数的binding参数

    <div id='app'>
        <input type="text"  v-model="message" v-color ="'blue'">
    </div>
    
    <script>
      Vue.directive('color',{
          bind:function(el,binding){
            el.style.color = binding.value
            console.log(binding.name) // 指令的名字:color
            console.log(binding.value)    //指令的value:blue
            console.log(binding.expression)    //指令的表达式:'blue'
              
        }
      })  
    var vm = new Vue({
        el:'#app',
        data: {
            message:"哈哈"
        },
     })
    </script>
    
  8. 自定义私有指令

    //有效果
    <div id='app'><p v-fontweight="900">这是app1</p></div>
    //没有效果
    <div id='app2'><p v-fontweight="900" v-fontcolor = "'red'">这是app2</p></div>
    <script>
     var vm2 = new Vue({
        el:'#app2', //绑定 app2 的div
        directives:{//注意:这是多了一个 "s"
            'fontweight':{  //自定义字体粗细的私有指令
                bind:function(el,binding){
                    el.style.fontWeight = binding.value
                }
            },
            'fontcolor':{  //自定字体颜色的指令
                    bind:function(el,binding){
                        el.style.color = binding.value
                    }
                }
        }
     })
    </script>
    
  9. 函数简写,你可能想在 bindupdate 时触发相同行为,而不关心其它的钩子

    <div id='app'>
        <p v-fontsize='32'>hello 小毅!</p>
    </div>
    
    <script>
    var vm = new Vue({
        el:'#app',
        directives:{//注意:这是多了一个 "s"
            'fontsize':function(el,binding){ //这里相当于同时把函数现在 bind 和 updat的钩子函数中
                el.style.fontSize = parseInt(binding.value)+"px"
            }
        }
     })
    </script>
    

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

  1. 四个类型的函数

    //创建
    beforeCreate(){},
    create(){},
    //挂载
    beforeMount(){},
    mounted(){},
    //数据更新
    beforeUpdate(){},
    update(){},
    //销毁
    deforeDestroy(){},
    destroyed(){}
    
  2. 学习过属性

    <script>
    var vm = new Vue({
        el:'#app',
        data: {},
        methods: {},
        filters:{},
        directive:{},
        components:{},
    
        beforeCreate(){},
        create(){},
        beforeMount(){},
        mounted(){},
        beforeUpdate(){},
        update(){},
        deforeDestroy(){},
        destroyed(){}
     })
    </script>
    

vue-resource 发起get post jsonp 请求

  1. 案列

    <script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
    <script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script>
    <div id="app">
        请输入关键字:<input type="text" v-model="keyword" @keyup="sendJsonP(keyword)">
        <ul>
            <li v-for="r in result">{{r}}</li>
        </ul>
    </div>
    <script>
    window.onload = function () {
        new Vue({
          el: '#app',
          data: {
            keyword: '',
            result: ''
          },
          methods: {
            sendJsonP(keyword) {
              let url = 'https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web';
    
              this.$http.jsonp(url, {
                params: {
                  wd: keyword
                },
                jsonp: 'cb'//jsonp默认是callback,百度缩写成了cb,所以需要指定下                     }
              }).then(res => {
                if (res.data.g) {
                  this.result = res.data.g.map(x => x['q']);
                } else {
                  this.result = [];
                }
              });
            }
          }
        });
      }
    </script>
    

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

  1. 客户端 click.html

    <body>
        <script>
            function showInfo(data){
                console.log(data)
            }
        </script>
        <script scr="http://127.0.0.1:3000/getscript?callback=showInfo"></script>
    </body>
    
  2. 服务端 app.js cmd中,输入node app.js

    // 导入 http 内置模块
    const http = require('http')
    // 这个核心模块,能够帮我们解析 URL地址,从而拿到  pathname  query 
    const urlModule = require('url')
    
    // 创建一个 http 服务器
    const server = http.createServer()
    // 监听 http 服务器的 request 请求
    server.on('request', function (req, res) {
    
      // const url = req.url
      const { pathname: url, query } = urlModule.parse(req.url, true)
    
      if (url === '/getscript') {
        // 拼接一个合法的JS脚本,这里拼接的是一个方法的调用
        // var scriptStr = 'show()'
    
        var data = {
          name: 'xjj',
          age: 18,
          gender: '女孩子'
        }
    
        var scriptStr = `${query.callback}(${JSON.stringify(data)})`
        // res.end 发送给 客户端, 客户端去把 这个 字符串,当作JS代码去解析执行
        res.end(scriptStr)
      } else {
        res.end('404')
      }
    })
    
    // 指定端口号并启动服务器监听
    server.listen(3000, function () {
      console.log('server listen at http://127.0.0.1:3000')
    })
    

Vue 过度动画

  1. 实现动画的过渡类名class

    .v-enter,是开始动画之前,还没有开始
    
    . v-leave-to 是动画结束之后的状态,已经结束
    
    .v-enter-active,是动画入场的过程
    
    .v-leave-active 是动画离场的过程
    
  2. 案例:通过过渡类名实现动画,transition 标签的内容,会响应过渡类名class,transition元素,是vue官方提供的。

    <style>
        .v-enter, 
        .v-leave-to {
            opacity: 0;
            transform:translateX(300px)//设置动画入场开始之前和离场结束之后的位置
        }
        .v-enter-active,
        .v-leave-active {
            transition: all 0.4s ease;//设置入场和离场的过程中的动画效果
        }
    </style>
    
    <div id='app'>
        <input type="button" value="toggle" @click="flag= !flag">
        <transition>
            <h3 v-if="flag">这是一个H3</h4>
        </transition>
    </div>
    
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                flag:false
            }
        })
    
    </script>
    
  3. 可以定义不同的动画

    <style>
    //第二个动画,前缀是 v-
        .v-enter, 
        .v-leave-to {
            opacity: 0;
            transform:translateX(300px)/*
            设置动画入场开始之前和离场结束之后的位置*/
        }
        .v-enter-active,
        .v-leave-active {
            /*设置入场和离场的过程中的动画效果*/
            transition: all 0.4s ease;
        }
    
    //第二个动画,前缀我my-
        .my-enter,
        .my-leave-to{
             opacity: 0;
            transform:translateY(300px)
        }
    
        .my-enter-active,
        .my-leave-active{
            transition: all 0.8s ease;
        }
    </style>
    
  4. transition 标签 name属性,调用不同的动画

    <div id='app'>
        这是调用 v- 前缀的动画
        <input type="button" value="toggle" @click="flag= !flag">
        <transition><h3 v-if="flag">这是一个h3</h3></transition>
    	<hr>
     	//这是调用 my- 前缀的动画
    	<input type="button" value="toggle2" @click="flag2= !flag2"> 
    	<transition name='my'><h3 v-if="flag2">这是一个h6</h3></transition>
    </div>
    <script>
    var vm = new Vue({
        el:'#app',
        data: { 
            flag:false,
            flag2:false
        }
     })
    </script>
    

使用第三方库animate.css实现动画

  1. animate.css:https://animate.style/

  2. 实现动画

    <link rel="stylesheet" href="../js/animate.css">
        
    <div id='app'>
        <input type="button" value="toggle" @click="flag=!flag">
         <transition enter-active-class="bounceIn" leave-active-class="bounceOut">
            <h3 v-if="flag" class="animated">v-if h3</h3>
         </transition>
    </div>  
    

钩子函数

  1. 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"
    >
    </transition>
    
  2. 可以在methods中定义JavaScript函数

    methods: {
      // --------
      // 进入中
      // --------
    
      beforeEnter: function (el) {
        // ...
      },
      // 当与 CSS 结合使用时
      // 回调函数 done 是可选的
      enter: function (el, done) {
        // ...
        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) {
        // ...
      }
    }
    
  3. 当只用 JavaScript 过渡的时候,在 enter 和 leave 中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成。

JavaScript钩子函数,实现半场动画案例

  1. html部分

    <style>
    .ball{
        width:15px;
        height: 15px;
        background-color: chocolate;
        border-radius:50%
    }
    
    </style>
    <body>
    <div id='app'>
        <input type="button" value="加入购物车" @click="flag=!flag">
        <transition
         @before-enter="beforeEnter"
         @enter="enter"
         @after-enter="afterEnter">
            <div class="ball" v-show="flag"></div>
        </transition>
    </div>
    </body>
    
  2. javaScript 部分,构子函数

    <script>
    var vm = new Vue({
        el:'#app',
        data: {
            flag:false
        },
        methods: {
            beforeEnter(el){
                console.log("before")
                //beforeEnter  表示动画入场之前,此时,动画未开始,可以在beforeEnter中
                //设置元素开始动画之前的前始位置
                el.style.transform = "translate(0,0)"
            },
            enter(el,done){
                //enter 表示动画,开始之后的样式,可以设置小球完成动画之后的,结束状态
                el.offsetWidth//没有什么意义,el.offsetWidth,会强制刷新
                el.style.transform = "translate(250px,250px)"
                el.style.transition = "all 1s ease"
                done() //done是afterEnter函数的引用,要应用,不然有延迟
                console.log("enter")
            },
            afterEnter(el){
                //动画完成之后,会调用
                this.flag = !this.flag
            }
        }
     })
    </script>
    

transition-group元素实现列表动画

  1. 使用transition-group 包裹住要循环的li

    <transition-group>
        <li v-for='item in list' :key="item.id">
            {{item.id}} ---- {{item.name}}
        </li>
    </transition>>
    
  2. 案例,实现列表的页面的刷新入场,删除和添加的动画效果

    appear 属性,实现页面展现出来的时候,入场的效果

    tag 属性,指定循环的元素,默认是 span

    <style>
        /* 动画开始前和结束后元素的位置 */
        .v-enter,
        .v-leave-to{
            opacity:0;
            transform: translateY(100px);
        }
    
        /* 动画开始入场和离场的过程的动画效果*/
        .v-enter-active,
        .v-leave-active{
            transition:all 0.8s ease;
        }
    
        /* 使用后续的元素,在删除的时候,有动画的效果*/
        .v-move{
            transition: all 0.6s ease;
        }
        .v-leave-active{
            position: absolute;
        }
    </style>
    
    <div id='app'>
        <input type="text" v-model="id">
        <input type="text" v-model="name">
        <input type="button" @click="add" value="添加">
        <transition-group appear tag='ul'>
            <li v-for='(item,i) in list' :key="item.id" @click="del">
                {{item.id}} ---- {{item.name}}
            </li>
        </transition>>
    </div>
    
    
    data: {
        id:'',
        name:'',
        list: [ {id: 1,name: '小毅'},
                {id: 2,name: '小黄'},
                {id: 3, name: '小俞'},
                {id: 4, name: '小陈' },]},
    methods: {
        add(){
            this.list.push({id:this.id,name:this.name})
        },
        del(id){
            this.list.splice(id,1)
        }
    }
    

组件化

  1. 组件的创建,这些都是公有的组件,在不同的Vue实例都可以使用

    <div id='app'>
        <mycoml></mycoml>
        <mycoml2></mycoml2>
        <mycoml3></mycoml3>
        <mycoml4></mycoml4>
    </div>
    
    //引用的外部代码,不可子div#app 里面写,不然写的代码直接响应在html页面上
    <template id="teml"> 
        <div>
            <h2>这是使用template 元素,在外部定义的组件结构</h2>
            <h4>这个方法有代码提示和高亮</h4>
        </div>
    </template>
    
    <script>
        const coml = Vue.extend({ //第一种
            template: "<h3>这是使用Vue.extend 创建的组件</h3>"
        })
        Vue.component('mycoml', coml)
    
        Vue.component('mycoml2',Vue.extend({//第二种
            template: "<h3>这是使用Vue.extend 不用中间变量接受创建的组件</h3>"
        }))
    
        Vue.component("mycoml3",{//第三种,可以直接放一个对象,或者对像的名字
            template: "<h3>这是使用Vue.component直接创建的组件</h3>"
        })
    
    //引用的外部代码,不可子div#app 里面写,不然写的代码直接响应在html页面上
        Vue.component('mycoml4',{//第四种
            template:'#teml'
        })
    </script>
    
  2. 组件的模板只能有一个根元素,不能有两个平级的元素

    <template id="teml"> 
        <div> //div 包裹着两个标题
            <h2>这是使用template 元素,在外部定义的组件结构</h2>
            <h4>这个方法有代码提示和高亮</h4>
        </div>
    </template>
    

##使用components定义私有组件

  1. 使用components定义私有组件,只能在定义自身的Vue实例中调用

    <template id="teml">
        <div>
            <h3>这是一个私有组件</h3>
            <h5>通过引用外部的template</h5>
        </div>
    </template>
    //定义一个私有组件
    var vm = new Vue({
        el:'#app',
        components:{
            login:{
                template:"#teml"
            }
        },
    </script>
    

组件中的data 和 methods

  1. 在组件,data是一个function,return 回来的是一个对象

    <div id='app'> <mycoml></mycoml></div>
        
    Vue.component('mycoml',{
        template:'<h1>这是组件中的data---id:{{id}}--name:{{name}}</h1>',
        data:function(){ //一个function return 一个对象
            return{
                id:1,
                name:"小毅"
            }
        }
    })
    
  2. 利用组件的data 和methods 做一个计数器,组件中methods中定义一个increment函数

    <div id='app'>
        <counter></counter>
        <hr>
        <counter></counter>
        <hr>
        <counter></counter>
    </div>
    <template id="templ"> 
        <div>
            <input type="button" value="加 1 " @click="increment"><br>
            {{count}}
        </div>
    </template>
    
    <script>
        var dataObj = {count:0}//在外面顶定义一个对象
        Vue.component('counter',{
            template:'#templ',
            data:function(){
                //return dataObj ,如果返回的是在外面定义的对象,因为它的引用是同一个地址,所有的count会同时加 1
                return{count:0}//返回这里的count,每一个组件的实例,调用的都是自己的count,他们是不同的地址,所以,不会同时加 1 
            },
            methods:{increment(){this.count++}}
        })
    var vm = new Vue({el:'#app', })
    </script>
    
    

组件切换

  1. 利用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>"
        })
        var vm = new Vue({ el: '#app',data:{flag:false} })
    </script>
    
  2. 利用Vue提供的标签 component占位, :is =“组件名” ,实现组件的切换

    <style>
        .v-enter,
        .v-leave-to{
            opacity: 0;
            transform: translateY(250px);
        }
    
        .v-enter-active,
        .v-leave-active{
            transition: all 0.5s ease;
        }
    </style>
    
    <div id='app'>
        <a href="#" @click.prevent="comName='login'">登录</a>
        <a href="#" @click.prevent="comName='register'">注册</a>
        <transition mode="out-in">  // mode 模式,先out再in
            <component :is='comName'></component>
        </transition>
    </div>
    
    <script>
        Vue.component('login', {
            template: "<h3>登录组件</h3>"
        })
    
        Vue.component('register', {
            template: "<h3>注册组件</h3>"
        })
        var vm = new Vue({ el: '#app',data:{comName:'login'} })
    </script>
    

子组件的使用父组件的data和本身的data

  1. 在组件中,默认无法访问到父组件中data 上的数据和methods 中的方法

  2. 可以使用,利用属性绑定机制:v-bind: 自定义一个属性,绑定父组件中data的,再在子组件的props:[]的数组中那个定义,这样就可以在子组件中使用父组件data中的数据了

  3. 子组件的所有props 中的数据都是通过父组件传递给子组件的

  4. 子组件的data,是一个function ,返回的是一个对象。

  5. 子组件的data,是子组件私有的,比如:子组件通过Ajax,请求回来的数据,都可以放到data身上

  6. 子组件的props中的数据,都是只可读的,不能写

  7. 父组件中的data 都是可读可写的

    <div id='app'> 
        //v-bind: 一个自定义的属性,再把父组件的的 msg 赋值给这个自定义组件 
        <coml v-bind:parent="msg"></coml>
    </div>
    
    var vm = new Vue({
        el:'#app',
        data: {
            msg:"hello,我是爸爸"
        },
        components:{
            coml:{
                template:"<h1>这是子组件 --   {{ parent }}</h1>",
                props:['parent'] //要把自定义的组件放在props:[] 才可以在子组件中使用
            },
        }
     })
    

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

  1. 父组件向子组件传递方法,使用的是事件的绑定机制,v-on,自定义一个事件属性之后,把父组件的方法挂在这个事件属性上,子组件就能过通过某些方式来调用

  2. 下面是子组件通过用自身的事件myclick,利用emit()方法 触发自定义的事件属性,并传入子组件的sonMsg作为参数,这样,就通过自定义的事件属性调用了父组件的方法,并且把子组件的sonMsg传给了父组件的function。

    <div id='app'>
        <com @func="show"></com>
        {{dataFormSon}}
    </div>
    
    <template id="template">
        <div>
            <h2>这是子组件</h2>
            <input type="button" value="触发父组件传递的function" @click='myclick'>
        </div>
    </template>
    
    <script>
        var com = {
            template: '#template',
            data() {
                return{
                    sonMsg:{name:'小毅',age:20}
                }
            },
            methods: {
              myclick(){
                  this.$emit('func',this.sonMsg)
              }
            }
        }
    
        var vm = new Vue({
            el: '#app',
            data: {      
               dataFormSon:null
            },
            methods: {
                show(data){
                    this.dataFormSon = data;
                }
            },
            components: {
                com
            }
        })
    </script>
    

组件的案例

  1. 可以发表评论,可以展示评论列表



## ref获取DOM元素和组件引用

1. javaScript 获取元素

```javascript
<div id='app'>
    <input type="button" value="获取元素" @click="getElement">
    <h3 id="h3">hello,小毅</h3>
</div>
// 通过id 获取h3 的元素
document.getElementById('h3')
  1. 在创建的Vue实例vm 中,有一个ref属性,默认是空的,如果个标签 ref 属性,就可以通过ref获取元素

    vm.$refs 返回一个对象,面里有使用了ref 属性的元素和组件

    我们可以通过 ’ . ’ 的方式,获取 refs对象中元素和组件的data 和方法

    <div id='app'>
        <input type="button" value="获取元素" @click="getElement">
        <h3 id="h3" ref="h3">hello,小毅</h3>
        <h4 id="h4" ref="h4">hello</h4>
        <login ref="login"><login>
    </div>
    
    <script>
        var login = {
            data(){
                return{
                    msg:"子组件的 msg "
                }
            },
            methods:{
                show(){
                    alert("调用了子组件的方法show()")
                }
            },
            template:"<h1>这是一个组件</h1>"
        }
    var vm = new Vue({
        el:'#app', 
        methods: {
            getElement(){
    			//通过ref 获取元素
                console.log(this.$refs)//3个对象{h3,h4,login}
                console.log(this.$refs.h3.innerText)// 通过ref获取h3中的内容
    
                //通过 ref 获取子组件的data 和 方法
                console.log(this.$refs.login.msg)
                this.$refs.login.show()
            }
        } ,
        components:{
            login
        }  
     })
    </script>
    

vue-router安装和基本使用

  1. vue-router 依赖vue,所以要先导入vue.js 再导入vue-router.js

  2. 创建一个vue-router 对象,对象里有一个属性是 routes(注意没有‘R’),是一个数组,用来定义router的规则,这个routes 数组中可以放多个对象,每个对象就一个路由规则

  3. 每一个路由规测有两个必须的参数,path:路由链接地址,component:对应的组件

  4. vue-router 提供一个标签‘router-view’,当作占位符,由路由规测匹配到的组件,就会再这里展示

    <div id='app'>
        <!-- 展示匹配路由URL成功的组件 -->
        <router-view></router-view>  
    </div>
    <script src='../js/vue.js'></script>
    <script src='../js/vue-router-3.0.1.js'></script>
    <script>
        //创建两个组件对象
        var login = {
            template:"<h3>登录组件</h3>"
        } 
        var register = {
            template:"<h3>注册组件</h3>"
        }
    
        var routerObj = new VueRouter({
            routes:[//路由规测数组
                {path:'/login',component:login}, //一个路由规测对象
                {path:'/register',component:register},
            ]
        })
    var vm = new Vue({
        el:'#app',
        router:routerObj //把路由对像挂到Vue的router,属性中
     })
    </script>
    

router-link 和重定向

  1. router-link

  2. 重定向

  3. tag标签

    <style> 
        /* .router-link-active, */
        .active{
            color:bisque;
        }
    </style>
    <body>
        <div id='app'>
            <router-link to="/login" tag="span">登录</router-link>
            <router-link to="/register">注册</router-link>
            <router-view></router-view>
        </div>
        <script src='../js/vue.js'></script>
        <script src='../js/vue-router-3.0.1.js'></script>
        <script>
            var login = {template: '<h3>登录组件</h3>' }
            var register = {template: '<h3>注册组件</h3>'}
    
            var routerObj = new VueRouter({
                routes: [
                    {path: '/', redirect: '/login'},
                    { path: '/login',component: login },
                    {  path: '/register', component: register}
                ],
                //linkActiveClass 默认为:router-link-active
                linkActiveClass:'active'
            })
            var vm = new Vue({ el: '#app',router:routerObj})
        </script>
    

router 动画

  1. 动画

    <style> 
        /* .router-link-active, */
        .active{
            color:bisque;
        }
    
        .v-enter,
        .v-leave-to{
            opicity:0;
            transform: translateX(250px);
        }
    
        .v-enter-active,
        .v-leave-active{
            transition:all 0.8s ease;    
        }
    </style>
    <body>
    <div id='app'>
        <router-link to="/login" tag="span">登录</router-link>
        <router-link to="/register">注册</router-link>
        <transition mode="out-in">
            <router-view></router-view>
        </transition>
    </div>
    

路由的两种获取参数的方法

  1. query

  2. params

    <div id='app'>
        <router-link to="/login?id=10&name='小毅'">登录</router-link>
        <router-link to="/register/11/'小花'">注册</router-link>
        <router-view></router-view>
    </div>
    
    <script>
    //方法一
    var login = {
        template:'<h2>登录 使用query获取参数:--id:{{$route.query.id}}--用户:{{$route.query.name}} </h2>',
    
    }
    //方法二
    var register = {
        template:'<h2>注册 使用params 获取参数:--id:{{this.$route.params.id}}--用户:{{this.$route.params.name}}</h2>',
    }
    
    var routerObj = new VueRouter({
        routes:[
            {path:'/',redirect:'login'},
            {path:'/login',component:login},
            {path:'/register/:id/:name',component:register}
            ]
    })
    var vm = new Vue({el:'#app', router:routerObj})
    </script>
    

使用children 属性实现路由的嵌套

  1. 在路由对象中,使用children属性实现路由的嵌套

    <style>
        .tem{ height: 500px; width:800px; background-color: bisque;
        }
        h3{ height:400px; background-color: blue;}
    </style>
    
    <div id='app'>
        <router-view></router-view>
    </div>
    
    <template id="template">
        <div class= 'tem'>
            <h2>这个root 组件</h2>
            <router-link to='/root/children1'>登录(children1)</router-link>
            <router-link to='/root/children2'>注册(children2)</router-link>
            <router-view></router-view>
        </div>
    </template>
    
    <script>
        var root = {template:"#template"}
        var children1 = {template:'<h3>登录</h3>'}
        var children2 = {template:'<h3>注册</h3>'}
        var routerObj = new VueRouter({
            routes:[
                {path:'/',redirect:'root'},
                {path:'/root',
                 component:root,
                  children:[
                        {path:'children1',component:children1},
                        {path:'children2',component:children2}
                    ]
                },]
            })
        var vm = new Vue({el:'#app',router:routerObj })
    </script>
    

路由命名视图实现经典布局

  1. 给 router-view 添加一个那么 属性

    <style>
        html,body,h1{margin:0;padding:0;}
        .header{background-color: magenta;}
        .container{display: flex;height:600px;}
        .left{ background-color: lightcoral; flex:2;}
        .main{ background-color:lightseagreen;flex:8;}
    </style>
    <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">Left</h1>'}
        var mainBox = {template:'<h1 class="main">main</h1>'}
        var routerObj = new VueRouter({
            routes:[
                {path:'/',components:{
                    'default':header,
                    'left':leftBox,
                    'main':mainBox
                }}
            ]
        })    
    	var vm = new Vue({el:'#app',router:routerObj})
    </script>
    

webpack的基本使用方法

  1. 新建项目的文件夹

    webpack  //项目名
        dist  //文件夹
        src   //文件夹
            images        // src 下的文件夹
            css		      // src 下的文件夹
            js		      // src 下的文件夹
            index.html  // src 下的html文件
            main.js     // src 下的js 文件
    
  2. 初始化项目

    npm init -y
    
  3. 安装

    //全局安装
    npm i webpack -g
    //安装到项目依赖中
    npm i webpack --save-dev
    
  4. 在main .js 文件中,导入其他文件(js.css),比如jquery.js 文件

    // 这是main.js 文件
    import $ from 'Jquery'
    
    //利用jquery 使列表隔行变色
    $(function(){
        $("li:odd").css('backgroundColor','lightblue')
        $("li:even").css('backgroundColor','green')
        // $('li').css('backgroundColor','red')
    
    })
    
  5. 运行webpack,运行下面的代码,在dist下有一个bundle.js 文件

    webpack .\src\main.js -o .\dist\bundle.js
    
  6. 在index.html中,写一个ul>li*10,在导入dist下的bundle.js 文件,在浏览器打开index.html 即可

    // 这是index.html
    
    <script src="../dist/bundle.js"></script>
      
    <ul>
        <li>这是第1个li</li>
        <li>这是第2个li</li>
        <li>这是第3个li</li>
        <li>这是第4个li</li>
        <li>这是第5个li</li>
        <li>这是第6个li</li>
        <li>这是第7个li</li>
        <li>这是第8个li</li>
        <li>这是第9个li</li>
        <li>这是第10个li</li>
    </ul>
    

webpack 配置文件

  1. 如果每一次修改js ,css 文件都需要用命令形式(webpack .\src\main.js -o .\dist\bundle.js)指定入口和出口文件太麻烦

  2. 我们可以在项目的跟目录,创建一个配置文件:webpack.config.js,在控制台运行:webpack 即可得到bundle.js,文件

    const path = require('path')
    module.exports = {
        //入口,表示要使用webpack 打包那个文件
        entry:path.join(__dirname,'./src/main.js'),
        //输出文件的配置,输出文件的目录,和文件名
        output:{
            path:path.join(__dirname,'./dist'),
            filename:'bundle.js'
        }
    }
    
  3. webpack 工作过程

    // 当在控制台运行: webpack
    1、webpack发现没有通过命令行的形式指定入口和出口
    2、找到配置文件,webpack.config.js 
    3、解析执行配置文件,导出配置对象
    4、当webpack拿到配置对象后,根据入口和出口进行打包构建
    

webpack-dev-server的基本使用

  1. 每一次修改代码,要重新看效果,都需要运行webpack,很麻烦,所以我们使用webpack-dev-server

  2. webpack-dev-server这个工具,可以实现自动打包编译的动能(和nodemon类似),不仅可以打包编辑项目,还可以使项目通过localhost本地的方式进行访问我们的项目,这一点和apache类似

  3. 安装,这个工具只能安装在项目中,不能进行全局的安装

    cnpm i webpack-dev-server -D
    
  4. webpack-dev-server 这个工具,如果想要正常运行,一定要在本地的项目中安装webpack,即使我们已经在全局中安装过了webpack

    cnpm i webpack -D
    
  5. 在package.json 文件中配置webpack-dev-server ,注意在json 文件中不能写注释,字符串要用双引号

     "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "dev": "webpack-dev-server"
      },
    
  6. 安装脚手架

    cnpm i webpack-cli -D 
    
  7. 运行

    npm run dev
    
  8. 默认访问loclhsot:8080即可访问我们的项目

  9. 生成的bundle.js在 根目录下,在内存中,所以在html 文件中引入这个js文件的路径一定要修改

    <script src="/bundle.js"></script>
    

webpack-dev-server 的常用命令

  1. 第一种方法,也是推荐的一种,在package,中配置webpacke-dev-server

    // --open	=>	运行完命令后打开浏览器
    // --oprt 3000	=>	设置端口
    // --contentBase	=>	访问的文件路径	默认是 根目录 /
    // --hot	=> 	不重新生成bundle.js 文件,只是在这个基础上加载修改的部分,而且可以同步到浏览器,不用					手动刷新
    
    
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "dev": "webpack-dev-server --open --port 3000 --contentBase  src --hot"
      }
    
  2. 第二种方法:在webpack.config.js 文件中配置我webpack-dev-server

    // 第一步  在package.json 文件下的script 中添加 dev2
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "dev": "webpack-dev-server --open --port 3001 --contentBase  src --hot",
        "dev2": "webpack-dev-server"
      },
          
    //第二步  在webpack.config.js 文件下配置webpack-dev-server    
    const path = require('path')
    //启动热更新的 第二步
    const webpack = require('webpack')
    module.exports = {
    //入口,表示要使用webpack 打包那个文件
    entry:path.join(__dirname,'./src/main.js'),
    //输出文件的配置,输出文件的目录,和文件名
    output:{
        path:path.join(__dirname,'./dist'),
        filename:'bundle.js'
    },
    devServer:{
        open:true,
        port:3000,
        contentBase:'src',
        hot:true   //启动热更新的  第一步
    },
    plugins:[
        new webpack.HotModuleReplacementPlugin()  启动热更新的  第三步
    ]
    }
    

html-webpack-plugin

  1. 在内存中生成html

  2. 安装

    cnpm i html-webpack-plugin -D
    
  3. 配置,在webpack.config.js 文件中配置

    //导入插件
    const htmlWebpaPlugin = require('html-webpack-plugin')
    
    // 在plugins 中添加插件配置
    plugins:[
        new webpack.HotModuleReplacementPlugin(),  启动热更新的  第三步
        new htmlWebpaPlugin({
            template:path.join(__dirname,'./src/index.html'), //把哪个文件生成到内存中
            filename:'index.html' // 生成到内存中的文件的文件名
        })
    ]
    
  4. 当使用了html-webpack-plugin 之后,就不需要手动处理bundle.js 的引用路径了,因为这个插件,会自动帮我们创建一个合适的 script 并且引用了正确的路径

css-loader处理css文件

  1. webpack默认只能处理JS类型的文件,如果需要处理非JS类型的文件,我们需要手动安装一些合适的第三方加载器

  2. 安装style-loader 和 css-loader

    cnpm i style-loader css-loader -D
    
  3. 在webpack.config.js 配置文件,新增一个配置节点module,他是一个对象,在这个module对象中,有个rules 属性,这个rules 属性是一个数组,这个数组中,存放了所有第三方文件的匹配和处理规则

    //这是webpack.config.js 配置文件
    module:{// 这个节点,用于配置 所有的第三方模块  加载器
        rules:[//所有第三方模块的 匹配规则  
            {test:/\.css$/,use:['style-loader','css-loader'],
        ]
    }
    
    // css目录下,新建一个index.css 文件,并写入样式
    li{
    	list-style: none;
    }
         
    // 在main.js 中导入css样式文件
    import './css/index.css'       
    
  4. 第三方loader的调用过程

    1、wenbpack发现,我们并没有通过命令的形式,给他指定入口和出口
    2、webpack就去根目录中,查找一个叫做"webpack.config.js"的配置wenjian
    3、webpack 解析配置文件,当解析完配置文件之后,就得到了配置文件中导出的配置对象
    4、webpack 拿到配置对象后,就拿到了配置对象中,指定的入口和出口,然后 进行打包和构建
    

配置处理less文件的loader

  1. 安装

    cnpm i less-loader -D
    cnpm i less -D   // less 是less-loader 的内部依赖文件
    
  2. 配置使用

    //配置
    module:{// 这个节点,用于配置 所有的第三方模块  加载器
        rules:[//所有第三方模块的 匹配规则  
            {test:/\.css$/,use:['style-loader','css-loader']},
            {test:/\.less$/,use:['style-loader','css-loader','less-loader']}
        ]
    // 在css 目录先创建一个index.less文件并写入内容
    ul{
        margin:0;
        padding: 0;
    }
        
    // 在main.js 中导入.less 文件
    import './css/index.less'
    
    

配置处理scss文件的loader

  1. 安装

    cnpm i sass-loader -D
    cnpm i node-sass -D //node-sass 是sass-loader 的内部依赖
    
  2. 配置使用

    //配置
    module:{// 这个节点,用于配置 所有的第三方模块  加载器
        rules:[//所有第三方模块的 匹配规则  
            {test:/\.css$/,use:['style-loader','css-loader']},
            {test:/\.less$/,use:['style-loader','css-loader','less-loader']},
    	    {test:/\.scss$/,use:['style-loader','css-loader','sass-loader']}
        ]
    // 在css 目录先创建一个index.scss文件并写入内容
    html,body{
        margin:0;
        padding:0;
    }
    
    li{
        font-size: 12px;
        line-height: 30px;
    }
        
    // 在main.js 中导入.less 文件
    import './css/index.scss'
    

webpack 项目初始化

  1. 简单的描述一下webpack 的配置

    npm init -y
    webpack ./src/main.js ./dist/bundle.js   //全局安装了wepback,但是这个办法太麻烦
    cnpm i webpack-dev-server -D   //安装一个工具,可以实时打包
    cnpm i webpack -D  //本地安装一个webpacn
    新建一个webpack.config.js 配置文件配置入口,和出口
    在pakage.json的script节点下配置dev
    	第一种方法:"dev":"webpack-dev-server --open --port 3000 --contentBase src --hot"
    cnpm i html-webpack-plugin -D  //可以在内存中生成html 的工具
    配置 html-webpack-plugin 
    	plugins:[
            template:path.jion(__dirname,'./src/index.html'),
            filename:'index.html'
        ]
        
    // 处理样式的 loader
    cnpm i style-loader css-loader -D //处理.css文件
    cnpm i less-loader less -D //处理.less文件
    cnpm i sass-loader node-sass -D //处理.less文件
    
    配置所有第三方某块
    module:{
        rules:[
            {test:/\.css$/,use:['style-loader','css-loader'},
       		{test:/\.less$/,use:['style-loader','css-loader','less-loader'},
            {test:/\.scss$/,use:['style-loader','css-loader','sass-loader'}
        ]
    }
    //在main.js 中引入样式文件
    import './css/index.css'
    import './css/index.less'
    import './css/index.scss'
    

webpack中url-loader 的使用 处理图片和字体图标

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

  2. 安装配置url-loader

    //安装
    cnpm i url-loader file-loader -D
    //配置
    module:{// 这个节点,用于配置 所有的第三方模块  加载器
            rules:[//所有第三方模块的 匹配规则  
                {test:/\.css$/,use:['style-loader','css-loader']},
                {test:/\.(jpg|png|gif|bmp|jpeg)$/,use:'url-loader?limit=30&name=[name].[ext]'},//处理图片 URL
                {test:/\.(ttf|eot|svg|woff|woff2)$/,use:'url-loader'}// 处理图标
            ]
                
        }
    

webpack中bable 的配置

  1. webpack中,默认只能处理一部分的ES6的新语法,一些更高级的ES6语法或ES7语法webpack就无能为力。

  2. 可以通过第三方loader 把更高级的语法转为低级的语之后,把结果交给webpack去打包到bundle.js中

  3. 通过第三方loader,Babel ,可以帮我们把高级的语法转换为低级的语法。

  4. 可能会版本不对应

    babel-loader 8.x对应babel-core 7.x
    babel-loader 7.x对应babel-core 6.x
    
  5. 安装

    cnpm i babel-core babel-loader babel-plugin-transform-runtime -D
    
    cnpm i babel-preset-env babel-preset-stage-0 -D
    
    cnpm i --save-dev babel-loader@7.1.5 //如果版本不对应,可以降低babel-loader的版本
    
  6. 配置

    //在webpack.config.js
    module:{
        rules:[
            {test:/\.js$/,use:'babel-loader',exclude:/node_modules/}
        ]
    }
    
    //在跟目录新建一个.babelrc 的文件,并写入
    {
        "presets":["env","stage-0"],
        "plugins":["transform-runtime"]
    }    
    
  7. babel-preset-env,是比较新的ES6语法,他包含了所有和ES*相关的语法

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

  1. 使用conponents

    <div id='app'>
        <login></login>
    </div> 
    
    <script>
        var login = {
            template:'<h1>这是登录组件</h1>'
        }
    var vm = new Vue({
        el:'#app',
        components:{
            login
        }
     })
    </script>
    
  2. 使用render

    <div id='app'>
    
    </div>
    <script>
        var login = {
            template:'<h1>这是登录组件</h1>'
        }
    	var vm = new Vue({
        el:'#app',
        render:function(createElements){//createElements 是一个方法,调用它,可以把指定的组件模板渲染为html结构
            return createElements(login)
        }
     })
    </script>
    
  3. 这两者的区别

    // 1、render会替换页面中el 指定的那个容器,容器的全部东西都会消失,只有组件的内容
    // 2、components就像差值表达式一样,只是插入这个组件
    

如何在webpack构建的项目中使用vue开发

  1. 在网页中

    1、使用script标签,引用vue的包
    2、在index页面中,创建一个 id 为 app 的div 容器
    3、通过 new Vue 得到一个vm 的实例
    
  2. 在webpack的项目中

  3. 按装Vue

     cnpm i vue -S
    
  4. 在webpack中,在main.js 使用import Vue from ‘vue’ 导入的Vue 构造函数,功能不完整,只能提供

    import Vue from 'vue'
    
  5. 包的查找过程

    1、在项目根目录中有没有node_modules的文件夹
    2、在node_modules中,找对应的vue文件夹
    3、在vue 文件夹的package.json 的配置文件中,有一个main 属性
    4、main属性指定了这个包在被加载时候的入口文件,默认: "main": "dist/vue.runtime.common.js",
    
  6. 在main.js 中导入VUE,创建一个实例

    //导入vue 的第一种方法
    import Vue from 'vue'//这是阉割版的vue.js(vue.runtime.common.js)
    
    //导入vue 的第二种方法
    import Vue from '../node_modules/vue/dist/vue.js'// 这是完全版的vue.js
    
    //导入vue 的第三种方法  是对第二种方法的一个改进
    import Vue from 'vue' // 先在main.js 导入vue
    //再在webpack.config.js 中和entry,output,module,plugins,平级再建一个配置节点,resolve
    resolve:{
        alias:{// 修改Vue被导入时候包的路径
            "vue$":"/node_modules/vue/dist/vue.js"
        }
    }
    -------------------------------------------------------------------------------------
    //在main.js中创建Vue实例
    var vm = new Vue({
        el:'#app',
        data:{
            a:"在webpack 中使用vue"
        }
    })
    -------------------------------------------------------------------------------------
    
    // 在index.html 中创建一个 id=app 的div容器
    
    <div id="app">
        <p> hello{{a}}</p> 
    </div>
    

在webpach 中使用vue 结合render渲染组件到指定的容器中

  1. 默认webpack 无法打包 .vue 文件,需要相关的loader

  2. 安装配置

    //安装
    cnpm i vue-loader vue-template-compiler -D
    //配置,在webpack.config.js的
    
    {test:/\.vue$/,use:"vue-loader"}
    
    
    const VueLoaderPlugin = require('vue-loader/lib/plugin');
    plugins:[
        new VueLoaderPlugin()// 把VueLoaderPlugin放到plugins中
    ],
    
  3. 定义一个login.vue 文件

    <template>
        <div>
            <h1 @click="show">这是登录组件,是使用.vue 文件定义的 {{msg}}</h1>
        </div>
    </template>
    
    <script>
    export default{
        data(){
            return {
                msg:"家强牛逼"
            }
        },
        methods:{
            show(){
                console.log('调用了 login.vue 中的show 方法'),
            }
        }
    }
    </script>
    
    
    <style>
    
    </style>
    
  4. 在main.js中,导入vue并创建一个实例,用render 的方法,渲染 login.vue组件

    //导入vue ,这是在only runtime 的模式下的vue
    import Vue from 'vue'
    import login from './login.vue'
    var vm = new Vue({
        el:'#app',
        // render:function(createElements){  
        //     return createElements(login)
        // }
        render:c=>c(login)// 这是render渲染用箭头函数的简写
    })
    
  5. 在html中创建一个容器,render 方法渲染的组件,会把这个容器里面的内容全部替换

        <div id="app">
            <p> hello{{a}}</p> 
        </div>
    

export default 和export 导入和导出

  1. 在node.js中,向外暴露成员的形式和导入。

    module.exports = {}
    exports {}
    var test =require('test')
    
  2. 在ES6 中,用export default 和export 向外暴露成员

//这个test.js 文件
export default { // export default 一个文件只能暴露一个对象
    name:"小毅",
    age:20
}

export var title ="家强牛逼"
export var content ="小毅牛逼"
  1. 接收,export default 和 export 暴露的对象

    //这是main.js 文件
    import test,{title,content} from './test'
    console.log(test)
    console.log(title+"----"+content)
    

webpack 使用vue-router

  1. 中文官方文档:https://router.vuejs.org/zh/

  2. 下载,安装,使用

    cnmp i vue-router -S//下载
    
    import Vue from 'vue'
    
    import VueRouter from 'vue-router'// 导入vue-router 包
    
    Vue.use(VueRouter)  // 手动安装 VueRouter
    
  3. 新建3 个.vue 文件的组件

    //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>
        </script>
        <style>
        </style>
    
    //account.vue   ----------------------------------------
    <template>
      <div>
        <h1>这是 Account 组件</h1>
      </div>
    </template>
    <script>
    </script>
    <style>
    </style>
    
    //goodslist.vue  ------------------------------------------
    <template>
      <div>
        <h1>这是 GoodsList 组件</h1>
      </div>
    </template>
    <script>
    </script>
    <style>
    </style>
    
  4. 导入.vue文件的组件

    // 导入组件
    import app from './App.vue'
    import account from './main/account.vue'
    import goodslist from './main/goodslist.vue'
    
  5. 使用vue-router

    //创建路由对象
    var router = new VueRouter({
        routes:[
            {path:'/account',component:account},
            {path:'/goodslist',component:goodslist},   
        ]
        })
    //将路由挂载到 Vue 实例中
    var vm = new Vue({
        el:'#app',
        render:c=>c(app),
        router
    })
    
  6. 注意:

    // 因为.vue 文件的组件的中,有style的标签,所以要处理样式的loader
    {test:/\.css$/,use:['style-loader','css-loader']},    
    

vue-router实现路由的嵌套

  1. 再建两个.vue 文件的子组件,并嵌套在account 路由下

  2. 在mian.js 中导入新建的两个子组件

    // 导入 Account的两个子组件
    import login from './suboom/login.vue'
    import register from './suboom/register.vue'
    
  3. 在account 路由对象中,添加children 属性,设置子路由,实现路由的嵌套

    var router = new VueRouter({
        routes:[
            {path:'/account',
            component:account,
            children:[
                {path:'login',component:login},
                {path:'register',component:register},
            ]    
        },
            {path:'/goodslist',component:goodslist},   
        ]
        })
    

组件中scoped属性和lang属性

  1. 样式的scoped 属性是通过css 的属性选择器实现的,因为一旦加了scoped属性,那么就回给这个组件的最外层的容器,添加一个data- 开头的属性,在渲染的时候,就只会选择这个属性。不会全局渲染。

    //全局的字体都变成了红色
    <style>
        div{
            color:red;
        }    
    </style>
    
    //只有当前组件的字体都变成了红色
    <style scoped>
        div{
            color:red;
        }    
    </style>
    
  2. 普通的style 标签只支持普通的css样式,如果想要启用 scss 或 less ,需要为style 元素,设置lang属性

    <style scoped lang="scss">
        div{
            font-style:italic;
        }    
    </style>
    

Mint UI中按钮组件的使用

  1. 中文官方文档:http://mint-ui.github.io/#!/zh-cn

  2. 安装

    cnpm install mint-ui -S
    

Promise 处理回调地狱问题

  1. 回调地狱,就是多层嵌套

    // 顺序读取的 1 2 3 文件的内容
    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 方法读取文件
    getFileByPath(path.join(__dirname, './files/1.txt'), function (data) {
        console.log(data)
      
        getFileByPath(path.join(__dirname, './files/2.txt'), function (data) {
            console.log(data)
      
            getFileByPath(path.join(__dirname, './files/3.txt'), function (data) {
                console.log(data)
                
             })
         })
    
    })
    
  2. Promise 是一个构造函数,表示异步操作。

    var poromise = new Promise()
    
  3. 在Promise 上有两个函数

    resolve // 成功之后的回调函数  resolve(决定)
    reject  // 失败之后的回调函数  reject(拒绝)
    
  4. Promise 是一个异步操作,所以,内部拿到操作结果后,无法使用return 把结果返回给调用者,,这个时候只能使用回调函数的形式,把成功或失败的的结果,返回给调用者

    1、异步执行成功,需要在内部调用 成功的回调函数, resoleve 把结果返回给调用者
    2、异步执行失败,需要在内部调用 失败的回调函数, reject 把结果返回给调用者
    
  5. 在Promise 构造函数的Prototype属性上,有一个.then()方法,也就是说,只要是Promise 构造函数创建的实例,都可以访问.then()方法。调用.then() 方法,为这个异步操作,指定成功(resolve) 和 失败(reject)回调函数

    // 使用.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// 放回promise对象
    }
    
    //调用读取文件的方法
    var p = getFileByPath("./files/1.txt")
    p.then(function(data){
            console.log(data)
        },function(err){
            console.log(err.message)
        }
    )
    

Promise 实例的创建,且创建就会立即执行

  1. Promise 实例的创建

    var promise = new Promise(function(){
        fs.readFile('./files/1.txt','utf-8',(err,dataStr)=>{
            if(err) throw err
            console.log(dataStr)
        })
    })
    
  2. Promise 的实例,一旦创建,就会立即调用,那么可以 创Promise 封装在一个function 中,调用function的时候在执行创建Promise 实例。

    const fs = require('fs')
    
    // 封装一个读取文件内容信息的方法
    function getFileByPath(fpath) {
        var promise = new Promise(function(){
        fs.readFile(fpath,'utf-8',(err,dataStr)=>{
            if(err) throw err
            console.log(dataStr)
          })
        })
    }
    //调用读取文件的方法
    getFileByPath("./files/1.txt")
    

利用Promise 解决回调地狱的问题

  1. 对顺序读取多个文件,利用Promise,可以提高代码的可读性,和速度

    // 使用.then()方法
    function getFileByPath(fpath) {
        return new Promise(function (resolve, reject) {
            fs.readFile(fpath, 'utf-8', (err, dataStr) => {
                if (err) return reject(err)
                resolve(dataStr)
            })
        })
    
    }
    //调用读取文件的方法
    getFileByPath("./files/1.txt")
        .then(function (data) {
            console.log(data)
            return getFileByPath('./files/2.txt')
        })
        .then(function(data){
            console.log(data)
            return getFileByPath('./files/3.txt')
        })
        .then(function(data){
            console.log(data)
        })
    

Promise 捕获异常

  1. .them()方法里面有两个回调函数,一个是成功,resolve ,成功之后的回调函数 reject 失败之后的回调函数 ,在读取第一个文件的时候,以为没有13333.txe的文件,所以调用了失败的的回调函数,然后继续执行,读取文件2 ,和文件3 的内容。

    //调用读取文件的方法
    getFileByPath("./files/13333.txt")
        .then(
        function (data) {// 成功的回调函数
            console.log(data)// 没有执行
            return getFileByPath('./files/2.txt')
        },
        function(err){ // 失败的的回调函数
            console.log("这是失败的结果:"+err.message)
            return getFileByPath('./files/2.txt')
        }
      )
    // 就算上的读取文件失败,也可以执行下面的代码
        .then(function(data){
            console.log(data)// 执行成功
            return getFileByPath('./files/3.txt')
        })
        .then(function(data){
            console.log(data)// 执行成功
        })
    
  2. 使用catch 捕获异常,在.then() 方法后面,加catch() 方法。如果在catch() 前面,有任何的Promise 执行失败,则立即终止所有的Promise 的执行,并马上进入catch 中去处理Promise 中抛出的异常。

    //调用读取文件的方法
    getFileByPath("./files/1.txt")
        .then(function (data) {
            console.log(data)// 执行成功
            return getFileByPath('./files/3333.txt')//执行失败,进入catch 处理异常
        },function(err){
            console.log("这是失败的结果:"+err.message)  // 不执行
            return getFileByPath('./files/2.txt')
        })
        .then(function(data){// 不执行
            console.log(data)  
            return getFileByPath('./files/3.txt')
        })
        .then(function(data){// 不执行
            console.log(data)
        })
        .catch(function(err){// 执行
            console.log("第二个文件读取失败:"+err.message)
        })
    
    

Promise-Jquery Ajax的使用

  1. 是用Promise 替代Ajax 成功的的方法

    <script>
        $('input').on('click',function(){
            $.ajax({
                url:'./data.json',
                type:'get',
                dataType:'json',
                // success:function(data){
                //     console.log(data)
                // }
            })
            .then(function(data){
                console.log(data)
            })
        })
    </script>
    

s.readFile(fpath,‘utf-8’,(err,dataStr)=>{
if(err) throw err
console.log(dataStr)
})
})
}
//调用读取文件的方法
getFileByPath("./files/1.txt")


1. 

##  利用Promise 解决回调地狱的问题

1. 对顺序读取多个文件,利用Promise,可以提高代码的可读性,和速度

```javascript
// 使用.then()方法
function getFileByPath(fpath) {
    return new Promise(function (resolve, reject) {
        fs.readFile(fpath, 'utf-8', (err, dataStr) => {
            if (err) return reject(err)
            resolve(dataStr)
        })
    })

}
//调用读取文件的方法
getFileByPath("./files/1.txt")
    .then(function (data) {
        console.log(data)
        return getFileByPath('./files/2.txt')
    })
    .then(function(data){
        console.log(data)
        return getFileByPath('./files/3.txt')
    })
    .then(function(data){
        console.log(data)
    })

Promise 捕获异常

  1. .them()方法里面有两个回调函数,一个是成功,resolve ,成功之后的回调函数 reject 失败之后的回调函数 ,在读取第一个文件的时候,以为没有13333.txe的文件,所以调用了失败的的回调函数,然后继续执行,读取文件2 ,和文件3 的内容。

    //调用读取文件的方法
    getFileByPath("./files/13333.txt")
        .then(
        function (data) {// 成功的回调函数
            console.log(data)// 没有执行
            return getFileByPath('./files/2.txt')
        },
        function(err){ // 失败的的回调函数
            console.log("这是失败的结果:"+err.message)
            return getFileByPath('./files/2.txt')
        }
      )
    // 就算上的读取文件失败,也可以执行下面的代码
        .then(function(data){
            console.log(data)// 执行成功
            return getFileByPath('./files/3.txt')
        })
        .then(function(data){
            console.log(data)// 执行成功
        })
    
  2. 使用catch 捕获异常,在.then() 方法后面,加catch() 方法。如果在catch() 前面,有任何的Promise 执行失败,则立即终止所有的Promise 的执行,并马上进入catch 中去处理Promise 中抛出的异常。

    //调用读取文件的方法
    getFileByPath("./files/1.txt")
        .then(function (data) {
            console.log(data)// 执行成功
            return getFileByPath('./files/3333.txt')//执行失败,进入catch 处理异常
        },function(err){
            console.log("这是失败的结果:"+err.message)  // 不执行
            return getFileByPath('./files/2.txt')
        })
        .then(function(data){// 不执行
            console.log(data)  
            return getFileByPath('./files/3.txt')
        })
        .then(function(data){// 不执行
            console.log(data)
        })
        .catch(function(err){// 执行
            console.log("第二个文件读取失败:"+err.message)
        })
    
    

Promise-Jquery Ajax的使用

  1. 是用Promise 替代Ajax 成功的的方法

    <script>
        $('input').on('click',function(){
            $.ajax({
                url:'./data.json',
                type:'get',
                dataType:'json',
                // success:function(data){
                //     console.log(data)
                // }
            })
            .then(function(data){
                console.log(data)
            })
        })
    </script>
    

原文地址:https://blog.csdn.net/XiaoYige_97/article/details/114293581

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


一准备工作umi为react的一个封装比较nice的脚手架。优点当然就是安装方便,开箱即用,集成了诸多好用功能,详见官网。当然缺点就是无法暴露原始的webpack.config.json文件,只能按照官方文档上特定的方法进行修改,而文档却并不完善。项目顺利进行大家笑嘻嘻,一旦遇到偏难怪需求,
webpack在引入两个依赖的包时,可能需要使用shimming,意思是处理代码上的兼容1、在main.js中引入jqueryimport$from'jquery'importappendfrom'./append'//下面的给页面添加元素文件append()2、append.js使用main.js的$向页面中添加元素functionappDomFunc(){
  Happypack (plugin)多线程使用loader编译文件treeshaking删除无用JS代码,依赖ESM规范source-map生产环境一定去掉process.env.XXX配置环境变量,区分各种编译环境splitchunks 代码分离去重DynamicImport动态加载js文件Hot-module-replacement开发环境热更新w
一目录结构├──build//构建相关├──config//配置相关├──src//源代码│├──api//所有请求│├──assets//主题字体等静态资源│
接着第一节的demo现在我们尝试整合一些其他资源,比如图像,看看webpack如何处理。在webpack出现之前,前端开发人员会使用grunt和gulp等工具来处理资源,并将它们从 /src 文件夹移动到 /dist 或 /build 目录中。同样方式也被用于JavaScript模块,但是,像webpack这样的工
webpack的打包原理识别入口文件通过逐层识别模块依赖(Commonjs、amd或者es6的import,webpack都会对其进行分析,来获取代码的依赖)webpack做的就是分析代码,转换代码,编译代码,输出代码最终形成打包后的代码什么是loaderloader是文件加载器,能够加载资源文件,并对这些文件进行
上一篇文章我们在一个demo中见到了webpack的身影,如果从未接触过webpack的同学学完了上一篇文章可能会觉得webpack只是一个“翻译官”,但事实上webpack可不仅仅可以‘翻译’代码,事实上,webpack是一个‘打包’工具,‘打包‘才是webpack的核心任务。打开webpack的官网:webpack中
注:本章将配合Vue详细讲解webpack前提条件1.在开始之前,请确保安装了Node.js和npm的最新版本。使用旧版本,你可能遇到各种问题,因为它们可能缺少webpack功能以及/或者缺少相关package包。在cmd中node-v,npm-v可查看对应的版本和安装情况。2.这里会用到ES6的模块化,如果你
前言、之前我认为对于项目的优化无非是从代码上去优化一些东西,比如循环呀函数式调用呀让你的代码看起来更加的简洁容易懂后来我在面试过程中不断有面试官不断地问了我这些问题所以自己就去研究了一下发现并不是我之前想的那样,一个好的webapck优化的胜过于你在整体代码上
##一、组件component###1.什么是组件?组件(Component)是Vue.js最强大的功能之一。组件可以扩展HTML元素,封装可重用的代码组件是自定义元素(对象)###2.定义组件的方式方式1:先创建组件构造器,然后由组件构造器创建组件方式2:直接创建组件###3.组件的分
 #webpack5概述>webpack是一个现代javascript应用程序的**静态模块打包器(modulebundler)**>>vue-cli脚手架环境,集成了webpack,所以才能对各类文件进行打包处理[webpack官网](https://webpack.js.org/) ##webpack能做什么webpack是一个静态模块打包
//这里导入webpack配置,我用对象的形式表示,当然entry属性上定义的文件要有//constconfig=require("./webpack.config");constconfig={entry:'./src/index.js'};const{join,dirname}=require("path");const{readFileSync,writeFileSync}=requi
安装cnpminstallwebpack-bundle-analyzer-D 修改vue.config.jsmodule.exports={chainWebpack:config=>{if(process.env.use_analyzer){//分析config.plugin('webpack-bundle-analyzer')
webpack打包html插件html-webpack-plugin的使用1.创建这样的测试目录结构1)index.html是即将被打包的文件,你可以随便写一些内容2)index.js是打包的入口文件,你可以写或不写内容2.webpack.config.js的代码如下:/***压缩html需要插件:html-webpack=plugin*插件使用方法:
vueinitwebpacktabbar创建vue项目时出现问题vue:无法加载文件C:\Users\dengqian\AppData\Roaming\npm\vue.ps1,因为在此系统上禁止运行脚本。C:\Windows\System32\WindowsPowerShell\v1.0,找到如上路径,以管理员身份运行powershell.exe即可输入set-ExecutionPolicyRemo
在webpack中使用ECharts【官网教程】1、使用如下命令通过npm 安装EChartsnpminstallecharts--save2、全局引用在main.jsimportechartsfrom'echarts'Vue.prototype.$echarts=echarts;3、运用<divstyle="width:60vw;height:280px;"ref="chart"&
如果没有看过我的上一篇文章,请先移步去看一下哈!时隔一年多,之前写的文章感觉大家还挺喜欢的,一直说要更新下一篇。但是一直没有机会,没时间,还有就是,感觉自己的技术,可能不足以支持我继续往下走。但是经过这个一年多的历练,感觉很多东西考虑的会更周全,不负期待!废话说一堆,步入正题
dist文件配置对应的路由名展示这样的效果可以创建一个本地的服务还可以进行代理项目开发是在src里进行代码逻辑编写./表示本地路径/表示绝对路径(nginx需要配置)
 1、用命令创建webpack模板项目vueinitwebpack 项目名,需要选是否的统一选否,所以的依赖手动添加  2、安装依赖vue-router,elementui,sass-loader,node-sass,axios插件安装路由:npminstallvue-router安装elementu
最近想把蘑菇博客部署到k8s上,作为一名java搬砖工,搬砖人不讲码德,biu一下就把后端各模块的dockerfile和chart包copy过来了,很快啊!接下来就可以愉快的使用helm管理蘑菇后端服务部署了。部署完后端服务后,准备制作前端镜像,发现前端打包后,无法动态读取系统环境变量,这很头疼,难不