[TOC]

Day01

MVVM 和 MVC的关系:

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

01 vue基本代码

MVVM代码示例

<!DOCTYPE html>














{{msg}}








02.v-cloak、v-text、v-html、v-bind、v-on 学习

<!DOCTYPE html>












+++{{msg}}—-






{{msg2}}





























跑马灯实例

<!DOCTYPE html>














{{msg}}









03.跑马灯案例

<!DOCTYPE html>














{{msg}}








04.事件修饰符

.stop .capture .self .prevent .once

<!DOCTYPE html>












默认冒泡
使用 .stop阻止冒泡:即触发按钮点击事件后又触发了div的点击事件




使用.capture实现捕获触发事件的机制(从外到里触发)




使用.self实现只有点击当前元素才能触发事件处理函数
self只会阻止自己身上冒泡行为的触发,并不会真正组织冒泡行为




阻止默认行为


事件只触发一次








05.v-model实现双向数据绑定

<!DOCTYPE html>








{{msg}}


















06.计算器案例

双向绑定

<!DOCTYPE html>


























07.vue中使用样式-class

<!DOCTYPE html>











BIG H1





BIG VUE




三元表达式




使用对象代替三元表达式




直接使用对象








08. vue 内联样式绑定

<!DOCTYPE html>













BIG H1



数组类型







09. v-for循环普通数组

<!DOCTYPE html>











{{list[0]}}



{{item}}



索引值:{{i}}—-每一项:{{item}}









10. v-for 循环对象数组

<!DOCTYPE html>











{{user.id}}——{{user.name}}—-索引{{i}}









11.v-for 循环对象

<!DOCTYPE html>












值是: {{val}} —- 键是: {{key}}—- 索引:{{index}}









12. v-for 迭代数字

<!DOCTYPE html>













这是第 {{count}} 次循环








13. v-for中key属性的使用

<!DOCTYPE html>























{{item.id}}
————-
{{item.name}}








14. v-if 和 v-show的使用

<!DOCTYPE html>



















这是用v-if控制的元素



这是v-show控制的元素



<!—方法只有一句话可以不在method中声明 —>









Day2

01. 品牌案例

<!DOCTYPE html>















添加品牌






































Id Name Ctime Operation
{{item.id}} {{item.ctime | dateFormat(‘yyyy-MM-DD hh:mm:ss’)}}

删除






{{1+1}}

{{dt | dateFormat}}













02. 过滤器学习

<!DOCTYPE html>











{{msg | msgFormat(‘疯狂+1’,’123’) | test}}







自定义私有过滤器
filters: { // 定义私有过滤器 过滤器有两个条件【过滤器名称 和 处理函数】
// 过滤器调用的时候, 采用的是就近原则,如果私有过滤器和全局过滤器名称一致,
// 优先调用私有过滤器
dateFormat: function(dt, pattern = “”) {
var y = dt.getFullYear()
// es6 新方法: str.padStart(a,b) | str.padEnd(a,b)
// 不足a位字符,在开始(结束)为hi填充b
var m = (dt.getMonth() + 1).toString().padStart(2,’0’)
var d = dt.getDate().toString().padStart(2,’0’)
if (pattern.toLowerCase() === ‘yyyy-mm-dd’) {
return ${y}-${m}-${d}
} else {
var hh = dt.getHours().toString().padStart(2,’0’)
var mm = dt.getMinutes().toString().padStart(2,’0’)
var ss = dt.getSeconds().toString().padStart(2,’0’)
return ${y}-${m}-${d} ${hh}:${mm}:${ss}~~
}
}
}


03.键盘修饰符

vue内置案件修饰符:
.enter .tab .delete(“捕获删除键和退格键”)
.esc .space .up .down .left .right

.js中按键对应的键盘码
可以通过 Vue.config.keyCodes 对象自定义案件修饰符别名

// 自定义全局案件修饰符
Vue.config.keyCodes.f2 = 113; // 将键盘码113 绑定f2

04.自定义指令

// 使用 Vue.directive()定义全局指令
// 其中, 参数1 : 指令名称, 注意 , 在定义的时候指令的名称前面不需要加 v- 前缀
// 在调用的时候 必须在指令名称前 加上v- 前缀进行调用
// 参数2: 是一个对象 这个对象身上有一些指令相关的函数 这些函数可以在特定的阶段执行相关操作
Vue.directive(‘focus’,{
bind: function(el){ // 每当指令绑定到元素上的之后 会立即执行这个bind函数,只执行一次
//参数el 被绑定的元素
// 注意: 在每个函数中 , 第一个参数永远是el,表示被绑定了指令的元素,这个el 是原生的js对象
// 在元素刚绑定了指令的时候,还没有插入到DOM中去,这时候调用focus方法没有作用
// 因为一个元素只有插入到DOM之后才能获取焦点

// el.focus()
},
inserted: function(el){// 表示元素插入到DOM中的时候,会执行inserted函数
el.focus()
},
updated:function(el){//当VNode更新的时候会执行updated,可能会触发多次
// 和JS行为有关的操作最好在inserted中执行,防止js不生效
}
})
自定义指令的使用

//自定义一个设置字体颜色的指令
Vue.directive(‘color’,{
// 样式 只要通过指令绑定给了元素,不管这个元素有没有被插入到页面中去
// 这个元素肯定有了一个内联样式
// 将来元素肯定会显示到页面中去, 这时候浏览器的渲染迎请必然会解析样式,解析给元素
bind:function(el,binding){
// el.style.color = ‘red’
// 和样式相关的操作, 一般都可以在bind中执行

//自定义指令的名称
/ console.log(binding.name)
console.log(binding.value)
console.log(binding.expression)
/

el.style.color = binding.value
}
})


05 自定义私有指令

directives: { // 自定义私有指令
‘fontweight’: { //设置字体粗细
bind: function(el, binding) {
el.style.fontweight = binding.value
}
},
‘fontsize’: function(el, binding) { // 自定义指令的简写 注意: 这个function等同于把代码写到了bind和 update中去
el.style.fontSize = parseInt(binding.value) + ‘px’
}
}


06 vue-resource 实现get,post,jsonp请求

<!DOCTYPE html>






















Day03

1.通过ajax访问后台完成增删改(未连接数据库)

前台代码为

<!DOCTYPE html>















添加品牌






























Id Name Ctime Operation
{{item.id}} {{item.name}} {{item.ctime}} 删除







后台代码为

package com.tjc.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value = “/test”)
public class Test {

private Map container;
private List> message;
private int countid = 3;

@RequestMapping(method = RequestMethod.GET, value = “/test”)
public Map test() {
if (container == null) {
container = new HashMap<>();
container.put(“status”, 0);
message = new ArrayList<>();
Map map = new HashMap<>();
map.put(“id”, “1”);
map.put(“name”, “奥迪”);
map.put(“ctime”, new Date());

Map map2 = new HashMap<>();
map2.put(“id”, “2”);
map2.put(“name”, “宝马”);
map2.put(“ctime”, new Date());
message.add(map);
message.add(map2);
container.put(“message”, message);
}
return container;
}

@RequestMapping(method = RequestMethod.POST, value = “/addproduct”)
public Map addProduct(@RequestBody Map formobj) {
Map map = new HashMap<>();
map.put(“status”, 0);
map.put(“message”, “添加成功”);

Map data = new HashMap<>();
data.put(“id”, “” + (countid++));
data.put(“name”, formobj.get(“name”));
data.put(“ctime”, new Date());
message.add(data);
container.put(“message”, message);
return map;

}

@RequestMapping(method = RequestMethod.GET, value = “/delproduct/{id}”)
public Map delProduct(@PathVariable String id) {
Map map = new HashMap<>();
map.put(“status”, 0);
map.put(“message”, “删除成功”);

Iterator> mp = message.iterator();
while (mp.hasNext()) {
Map next = (Map) mp.next();
String mid = (String) next.get(“id”);
if (mid.equals(id)) {
// message.remove(next);
mp.remove();
countid—;
// break; // 注意 : 不加break 会报 java.util.ConcurrentModificationException: null
// 原因是在遍历list的过程中,如果修改了元素,会导致list中索引与对应的值不同,因此抛出异常;
// 但是加break只能解决单个删除的问题
// 通过迭代器提供的remove方法,就完美解决了这个问题
}
}

return map;
}

}

03.使用过度类名实现动画.html

<!DOCTYPE html>




















这是一个H3








这是一个H6









04. 使用第三方类实现动画

<!DOCTYPE html>





















这是一个H3









05. 使用钩子函数模拟小球半场动画

<!DOCTYPE html>




























06. 列表动画

<!DOCTYPE html>




























  • {{item.id}} — {{item.name}}









  • 07 定义vue组件

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

    组件化 和 模块化 的不同:
    模块化: 是从代码逻辑的角度进行划分的,方便后台代码的分层开发,保证每个功能模块的职能单一
    组件化: 是从UI界面的角度进行划分的,前端的组件化,方便ui组件的重用

    7.1自定义组件方式一

    <!DOCTYPE html> <html lang=”en”> <head> <meta charset=”UTF-8”> <title>创建组件的方式1</title> <script src=”lib/vue.js”></script> </head> <body> <div id=”app”> <my-com1></my-com1> <mycom2></mycom2> </div>

    <script> // 1.1 使用vue.extend 来创建全局的Vue组件 var com1 = Vue.extend({
    template:

    这是使用Vue.extend创建的组件

    //通过 template 属性,制定了组件要展示的HTML结构 });
    // 1.2 使用Vue.component(‘组件的名称’,创建出来的组件模板对象) // 如果使用vue.component 定义全局组件的时候,组件名称使用了驼峰命名,则在引用组件的时候
    // 需要把 大写的驼峰 改为小写的字母 ,同时两个单词之间使用 - 进行连接;
    // 如果不使用驼峰,则直接引用名称即可
    // Vue.component(‘myCom1’,com1) _Vue.component(‘myCom1’, **_com1
    )

    _//Vue.component 第一个参数: 组件的名称,将来在引用组件的时候,就是一个标签形式来引入
    // 第二个参数: Vue.extend 创建的组件,其中template 就是组件将来要展示的内容 _Vue.
    component(“mycom2”, Vue.extend({
    template:

    组件注册方式-合并写法

    >”
    }))

    var vm = new Vue({
    el: ‘#app’,
    data: {
    flag: false
    },
    methods: {}
    });
    </
    script>
    </
    body> </html**>

    7.2 自定义组件方式2

    | <!DOCTYPE html> <html lang=”en”> <head> <meta charset=”UTF-8”> <title>创建组件的方式2</title> <script src=”lib/vue.js”></script> </head> <body> <div id=”app”> <my-com></my-com> </div>

    <script> Vue.component(“myCom”, {
    /注意: 不论是那种方式创建出来的组件,组件的template属性指向的模板内容必须有且只有一个唯一的根元素/ template:

    Vue.component创建出来的组件

    这是span中的内容

    })
    var vm = new Vue({
    el: ‘#app’,
    data: {
    flag: false
    },
    methods: {}
    });
    </script>
    </body> </html> | | —- |

    7.3 自定义组件方式3(使用这种方式)

    <!DOCTYPE html> <html lang=”en”> <head> <meta charset=”UTF-8”> <title>创建组件的方式2</title> <script src=”lib/vue.js”></script> </head> <body> <div id=”app”>
    <my-com></my-com> </div>
    <div id=”app2”> <my-com></my-com> <login></login> </div>
    <template id=”tmpl”> <div> <h1>这是通过tmplate元素,在外部定义的组件结构</h1> <h3>一般使用这种方式</h3> </div> </template>

    <script> /自定义组件方式3/ _Vue.component(“myCom”, {
    template: ‘#tmpl’ })
    **var _vm
    = new Vue({
    el: ‘#app’,
    data: {
    flag: false
    },
    methods: {}
    });

    var vm2 = new Vue({
    el: ‘#app2’,
    data:{},
    methods:{},
    filters:{},
    directives:{},
    components:{ //定义实例内部私有组件 login:{/私有组件,只能在vm2控制区域内使用/ // template:’

    这是私有的login组件


    template: ‘#tmpl’
    }
    },
    _// 生命周期钩子函数 _beforeCreate(){},
    created(){},
    beforeMount(){},
    mounted(){},
    beforeUpdate(){},
    updated(){},
    beforeDestroy(){},
    destroyed(){}
    });
    </
    script>
    </
    body> </html**>


    08. 组件中的data和 methods

    <!DOCTYPE html> <html lang=”en”> <head> <meta charset=”UTF-8”> <title>组件中的data</title> <script src=”lib/vue.js”></script> </head> <body> <div id=”app”> <mycom1></mycom1> </div>

    <script> // 1. 组件可以有自己的data数据 // 2. 组件的data 和实例的 data 不同,实例中的data可以为一个对象,但是组件中的data必须是一个方法 // 3. 组件中的data 除了必须为一个方法之外,这个方法内部还必须返回一个对象 // 4. 组件中的data数据 使用方式和实例中的data 使用方式完全一样 _Vue.component(“mycom1”,{
    template:

    这是全局组件——-{{msg}}

    ,
    data:function () {
    return {
    msg:‘这是组件中的data定义的数据’
    }
    }
    })


    //创建vue实例,得到ViewModel **var _vm = new Vue({
    el:‘#app’
    })
    </
    script>
    </
    body> </html**>

    为什么组件中的data必须是一个方法,返回值是一个对象(为了让不同的组件不相互影响)

    <!DOCTYPE html> <html lang=”en”> <head> <meta charset=”UTF-8”> <title>为什么组件中的data必须是一个方法</title> <script src=”lib/vue.js”></script> </head> <body> <div id=”app”> <counter></counter> <hr> <counter></counter> <hr> <counter></counter> </div>
    <template id=”tmpl”> <div> <input type=”button” value=”+1” @click=”increment”> <h3>{{count}}</h3> </div> </template>

    <script> // 这是一个计数器的组件,附带一个按钮,每当点击按钮,data中的count值+1
    var dataObj = {count: 0}

    Vue.component(‘counter’, {
    template: ‘#tmpl’,
    data: function () {
    // return dataObj
    return {count: 0} / 就是为了 让不同的组件之间互不影响 / },
    methods: {
    increment() {
    this.count++
    }
    }
    })

    //创建vue实例,得到ViewModel
    var vm = new Vue({
    el: ‘#app’
    })
    </script>
    </body> </html>

    09. 组件切换方式1

    <!DOCTYPE html> <html lang=”en”> <head> <meta charset=”UTF-8”> <title>组件切换-方式1</title> <script src=”lib/vue.js”></script> </head> <body> <div id=”app”> <a href=”” @click.prevent=”flag=false”>登录</a> <a href=”” @click.prevent=”flag=true”>注册</a>
    <login v-if=”!flag”></login> <register v-else=”flag”></register>
    </div>
    <template id=”login”> <div> <h3>登录组件</h3> 用户名: <input type=”text”> 密码: <input type=”password”> <input type=”button” value=”登录”> </div> </template>
    <template id=”register”> <div> <h3>注册组件</h3> 用户名: <input type=”text”> 密码: <input type=”password”> <input type=”button” value=”注册”> </div> </template>

    <script>
    Vue.component(‘login’,{
    template:‘#login’
    });

    Vue.component(‘register’,{
    template: ‘#register’
    })

    //创建vue实例,得到ViewModel
    var vm = new Vue({
    el: ‘#app’,
    data:{
    flag:true
    }
    })
    </script>
    </body> </html>

    10 组件切换方式2(推荐)

    <!DOCTYPE html> <html lang=”en”> <head> <meta charset=”UTF-8”> <title>组件切换-方式1</title> <script src=”lib/vue.js”></script> </head> <body> <div id=”app”>
    <a href=”” @click.prevent=”comName=’login’”>登录</a> <a href=”” @click.prevent=”comName=’register’”>注册</a> <component :is=”comName”></component>


    </div>

    <template id=”login”> <div> <h3>登录组件</h3> 用户名: <input type=”text”> 密码: <input type=”password”> <input type=”button” value=”登录”> </div> </template>
    <template id=”register”> <div> <h3>注册组件</h3> 用户名: <input type=”text”> 密码: <input type=”password”> <input type=”button” value=”注册”> </div> </template>

    <script>
    Vue.component(‘login’,{
    template:‘#login’
    });

    Vue.component(‘register’,{
    template: ‘#register’
    })

    //创建vue实例,得到ViewModel
    var vm = new Vue({
    el: ‘#app’,
    data:{
    comName:‘login’ // 当前component中的 :is 绑定的组件的名称 }
    })
    </script>
    </body> </html>


    11.组件切换动画

    <!DOCTYPE html> <html lang=”en”> <head> <meta charset=”UTF-8”> <title>组件切换-方式1</title> <script src=”lib/vue.js”></script> <style> .v-enter,.v-leave-to{
    opacity: 0;
    transform: translateX(150px);
    }
    .v-enter-active,.v-leave-active{
    transition: all 1s ease;
    }
    </style> </head> <body> <div id=”app”>
    <a href=”” @click.prevent=”comName=’login’”>登录</a> <a href=”” @click.prevent=”comName=’register’”>注册</a>

    <transition mode=”out-in”> <component :is=”comName”></component> </transition>


    </div>
    <template id=”login”> <div> <h3>登录组件</h3> 用户名: <input type=”text”> 密码: <input type=”password”> <input type=”button” value=”登录”> </div> </template>
    <template id=”register”> <div> <h3>注册组件</h3> 用户名: <input type=”text”> 密码: <input type=”password”> <input type=”button” value=”注册”> </div> </template>

    <script>
    Vue.component(‘login’,{
    template:‘#login’
    });

    Vue.component(‘register’,{
    template: ‘#register’
    })

    //创建vue实例,得到ViewModel
    var vm = new Vue({
    el: ‘#app’,
    data:{
    comName:‘login’ // 当前component中的 :is 绑定的组件的名称
    }
    })
    </script>
    </body> </html>


    Day 03

    01. 小球动画复习

    <!DOCTYPE html> <html>
    <head> <meta charset=”utf-8”> <title></title> <script src=”../lib/vue.js” type=”text/javascript” charset=”utf-8”></script> <script src=”../lib/vue-resource.js” type=”text/javascript” charset=”utf-8”></script> <link rel=”stylesheet” type=”text/css” href=”../lib/bootstrap.css”/> <style type=”text/css”> .ball {
    width: 15px;
    height: 15px;
    border-radius: 50%;
    background-color: red;
    }
    </style> </head>
    <body> <div id=”app”> <input type=”button” value=”加入购物车” @click=”flag=!flag”/> <br/><br/>
    <transition @before-enter=”beforeEnter” @enter=”enter” @after-enter=”afterEnter”> <div class=”ball” v-show=”flag”></div> </transition> </div>

    <script type=”text/javascript”> var vm = new Vue({
    el: ‘#app’,
    data: {
    flag: false
    },
    methods: {
    //注意 : 动画钩子函数第一个参数:el 表示要执行动画 的那个元素,是个原生的JS DOM对象
    //可以认为el是通过-> document.getElementById(‘’) 获取到的原生对象
    _beforeEnter(el) {
    //beforeEnter 表示动画入场之前,此时,动画尚未开始,可以在beforeEnter中设置原色开始动画之前的起始样式
    / 设置小球开始动画之前的起始位置 /
    el.style.transform = “translate(0,0)”
    },
    enter(el, done) {
    // 这句话没有实际的作用,但是如果不写出不来动画效果,可以认为el.offsetWidth强制动画刷新
    el.offsetWidth
    // enter 表示动画开始之后的样式, 这里 可以设置小球完成动画之后的结束状态
    el.style.transform = “translate(150px,450px)”
    // 设置小球的过度状态
    el.style.transition = ‘all 1s ease’

    // 这里的done() 其实就是 afterEnter这个函数, 也就是说: done是一个函数的引用
    done()

    },
    afterEnter(el) {
    // 这句话,第一个功能是控制小球的显示和隐藏
    // 第二个功能直接跳过后半场动画,让flag 变成false
    // 当第二次点击的时候,flag flase—> true this.flag = !this.flag

    //Vue 把一个完整的动画,使用钩子函数拆分成了两部分
    // 我们使用flag 标识符来表示动画的切换;
    //刚开始,flag = false —-> true 上半场动画
    // true —-> false 后半场动画 _}
    }
    });
    </script> </body>
    </html>

    02. 组件定义复习

    <!DOCTYPE html> <html>
    <head> <meta charset=”utf-8”> <title>定义组件的方式</title> <script src=”../lib/vue.js” type=”text/javascript” charset=”utf-8”></script> <script src=”../lib/vue-resource.js” type=”text/javascript” charset=”utf-8”></script> <link rel=”stylesheet” type=”text/css” href=”../lib/bootstrap.css”/>
    </head>
    <body> <div id=”app”> <mylogin></mylogin> <mylogin2></mylogin2> <login></login> </div>

    <script type=”text/javascript”> // 通过 对象字面量的形式,定义了一个组件模板对像 var login = {
    template:

    1234


    }
    // 通过 Vue.component 把组件模板对象注册为一个全局的Vue 组件,同时为这个组件起了一个名称, //可以让我们 通过标签的形式再页面中直接引入这个组件 _Vue.component(‘mylogin’,**_login)

    // 定义组件的时候,如果要定义全局的组件, Vue.component(“组件的名称”,组件的模板对象)
    var vm = new Vue({
    el: ‘#app’,
    components:{
    //定义私有组件
    ‘mylogin2’: login, //组件的名称: 组件的模板对象 login //组件内部定义私有的组件,可以直接写对象名字,等同于 login:login
    }
    });
    </
    script> </body>
    </
    html**>


    03. 父组件向子组件传值

    <!DOCTYPE html> <html>
    <head> <meta charset=”utf-8”> <title>父组件向子组件传值</title> <script src=”../lib/vue.js” type=”text/javascript” charset=”utf-8”></script> <script src=”../lib/vue-resource.js” type=”text/javascript” charset=”utf-8”></script> <link rel=”stylesheet” type=”text/css” href=”../lib/bootstrap.css”/>
    </head>
    <body> <div id=”app”> <com1 :parentmsg=”msg”></com1> </div>

    <script type=”text/javascript”>

    var vm = new Vue({
    el: ‘#app’,
    data:{
    msg:‘父组件中的数据’
    },
    components:{
    data:function(){ // 注意: 子组件中的data 数据,并不是通过 父组件传递过来的,而是子组件自身私有的 // 比如 子组件通过ajax 请求,返回的数据都可以放在 data 身上 // data 中的数据 是可读 可写的/ props 中的数据都是只读的,无法重新赋值 return {
    title: ‘123’,
    content: ‘ddd’
    }
    },
    com1 : {
    // 结论: 子组件中默认无法访问到父组件中的 data 上的数据和 methods 中的方法 template:

    这是子组件—-{{parentmsg}}

    ,
    // 注意 : 组件中的 所有 props 中的数据,都是通过父组件传递给子组件的 props:[‘parentmsg’] // 把父组件传递过来的parentmsg属性现在props 数组中定义一下,这样才能使用这个数据 }
    }
    });
    </script> </body>
    </html>


    04. 父组件把方法传递给子组件

    <!DOCTYPE html> <html>
    <head> <meta charset=”utf-8”> <title>父组件向子组件传值</title> <script src=”../lib/vue.js” type=”text/javascript” charset=”utf-8”></script> <script src=”../lib/vue-resource.js” type=”text/javascript” charset=”utf-8”></script> <link rel=”stylesheet” type=”text/css” href=”../lib/bootstrap.css”/>
    </head>
    <body> <div id=”app”> <com2 @func=”show”></com2> </div>
    <template id=”tmpl”> <div> <h1>这是子组件</h1> <input type=”button” value=”这是子组件中的按钮,点击触发父组件传递过来的func方法” @click=”myclick”> </div> </template>
    <script type=”text/javascript”>
    var com2 = { // 定义了一个字面量类型的 组件模板对象
    template: ‘#tmpl’, // 通过指定了一个Id 表示要加载指定Id 的template 元素中的内容,当作组件的html结构 methods: { myclick() {
    // 当点击子组件的按钮的时候 如何拿到父组件穿过来的func 方法,并调用这个方法?
    // emit 英文原意 : 触发 调用的意思
    this.$emit(‘func’,123) // 123 是传给show方法的参数
    this.$emit(‘func’,this.sonmsg) // 子组件向父组件传值 } },
    data() {
    return {
    sonmsg : {name:‘小头儿子’, age:6}
    }
    }

    }

    var vm = new Vue({
    el: ‘#app’,
    data: {
    datamsgFromSon : null
    },
    methods: {
    show(data) {
    alert(“调用了父组件的show方法”)
    console.log(data)
    this.datamsgFromSon = data
    } },
    components: {
    com2 // com2:com2 相同的 }
    });
    </script> </body>
    </html>

    05. 组件案例-评论列表

    <!DOCTYPE html> <html>
    <head> <meta charset=”utf-8”> <title>评论列表案例</title> <script src=”../lib/vue.js” type=”text/javascript” charset=”utf-8”></script> <script src=”../lib/vue-resource.js” type=”text/javascript” charset=”utf-8”></script> <link rel=”stylesheet” type=”text/css” href=”../lib/bootstrap.css”/>
    </head>
    <body> <div id=”app”>
    <cmt-box @func=”loadComments”></cmt-box>
    <ul class=”list-group”> <li class=”list-group-item” v-for=”(item,index) in list” :key=”index”> <span class=”badge”>评论人: {{item.user}}</span> {{item.content}}
    </li> </ul>
    </div>
    <template id=”tmpl”> <div> <div class=”form-group”> <label>评论人:</label> <input type=”text” class=”form-control” v-model=”user”> </div>
    <div class=”form-group”> <label>评论内容:</label> <textarea class=”form-control” v-model=”content”></textarea> </div>
    <div class=”form-group”> <input type=”button” value=”发表评论” class=”btn btn-info” @click=”postComment” > </div>
    </div> </template>

    <script type=”text/javascript”>
    var commentBox = {
    template: “#tmpl”,
    data() {
    return {
    user: “”,
    content: “”
    }
    },
    methods: {
    postComment() {
    //发表评论的方法
    // 分析: 发表评论的业务逻辑 // 1. 评论数据存到哪里去 —- 存放到 localStroge中
    // 2. 先组织出一个最新的评论数据对象
    // 3. 想办法 把 第二步中得到的评论对象保存到 localStorage 中
    // 3.1 localStorage 只支持存放字符串数据,要先调用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: ‘春风吹又生’}
    ]
    },beforeCreate(){
    //这里不能调用loaddComments方法,因为在执行这个钩子函数的时候,data 和 method 都还没被初始化 },created(){
    //这里已经初始化好了
    this.loadComments()
    },
    methods: {
    loadComments(){
    // 从本地的localStorage 中加载列表
    var list = JSON.parse(localStorage.getItem(‘cmts’)||‘[]’) //能读到就是读到了,读不到就是’[]’ this.list = list
    }
    },
    components: {
    ‘cmt-box’: commentBox
    }
    });
    </
    script> </body>
    </
    html**>

    06. ref 获取DOM元素

    <!DOCTYPE html> <html>
    <head> <meta charset=”utf-8”> <title>ref获取DOM元素和组件</title> <script src=”../lib/vue.js” type=”text/javascript” charset=”utf-8”></script> <script src=”../lib/vue-resource.js” type=”text/javascript” charset=”utf-8”></script> <link rel=”stylesheet” type=”text/css” href=”../lib/bootstrap.css”/>
    </head>
    <body> <div id=”app”> <input type=”button” @click=”getElement” value=”获取元素”> <h3 id=”myh3” ref=”myh3”>哈哈哈,今天天气太好了!!</h3>
    <hr> <login ref=”mylogin”></login>
    </div>

    <script type=”text/javascript”> var login = {
    template:

    登录组件

    ,
    data(){
    return {
    msg:“my msg”
    }
    },methods: {
    show(){
    alert(“调用了子组件的方法”)
    }
    }
    }

    var vm = new Vue({
    el: ‘#app’,
    methods: {
    getElement() {
    // console.log(document.getElementById(‘myh3’).innerText)
    // ref 是 英文单词 【reference】引用
    console.log(this.$refs.myh3.innerText) console.log(this.$refs.mylogin)
    }
    }, components: {
    login
    }

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

    07. 路由-路由的基本使用

    | <!DOCTYPE html> <html>
    <head> <meta charset=”utf-8”> <title></title> <script src=”../lib/vue.js” type=”text/javascript” charset=”utf-8”></script> <script src=”../lib/vue-resource.js” type=”text/javascript” charset=”utf-8”></script> <link rel=”stylesheet” type=”text/css” href=”../lib/bootstrap.css”/>
    <script src=”../lib/vue-router.js”></script>
    <style> /第一种方式,不修改linkActiveClass,路由时默认给当前路由对象添加class = router-link-active/
    .router-link-active {
    color: #7dff31;
    font-weight: 800;
    font-style: italic; /倾斜/
    font-size: 80px;
    text-decoration: underline;
    }

    /第二种方式,修改linkActiveClass,路由时给当前路由对象添加 class = myactive/
    .myactive {
    color: #7dff31;
    font-weight: 800;
    font-style: italic; /倾斜/
    font-size: 80px;
    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”> <a href=”#/login”>登录</a> <a href=”#/register”>注册</a> <!—所以 可以把 router-view 认为是一个占位符 —

    <hr>


    <router-link to=”/login”>登录</router-link> <router-link to=”/register”>注册</router-link>

    <transition mode=”out-in”> <router-view></router-view> </transition>
    </div>
    <script type=”text/javascript”>
    // 组件的模板对象
    **var _login = {
    template:

    登录组件


    }
    var register = {
    template:

    注册组件


    }

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

    // {path:’/‘,component:login}, {
    path:‘/‘,redirect:‘/login’**},_//这里的redirect(重定向),如果请求的是根路径,则跳转到/login
    {path: ‘/login’, component: **_login},
    {
    path: ‘/register’, component: register}
    ],
    linkActiveClass: ‘myactive’/修改高亮的第二种方式/
    });


    var vm = new Vue({
    el: ‘#app’,
    router: routeObj // 3. 将路由规则对象注册到vm实例上,用来监听url地址变化,然后展示对应的组件
    });
    </
    script> </body>
    </
    html**>
    | | —- |

    08. 路由规则中定义参数

    <!DOCTYPE html> <html>
    <head> <meta charset=”utf-8”> <title></title> <script src=”../lib/vue.js” type=”text/javascript” charset=”utf-8”></script> <script src=”../lib/vue-resource.js” type=”text/javascript” charset=”utf-8”></script> <link rel=”stylesheet” type=”text/css” href=”../lib/bootstrap.css”/>
    <script src=”../lib/vue-router.js”></script> <style> /给路由切换添加动画/
    .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?id=10&name=张三”>登录</router-link> <router-link to=”/register”>注册</router-link>
    <transition mode=”out-in”> <router-view></router-view> </transition> </div>
    <script type=”text/javascript”>
    var login = {
    template:

    登录—{{$route.query.id}}—-{{$route.query.name}}

    , created(){ //组件的生命周期钩子函数
    // console.log(this.$route)
    console.log(this.$route.query.id)
    }
    }
    var register = {
    template:

    注册


    }

    var routerObj = new VueRouter({
    routes: [
    {path: “/“, redirect: “/login”},
    {path: “/login”, component: login},
    {path: “/register”, component: register}
    ], linkActiveClass: ‘btn-primary’/修改高亮的第二种方式/
    })

    var vm = new Vue({
    el: ‘#app’,
    router: routerObj
    });
    </script> </body>
    </html>


    09. 路由规则传参—方式2

    <!DOCTYPE html> <html>
    <head> <meta charset=”utf-8”> <title></title> <script src=”../lib/vue.js” type=”text/javascript” charset=”utf-8”></script> <script src=”../lib/vue-resource.js” type=”text/javascript” charset=”utf-8”></script> <link rel=”stylesheet” type=”text/css” href=”../lib/bootstrap.css”/>
    <script src=”../lib/vue-router.js”></script> <style> /给路由切换添加动画/
    .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/12/李四”>登录</router-link> <router-link to=”/register”>注册</router-link>
    <transition mode=”out-in”> <router-view></router-view> </transition> </div>
    <script type=”text/javascript”>
    var login = {
    template:

    登录—-{{$route.params.id}}——{{$route.params.name}}

    , created(){ //组件的生命周期钩子函数
    // console.log(this.$route)
    console.log(this.$route.query.id)
    }
    }
    var register = {
    template:

    注册


    }

    var routerObj = new VueRouter({
    routes: [
    {path: “/“, redirect: “/login”},
    {path: “/login/:id/:name”, component: login}, {path: “/register”, component: register}
    ], linkActiveClass: ‘btn-primary’/修改高亮的第二种方式/
    })

    var vm = new Vue({
    el: ‘#app’,
    router: routerObj
    });
    </script> </body>
    </html>

    10. 路由-路由的嵌套

    <!DOCTYPE html> <html>
    <head> <meta charset=”utf-8”> <title></title> <script src=”../lib/vue.js” type=”text/javascript” charset=”utf-8”></script> <script src=”../lib/vue-resource.js” type=”text/javascript” charset=”utf-8”></script> <link rel=”stylesheet” type=”text/css” href=”../lib/bootstrap.css”/>
    <script src=”../lib/vue-router.js”></script> <style> /给路由切换添加动画/
    .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=”/account”>Account</router-link>
    <transition mode=”out-in”> <router-view></router-view> </transition> </div>
    <template id=”tmpl”> <div> <h1>这是Account组件</h1> <router-link to=”/account/login”>登录</router-link> <router-link to=”/account/register”>注册</router-link>
    <transition mode=”out-in”> <router-view></router-view> </transition> </div> </template>
    <script type=”text/javascript”>
    //组件模板对象
    var account = {
    template: ‘#tmpl’
    }
    var login = {
    template:

    登录组件


    }
    var register = {
    template:

    注册组件


    }

    var router = new VueRouter({
    routes: [
    {
    path: ‘/account’, component: account, children: [//使用children 属性设置子路由 ,同时 子路由的path 前面不要加/
    //否则永远以跟路径开始请求
    {path: ‘login’, component: login},
    {path: ‘register’, component: register} ]
    }
    ]
    })


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

    11. 路由-命名视图(使用组件实现经典布局)

    <!DOCTYPE html> <html>
    <head> <meta charset=”utf-8”> <title></title> <script src=”../lib/vue.js” type=”text/javascript” charset=”utf-8”></script> <script src=”../lib/vue-resource.js” type=”text/javascript” charset=”utf-8”></script> <script src=”../lib/vue-router.js”></script> <style> /给路由切换添加动画/
    .v-enter, .v-leave-to {
    opacity: 0;
    transform: translateX(140px);
    }

    .v-enter-active, .v-leave-active {
    transition: all 0.5s ease;
    }

    html, body { /去除html以及body自带的边距/
    margin: 0;
    padding: 0;
    }
    .header {
    background-color: orange;
    height: 80px;
    }

    h1 {
    margin: 0; /去除h1所带来的边距/
    padding: 0;
    font-size: 16px;
    }
    .container {
    display: flex; /设置左右排列/ height: 600px;
    }

    .left {
    background-color: lightblue;
    flex: 2; /设置所占比例/ }

    .main {
    background-color: lightcoral;
    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 type=”text/javascript”> var header = {
    template:

    Header头部区域


    }
    var leftBox = {
    template:

    Left区域侧边栏


    }
    var mainBox = {
    template:

    Main主体区域


    }

    // 创建路由对象
    var router = new VueRouter({
    routes: [
    {
    path: ‘/‘, components: {
    ‘default’: header,
    ‘left’: leftBox,
    ‘main’: mainBox__ }
    }
    ]
    })


    var vm = new Vue({
    el: ‘#app’,
    data: {},
    methods: {},
    router: router__ });
    </script> </body>
    </html>


    效果图如下:


    Day 04

    1. watch 监听data中数据的变化

    <!DOCTYPE html> <html lang=”en”> <head> <meta charset=”UTF-8”> <title>名称案例</title> <link rel=”stylesheet” href=”../lib/bootstrap.css”> <script src=”../lib/vue.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> var vm = new Vue({
    el: ‘#app’,
    data: {
    firstname: ‘’,
    lastname: ‘’,
    fullname: ‘’
    },
    methods: {},
    watch: {
    //使用这个属性可以 监视 data 中指定数据的变化,然后触发 watch中对应的function 处理函数
    _firstname: function (newVal, oldVal) {
    // this.fullname = this.firstname + ‘-‘ + this.lastname

    this.fullname = newVal + “-“ + this.lastname
    },
    lastname: function (newVal, oldVal) {
    // this.fullname = this.firstname + ‘-‘ + this.lastname
    _this.fullname = this.firstname + “-“ + newVal
    } }
    })

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

    02.使用watch监听路由地址的改变

    <!DOCTYPE html> <html lang=”en”> <head> <meta charset=”UTF-8”> <title>watch监视路由地址的改变</title> <script src=”../lib/vue.js”></script> <script src=”../lib/vue-router.js”></script> <link rel=”stylesheet” href=”../lib/bootstrap.css”> <style> .v-enter, .v-leave-to {
    opacity: 0;
    transform: translateX(180px);
    }

    .v-enter-active, .v-leave-active {
    transition: all 0.4s ease;
    }

    .myactive {
    color: pink;
    font-size: medium;
    }
    </style> </head> <body> <div id=”app”> <router-link to=”/account”>Account</router-link> <transition mode=”out-in”> <router-view></router-view> </transition> </div>
    <template id=”tmpl”> <div> <h1>这是account组件</h1> <router-link to=”/account/login”>登录</router-link> <router-link to=”/account/register”>注册</router-link> <transition mode=”out-in”> <router-view></router-view> </transition> </div> </template>
    <template id=”login”> <div> 用户名:
    <input type=”text”> 密码:
    <input type=”password”> </div> </template>
    <template id=”register”> <div> 手机号:
    <input type=”text”> </div> </template>
    <script> var account = {
    template: ‘#tmpl’
    }

    var login = {
    template: ‘#login’
    }
    var register = {
    template: ‘#register’
    }

    var router = new VueRouter({
    routes: [
    {
    path: ‘/account’, component: account, children: [
    {path: “login”, component: login},
    {path: “register”, component: register}
    ]
    }
    ], linkActiveClass: ‘myactive’
    })

    var vm = new Vue({
    el: ‘#app’,
    data: {},
    methods: {},
    router: router,
    watch: {
    // this.$route.path 路由地址 ‘$route.path’: function (newVal, oldVal) { // console.log(newVal + “————-“ + oldVal)
    if(newVal===‘/account/login’){
    alert(‘欢迎进入登录页面’)
    }else if(newVal===‘/account/register’){
    alert(“欢迎进入注册页面”) }
    }
    }
    })
    </script>

    </body> </html>

    03.计算属性computed

    <!DOCTYPE html> <html lang=”en”> <head> <meta charset=”UTF-8”> <title>名称案例</title> <link rel=”stylesheet” href=”../lib/bootstrap.css”> <script src=”../lib/vue.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> var vm = new Vue({
    el: ‘#app’,
    data: {
    firstname: ‘’,
    lastname: ‘’,
    },
    methods: {},
    computed: { //在computed中,可以定义一些属性,这些属性叫做【计算属性】,计算属性的本质就是一个方法
    // 只不过我们在使用这些计算属性的时候,就是把他们的名称直接当作属性来使用的
    // 并不会把计算属性当作方法去调用
    ‘fullname’: function () {
    // 注意: 计算属性,在引用的时候不要加() ,直接当作普通属性使用就可以了
    // 注意: 只要计算属性 这个 function 内部 所用到的任何data中的数据发生了变化,就会立即重新计算这个计算属性的值 // 注意: 计算属性的求值结果会被缓存,方便下次直接使用,如果计算属性方法中所依赖的任何数据都没有发生过变化
    // 则不会对计算属性求值
    return this.firstname + ‘-‘ + this.lastname
    }
    }
    })

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


    04. webpack的使用


    D:\HTML_code\WEBPACK-STUDY>npm init -y
    Wrote to D:\HTML_code\WEBPACK-STUDY\package.json:

    {
    “name”: “WEBPACK-STUDY”,
    “version”: “1.0.0”,
    “description”: “”,
    “main”: “index.js”,
    “scripts”: {
    “test”: “echo \“Error: no test specified\“ && exit 1”
    },
    “keywords”: [],
    “author”: “”,
    “license”: “ISC”
    }



    D:\HTML_code\WEBPACK-STUDY>npm install jquery -S
    npm notice created a lockfile as package-lock.json. You should commit this file.
    npm WARN WEBPACK-STUDY@1.0.0 No description
    npm WARN WEBPACK-STUDY@1.0.0 No repository field.

    + jquery@3.4.1
    added 1 package from 1 contributor in 1.525s

    D:\HTML_code\WEBPACK-STUDY>webpack .\src\main.js -o .\dist\bundle.js
    Hash: 770190926be334db6609
    Version: webpack 4.41.2
    Time: 2025ms
    Built at: 2019-12-01 18:14:05
    Asset Size Chunks Chunk Names
    bundle.js 87.7 KiB 0 [emitted] main
    Entrypoint main = bundle.js
    [1] ./src/main.js 390 bytes {0} [built]
    + 1 hidden module

    WARNING in configuration
    The ‘mode’ option has not been set, webpack will fallback to ‘production’ for this value. S
    et ‘mode’ option to ‘development’ or ‘production’ to enable defaults for each environment.
    You can also set it to ‘none’ to disable any default behavior. Learn more: https://webpack.
    js.org/configuration/mode/
    //main.js是项目的js入口文件
    // 1. 导入 Jquery
    // import from 是 ES6 中导入模块的方式
    // 由于 ES6 代码太高级 浏览器不能解析,所以这一行 执行会报错
    import $ from ‘jquery’

    $
    (function () {
    $(“li:odd”).css(“backgroundColor”,“lightblue”)
    $(“li:even”).css(“backgroundColor”,function () {
    return “#”+“D97655”
    })
    })

    //webpack 可以做什么?
    //1. webpack 能处理JS文件相互依赖的关系
    //2. webpack 能够处理JS的兼容性的问题,把 高级的 浏览器不识别的语法转为 // 低级的 浏览器能正常识别的语法
    // 命令格式 webpack 要打包的文件路径 -out 打包好后文件的输出路径


    05. webpack最基本的配置

    // 这个配置文件 其实就是一个JS文件,通过Node 中的模块操作,向外暴露了一个配置对象
    const path = require(‘path’)
    module.exports = {
    // 手动指定入口 和 出口
    entry: path.join(dirname,‘./src/main.js’), //入口 ,表示要使用webpack打包那个文件
    output:{ //输出文件相关的配置
    path: path.join(
    dirname,‘./dist’), //指定打包好的文件输出到哪个目录中去
    filename:‘bundle.js’ //指定输出的文件的名称为 bundle.js
    }
    }

    // 当我们在 控制台 直接输入 webpack命令执行的时候, webpack 执行以下几步
    // 1. 首先 webpack发现 我们并没有铜鼓哟命令的形式 指定入口和出口
    // 2. webpack 就回去 项目的根目录查找一个叫做 webpagk.config.js 的配置文件
    // 3. 当找到配置文件后, webpack会去解析执行配置文件,当解析执行之后 就得到了配置文件中导出的配置对象
    // 4. 当webpack 拿到配置对象后, 就拿到了 配置对象中指定的入口 和出口


    webpack**


    06. webpack-dev-server

    1. 要求在本地项目中 安装webpack

    npm install webpack-dev-server -D



    2. 修改 script 引入地址

    3 修改 package.json

    {
    “name”: “WEBPACK-STUDY”,
    “version”: “1.0.0”,
    “description”: “”,
    “main”: “index.js”,
    “scripts”: {
    “test”: “echo \“Error: no test specified\“ && exit 1”,
    “dev”: “webpack-dev-server —open —port 3000 —contentBase src —hot” },
    “keywords”: [],
    “author”: “”,
    “license”: “ISC”,
    “dependencies”: {
    “jquery”: “^3.4.1”,
    “webpack”: “^4.41.2”
    },
    “devDependencies”: {
    “webpack-dev-server”: “^3.9.0”
    }
    }



    4. npm run dev 执行 webpack-dev-server 脚本

    5. 启动 localhost:8080/src

    //main.js是项目的js入口文件
    // 1. 导入 Jquery
    // import from 是 ES6 中导入模块的方式
    // 由于 ES6 代码太高级 浏览器不能解析,所以这一行 执行会报错
    import $ from ‘jquery’

    $
    (function () {
    $(“li:odd”).css(“backgroundColor”,“pink”)
    $(“li:even”).css(“backgroundColor”,function () {
    return “#”+“D97655”
    })
    })

    //webpack 可以做什么?
    //1. webpack 能处理JS文件相互依赖的关系
    //2. webpack 能够处理JS的兼容性的问题,把 高级的 浏览器不识别的语法转为 // 低级的 浏览器能正常识别的语法
    // 命令格式 webpack 要打包的文件路径 -out 打包好后文件的输出路径


    // 使用 webpack-dev-server 这个工具 来实现 自动打包编译功能
    // 1 运行 npm install webpack-dev-server -D 把这个工具安装到项目的本地开放以来
    // 2 安装完毕后 这个工具的用法 和 webpack命令的用法 完全一样 // 3 由于 我们是在 项目中 本地安装的 webpack-dev-server ,所以无法把他当作 脚本命令
    // 在 Terminal中直接运行(只有安装到全局 -g 中的工具才能在终端中正常执行)
    // 4. 注意 : webpack-dev-server 这个工具 如果想正常运行,要求 在本地项目中,必须安装webpack
    // 5. webpack-dev-server 帮我们打包生成的bundle.js文件,并没有存放到实际的物理磁盘上, 而是直接托管到了
    // 电脑的内存中,所以 在根目录中找不到这个打包好的 bundle.js
    // 6. 可以认为 wabpack-dev-server 把打包好的工具,以一种虚拟的形式托管到了 项目的根目录中,与dist src node-moudle 平级


    07. html-webpack-plugin 的两个基本作用

    1. 安装插件

    cnpm install html-webpack-plugin -D


    2. 配置webpack.config.js

    // 这个配置文件 其实就是一个JS文件,通过Node 中的模块操作,向外暴露了一个配置对象
    const path = require(‘path’)

    //导入在内存中生成HTML页面的插件
    //只要是插件,都一定要 放到 plugins 节点中去
    /这个插件的两个作用: 1. 自动在内存中根据指定页面生成内存的页面 2. 自动把打包好的bundle.js追加到页面中去/
    const htmlWebpackPlugin = require(“html-webpack-plugin”)
    module.exports = {
    // 手动指定入口 和 出口
    entry: path.join(dirname,‘./src/main.js’), //入口 ,表示要使用webpack打包那个文件
    output:{ //输出文件相关的配置
    path: path.join(
    dirname,‘./dist’), //指定打包好的文件输出到哪个目录中去
    filename:‘bundle.js’ //指定输出的文件的名称为 bundle.js
    },
    plugins: [ //配置插件的节点
    new htmlWebpackPlugin({
    // 创建一个在 内存中生成HTML 页面插件
    template: path.join(_dirname,‘./src/index.html’), //指定 模板页面,将来会更具指定的页面生成内存中的页面
    filename: “index.html” //指定生成的页面的名称
    })
    ] }

    // 当我们在 控制台 直接输入 webpack命令执行的时候, webpack 执行以下几步
    // 1. 首先 webpack发现 我们并没有铜鼓哟命令的形式 指定入口和出口
    // 2. webpack 就回去 项目的根目录查找一个叫做 webpagk.config.js 的配置文件
    // 3. 当找到配置文件后, webpack会去解析执行配置文件,当解析执行之后 就得到了配置文件中导出的配置对象
    // 4. 当webpack 拿到配置对象后, 就拿到了 配置对象中指定的入口 和出口

    _


    3. 修改index.html内容

    <!DOCTYPE html> <html> <head> <meta charset=”utf-8” /> <title></title>






    </head> <body> <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> </body> </html>

    08. loader-配置处理css样式 的第三方loader

    1. 安装第三方插件

    cnpm install style-loader css-loader -D

    //main.js是项目的js入口文件
    // 1. 导入 Jquery
    // import from 是 ES6 中导入模块的方式
    // 由于 ES6 代码太高级 浏览器不能解析,所以这一行 执行会报错
    import $ from ‘jquery’

    //使用import 语法导入css样式表 import ‘./css/index.css’
    // 注意 webpack默认只能打包处理 js 类型的文件,无法处理其他的非js类型的文件
    // 如果要处理 非 JS 文件,我们需要手动安装一些 合适的第三方 loader 加载器
    //1. 如果想要打包处理 css 文件, 需要安装 cnpm install style-loader css-loader -D
    //2. 打开webpack.config.js 配置文件,在里面新增配置节点 ,叫做 module,它是一个对象, // 然后在这个对象上 有一个 rules 属性,这个rules 属性是一个数组,这个数组中存放了所有第三方 // 文件的匹配和处理规则
    $(function () {
    $(“li:odd”).css(“backgroundColor”,“orange”)
    $(“li:even”).css(“backgroundColor”,function () {
    return “#”+“D97655”
    })
    })

    //webpack 可以做什么?
    //1. webpack 能处理JS文件相互依赖的关系
    //2. webpack 能够处理JS的兼容性的问题,把 高级的 浏览器不识别的语法转为 // 低级的 浏览器能正常识别的语法
    // 命令格式 webpack 要打包的文件路径 -out 打包好后文件的输出路径


    // 使用 webpack-dev-server 这个工具 来实现 自动打包编译功能
    // 1 运行 npm install webpack-dev-server -D 把这个工具安装到项目的本地开放以来
    // 2 安装完毕后 这个工具的用法 和 webpack命令的用法 完全一样 // 3 由于 我们是在 项目中 本地安装的 webpack-dev-server ,所以无法把他当作 脚本命令
    // 在 Terminal中直接运行(只有安装到全局 -g 中的工具才能在终端中正常执行)
    // 4. 注意 : webpack-dev-server 这个工具 如果想正常运行,要求 在本地项目中,必须安装webpack
    // 5. webpack-dev-server 帮我们打包生成的bundle.js文件,并没有存放到实际的物理磁盘上, 而是直接托管到了
    // 电脑的内存中,所以 在根目录中找不到这个打包好的 bundle.js
    // 6. 可以认为 wabpack-dev-server 把打包好的工具,以一种虚拟的形式托管到了 项目的根目录中,与dist src node-moudle 平级


    2. 配置webpack.config.js

    // 这个配置文件 其实就是一个JS文件,通过Node 中的模块操作,向外暴露了一个配置对象
    const path = require(‘path’)

    //导入在内存中生成HTML页面的插件
    //只要是插件,都一定要 放到 plugins 节点中去
    /这个插件的两个作用: 1. 自动在内存中根据指定页面生成内存的页面 2. 自动把打包好的bundle.js追加到页面中去/
    const htmlWebpackPlugin = require(“html-webpack-plugin”)

    module.exports = {
    // 手动指定入口 和 出口
    entry: path.join(dirname, ‘./src/main.js’), //入口 ,表示要使用webpack打包那个文件
    output: { //输出文件相关的配置
    path: path.join(
    dirname, ‘./dist’), //指定打包好的文件输出到哪个目录中去
    filename: ‘bundle.js’ //指定输出的文件的名称为 bundle.js
    },
    plugins: [ //配置插件的节点
    new htmlWebpackPlugin({
    // 创建一个在 内存中生成HTML 页面插件
    template: path.join(_dirname, ‘./src/index.html’), //指定 模板页面,将来会更具指定的页面生成内存中的页面
    filename: “index.html” //指定生成的页面的名称
    })
    ], module: {
    // 这个节点用于配置所有的第三方模块加载器
    rules: [
    //所有第三方模块的匹配规则 {test:/\.css$/, use:[‘style-loader’,‘css-loader’]} //匹配所有以 .css 结尾的文件,配置 处理 .css 文件的第三方loader规则 ]
    } }

    // 当我们在 控制台 直接输入 webpack命令执行的时候, webpack 执行以下几步
    // 1. 首先 webpack发现 我们并没有铜鼓哟命令的形式 指定入口和出口
    // 2. webpack 就回去 项目的根目录查找一个叫做 webpagk.config.js 的配置文件
    // 3. 当找到配置文件后, webpack会去解析执行配置文件,当解析执行之后 就得到了配置文件中导出的配置对象
    // 4. 当webpack 拿到配置对象后, 就拿到了 配置对象中指定的入口 和出口

    _




    09.webpack 中使用url-loader 的使用

    一.处理图片

    1. 安装url-loader

    D:\springbootworkspace\01-springboot-hello\src\main\resources\static\vueDay06>cnpm install
    url-loader file-loader -D


    2. css 文件

    html, body {
    margin: 0;
    padding: 0;
    background-color: palegoldenrod;
    /默认情况下,webpack无法处理css 文件中的 url 地址 不管是 图片还是字体库,只要是url地址,都处理不了/
    background: url(“images/bc.png”);
    background-size: cover; }


    3.web.config.js 配置

    | //webpack 基于node进行构建的,所以webpack的配置文件中 支持合法的node代码 var path = require(“path”)
    //当以命令行形式运行webpack 或 webpack-dev-server时,工具会发现并没有提供要打包的文件的入口和出口文件 // 此时会检查项目根目录中的 webpack.config.js文件 ,根据配置文件进行打包构建
    //在内存中 根据指定的模板页面,生成一份内存中的首页,同时自动把打包好的bundle注入到页面底部 // 如果要配置插件,需要在导出的对象中挂在一个plugins节点
    var htmlWebpackPlugin = require(“html-webpack-plugin”)
    module.exports = {
    entry: path.join(dirname, “./src/main.js”),//入口文件 output: {
    path: path.join(
    dirname, “./dist”),//输出路径 filename: “bundle.js” //指定输出文件的名称 }, plugins: [
    //所有webpack插件的配置节点 new htmlWebpackPlugin({
    template: path.join(_dirname, “./src/index.html”), //指定模板文件路径 filename: “index.html” //设置生成的内存页面名称 })
    ],
    module: {
    // 配置所有第三方loader模块 rules: [
    //第三方模块的匹配规则 {test: /\.css$/, use: [‘style-loader’, ‘css-loader’]}, //处理css文件的loader
    {test: /\.(jpg|png|gif|bmp|jpeg)$/, use: “url-loader?limit=5000”} //处理图片路径的loader
    // limit 给定的值是 图片的大小, 单位是 byte ,如果引用的图片 大于或等于 给定的 limit值 //则 不会被转为base64格式的字符串,如果图片小于给定的limit值,则会被转为base64的字符串_ ]
    }
    }
    | | —- |



    二. 处理字体图标
    1. 导入bootstrap

    cnpm install bootstrap -S


    2. main.js中引入字体文件配置

    // 项目的 js入口文件 console.log(‘ok’)

    import “./index.css”

    /注意: 如果要通过路径的形式去引入 node_modules 中 相关的文件,可以直接省略路径前面的 node_modules这一层目录 直接写 包的名称,后面跟上具体的文件路径/
    // 不写 node_modules这一层目录,默认回去node_modules中查找
    import “bootstrap/dist/css/bootstrap.css”


    3. webpack.config.js中配置

    //webpack 基于node进行构建的,所以webpack的配置文件中 支持合法的node代码 var path = require(“path”)
    //当以命令行形式运行webpack 或 webpack-dev-server时,工具会发现并没有提供要打包的文件的入口和出口文件 // 此时会检查项目根目录中的 webpack.config.js文件 ,根据配置文件进行打包构建
    //在内存中 根据指定的模板页面,生成一份内存中的首页,同时自动把打包好的bundle注入到页面底部 // 如果要配置插件,需要在导出的对象中挂在一个plugins节点
    var htmlWebpackPlugin = require(“html-webpack-plugin”)
    module.exports = {
    entry: path.join(dirname, “./src/main.js”),//入口文件 output: {
    path: path.join(
    dirname, “./dist”),//输出路径 filename: “bundle.js” //指定输出文件的名称 }, plugins: [
    //所有webpack插件的配置节点 new htmlWebpackPlugin({
    template: path.join(_dirname, “./src/index.html”), //指定模板文件路径 filename: “index.html” //设置生成的内存页面名称 })
    ],
    module: {
    // 配置所有第三方loader模块 rules: [
    //第三方模块的匹配规则 {test: /\.css$/, use: [‘style-loader’, ‘css-loader’]}, //处理css文件的loader

    {test: /\.(jpg|png|gif|bmp|jpeg)$/, use: “url-loader?limit=5000”}, //处理图片路径的loader
    // limit 给定的值是 图片的大小, 单位是 byte ,如果引用的图片 大于或等于 给定的 limit值 //则 不会被转为base64格式的字符串,如果图片小于给定的limit值,则会被转为base64的字符串
    {test:/\.(ttf|eot|svg|woff|woff2)/,use:“url-loader”}/这是处理字体文件的loader配置/ _]
    }
    }


    4. html中引入

    <!DOCTYPE html> <html lang=”en”> <head> <meta charset=”UTF-8”> <title>webpack 复习</title>


    </head> <body> <div class=”box”></div> <span class=”glyphicon glyphicon-heart” aria-hidden=”true” style=”width: 50px;height: 50px”></span> </body> </html>

    Day05

    01. webpack中babel配置

    cnpm install babel-core babel-loader babel-plugin-transform-runtime -D
    cnpm install babel-preset-env babel-preset-stage-0 -D


    main.js文件

    // 项目的 js入口文件
    console.log(‘ok’)

    import “./index.css”

    /注意: 如果要通过路径的形式去引入 node_modules 中 相关的文件,可以直接省略路径前面的 node_modules这一层目录 直接写 包的名称,后面跟上具体的文件路径/
    // 不写 node_modules这一层目录,默认回去node_modules中查找
    import “bootstrap/dist/css/bootstrap.css”

    // class 关键字是es6 中提供的新语法,实现ES6 中面向对象编程的方式
    /与 java python 实现面向对象的方式完全一样/
    class Person {
    /使用static关键字,可以定义静态属性/
    //静态属性 可以直接通过类名直接访问的属性
    //实例属性: 只能通过类的实例访问的属性
    static info = {name: “张三”, age: 20}
    }

    // var p1 = new Person()

    //访问 Person.info属性
    console.log(Person.info)

    /在webpack中,只能处理一部分 ES6的新语法,一些更高级的新语法 或者ES7的语法,webpack无法处理/
    /这时候就需要借助第三方的loader 帮助webpack处理这些更高及的语法/
    //1. 通过Babel 可以将高级的语法转换为低级的语法,在webpack中,可以运行如下两套命令,安装两套包来安装Babel相关的功能 // 1.1 第一套: 运行 cnpm install babel-core babel-loader babel-plugin-transform-runtime -D // 1.2 第二套: cnpm install babel-preset-env babel-preset-stage-0 -D //2. 打开webpack 的配置文件,在module 节点下的rules数组中,添加一个新的匹配规则:
    // 2.1 {test:/\.js$/,use:”babel-loader”,exclude:/node_modules/}
    // 2.2 注意: 在配置 babel 的 loader 规则的时候,必须把node_modules目录,通过exclude 选项排除 // 2.2.1 原因1: 如果不排除node_modules,则babel 会把其中的第三方js文件打包编译,消耗资源
    // 2.2.2 原因2: 转换完毕也无法正常运行
    //3. 在项目的根目录中,新建一个叫做 .babelrc 的配置文件,这个配置文件属于json格式,所以必须符合
    //json规范,例如 不能用注释,字符串必须用双引号等
    // 3.1 在 .babelrc 写如下配置:
    // {
    // “presets”:[“env”,”stage-0”], // “plugins” : [“transfrom-runtime”]
    // }
    // 可以理解为 语法 和 插件


    .babelrc 文件

    {
    “presets”: [“env”,“stage-0”],
    “plugins”: [“transform-runtime”]
    }


    webpack.config.js 文件

    //webpack 基于node进行构建的,所以webpack的配置文件中 支持合法的node代码 var path = require(“path”)
    //当以命令行形式运行webpack 或 webpack-dev-server时,工具会发现并没有提供要打包的文件的入口和出口文件
    // 此时会检查项目根目录中的 webpack.config.js文件 ,根据配置文件进行打包构建

    //在内存中 根据指定的模板页面,生成一份内存中的首页,同时自动把打包好的bundle注入到页面底部
    // 如果要配置插件,需要在导出的对象中挂在一个plugins节点
    var htmlWebpackPlugin = require(“html-webpack-plugin”)
    module.exports = {
    entry: path.join(dirname, “./src/main.js”),_//入口文件
    _output: {
    path: path.join(
    dirname, “./dist”),//输出路径
    _filename: “bundle.js”
    //指定输出文件的名称
    }, plugins: [
    //所有webpack插件的配置节点
    new htmlWebpackPlugin({
    template: path.join(__dirname, “./src/index.html”),
    //指定模板文件路径
    filename: “index.html” //设置生成的内存页面名称
    })
    ],
    module: {
    // 配置所有第三方loader模块 rules: [
    //第三方模块的匹配规则 {test: /\.css$/, use: [‘style-loader’, ‘css-loader’]}, //处理css文件的loader

    {test: /\.(jpg|png|gif|bmp|jpeg)$/, use: “url-loader?limit=5000”}, //处理图片路径的loader
    // limit 给定的值是 图片的大小, 单位是 byte ,如果引用的图片 大于或等于 给定的 limit值 //则 不会被转为base64格式的字符串,如果图片小于给定的limit值,则会被转为base64的字符串

    {test:/\.(ttf|eot|svg|woff|woff2)/,use:“url-loader”},/这是处理字体文件的loader配置/

    {test:/\.js$/,use:“babel-loader”,exclude:/node_modules/}/配置Babel来转换高级的ES语法/ _]
    }
    }


    问题解决

    # 第一套包,相当于babel的转换工具
    npm i babel-core babel-loader babel-plugin-transform-runtime -D
    # 第二套包,babel的语法
    npm i babel-preset-env babel-preset-stage-0 -D

    ## 安装第一个包出现报警告 babel-loader@8.0.5 requires a peer of @babel/core@^7.0.0 原因如下:
    # babel-loader@8.x is the Webpack integration used for Babel 7.x. Babel 7.x has moved all packages from a babel-prefix to the @babel npm scope.
    # 解决办法就是 将babel-loader@8.x降级为babel-loader@7.x
    # npm uninstall babel-loader -D
    # npm i babel-loader@7 -D
    # 或者一开始就直接为babel-loader指定到@7版本
    # npm i babel-core babel-loader@7 babel-plugin-transform-runtime -D

    删除 node_modules
    在 package.json 中配置适合的版本
    npm install 重新安装


    02. 在页面中使用render函数渲染组件

    <!DOCTYPE html> <html lang=”en”> <head> <meta charset=”UTF-8”> <title>在页面中渲染基本的组件</title> <script src=”../lib/vue.js”></script> </head> <body> <div id=”app”>
    </div> <script> var login = {
    template:

    这是登录组件


    }
    var vm = new Vue({
    el: “#app”,
    data: {},
    methods: {},
    render: function (createElements) { //createElements 是一个方法,调用它能够把指定的 组件模板渲染为 // HTML结构 var html = createElements(login)
    return html
    //注意 这里 return 的结果 会替换页面中 el 指定的容器, 即 id 为app的容器
    } })
    </script> </body> </html>


    03. webpack中使用vue

    1. main.js中

    //这是入口文件
    // console.log(“ok”)

    //如何在 webpack构建的项目中,使用Vue进行开发
    // 复习:
    // 在普通网页中 , 如何使用vue
    //1. 使用 script 标签, 引入 vue的包
    //2. 在index页面中,创建一个 id 为 app 的div 容器
    //3. 通过 new Vue 得到一个vm 实例



    //在webpack中 尝试使用vue:
    //从 node_modules导入vue这个包

    /注意 : 在webpack中使用 import Vue from ‘vue’导入 Vue的构造函数,功能不完整 只提供了 runtime-only的方式,没有提供网页的方式*/
    import Vue from ‘vue’

    // 分析: 包的查找规则:
    /
    1. 找项目更目录中有没有node_modules的文件夹 2. 在node_modules中根据包名找对应的vue文件夹 3. 在 vue文件夹中 找一个叫做 package.json的包配置文件 4. 在 package.json文件中,查找 main 属性, 【main指定了这个包在被加载(导入)时候的入口文件】 */

    // import Vue from ‘../node_modules/vue/dist/vue.js’ //方式 1
    // 修改 package.json配置文件
    var vm = new Vue({
    el:‘#app’,
    data:{
    msg:“123”
    }

    })



    2. webpack.config.js中配置

    //webpack 基于node进行构建的,所以webpack的配置文件中 支持合法的node代码 var path = require(“path”)
    //当以命令行形式运行webpack 或 webpack-dev-server时,工具会发现并没有提供要打包的文件的入口和出口文件
    // 此时会检查项目根目录中的 webpack.config.js文件 ,根据配置文件进行打包构建

    //在内存中 根据指定的模板页面,生成一份内存中的首页,同时自动把打包好的bundle注入到页面底部
    // 如果要配置插件,需要在导出的对象中挂在一个plugins节点
    var htmlWebpackPlugin = require(“html-webpack-plugin”)
    module.exports = {
    entry: path.join(dirname, “./src/main.js”),//入口文件
    output: {
    path: path.join(
    dirname, “./dist”),//输出路径
    filename: “bundle.js” //指定输出文件的名称
    }, plugins: [
    //所有webpack插件的配置节点
    new htmlWebpackPlugin({
    template: path.join(_dirname, “./src/index.html”), //指定模板文件路径
    filename: “index.html” //设置生成的内存页面名称
    })
    ],
    module: {
    // 配置所有第三方loader模块 rules: [
    //第三方模块的匹配规则 {test: /\.css$/, use: [‘style-loader’, ‘css-loader’]}, //处理css文件的loader

    {test: /\.(jpg|png|gif|bmp|jpeg)$/, use: “url-loader?limit=5000”}, //处理图片路径的loader
    // limit 给定的值是 图片的大小, 单位是 byte ,如果引用的图片 大于或等于 给定的 limit值 //则 不会被转为base64格式的字符串,如果图片小于给定的limit值,则会被转为base64的字符串

    {test:/\.(ttf|eot|svg|woff|woff2)/,use:“url-loader”},/这是处理字体文件的loader配置/

    {test:/\.js$/,use:“babel-loader”,exclude:/node_modules/}/配置Babel来转换高级的ES语法/
    ]
    },resolve:{
    alias:{
    //修改 vue 被导入时 包的路径
    _“vue$” : “vue/dist/vue.js”
    } }
    }

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

    1. 配置第三方loader

    cnpm install vue-loader vue-template-compiler -D
    npm i vue-loader-plugin -S


    2. 编写 .vue文件

    <template>
    <div> <h1>这是登录组件,使用.vue文件定义</h1> </div> </template>
    <script> / 业务逻辑 /
    </script>
    <style> / css样式 /
    </style>


    3. 编写 main.js

    //这是入口文件
    // console.log(“ok”)

    //如何在 webpack构建的项目中,使用Vue进行开发
    // 复习:
    // 在普通网页中 , 如何使用vue
    //1. 使用 script 标签, 引入 vue的包
    //2. 在index页面中,创建一个 id 为 app 的div 容器
    //3. 通过 new Vue 得到一个vm 实例


    //在webpack中 尝试使用vue:
    //从 node_modules导入vue这个包

    /注意 : 在webpack中使用 import Vue from ‘vue’导入 Vue的构造函数,功能不完整 只提供了 runtime-only的方式,没有提供网页的方式*/

    import Vue from ‘vue’

    // 分析: 包的查找规则:
    /
    1. 找项目更目录中有没有node_modules的文件夹 2. 在node_modules中根据包名找对应的vue文件夹 3. 在 vue文件夹中 找一个叫做 package.json的包配置文件 4. 在 package.json文件中,查找 main 属性, 【main指定了这个包在被加载(导入)时候的入口文件】 /

    // import Vue from ‘../node_modules/vue/dist/vue.js’ //方式 1
    // 修改 package.json配置文件

    /
    var login = {
    template: “

    这是login组件,时使用网页中的形式创建出来的模板


    }*/

    // 1. 导入login 组件
    import login from ‘./login.vue’ // 默认 .webpack 无法打包 .vue文件,需要安装相关的loader
    // cnpm install vue-loader vue-template-compiler -D
    // 在 配置文件中新增loader配置项{test:”\.vue$”,use:”vue-loader”}
    // 还需要再装一个
    //npm i vue-loader-plugin -S
    var vm = new Vue({
    el: ‘#app’,
    data: {
    msg: “123”
    },
    components: {
    // login
    }, _/render: function (createElements) { //在webpack中,如果想要通过 vue ,把一个组件放到页面中去展示 // vm实例中的 render 可以实现 return createElements(login)
    }
    /
    //render 可以简写为 /参数列表和函数体之间加 => ,只有一个参数可以省略括号/
    / 只有一个方法,省略{},默认会return , 去掉return关键字/
    _render: c => c(login) })


    4. 配置webpack.config.js

    //webpack 基于node进行构建的,所以webpack的配置文件中 支持合法的node代码 var path = require(“path”)
    //当以命令行形式运行webpack 或 webpack-dev-server时,工具会发现并没有提供要打包的文件的入口和出口文件
    // 此时会检查项目根目录中的 webpack.config.js文件 ,根据配置文件进行打包构建

    //在内存中 根据指定的模板页面,生成一份内存中的首页,同时自动把打包好的bundle注入到页面底部
    // 如果要配置插件,需要在导出的对象中挂在一个plugins节点
    var htmlWebpackPlugin = require(“html-webpack-plugin”)

    // 配置vue-loader
    const VueLoaderPlugin = require(‘vue-loader/lib/plugin’)

    module.exports = {
    entry: path.join(dirname, “./src/main.js”),//入口文件
    output: {
    path: path.join(
    dirname, “./dist”),//输出路径
    filename: “bundle.js” //指定输出文件的名称
    }, plugins: [
    //所有webpack插件的配置节点
    new htmlWebpackPlugin({
    template: path.join(_dirname, “./src/index.html”), //指定模板文件路径
    filename: “index.html” //设置生成的内存页面名称
    }),
    new VueLoaderPlugin()
    //配置vue-loader ],
    module: {
    // 配置所有第三方loader模块 rules: [
    //第三方模块的匹配规则 {test: /\.css$/, use: [‘style-loader’, ‘css-loader’]}, //处理css文件的loader

    {test: /\.(jpg|png|gif|bmp|jpeg)$/, use: “url-loader?limit=5000”}, //处理图片路径的loader
    // limit 给定的值是 图片的大小, 单位是 byte ,如果引用的图片 大于或等于 给定的 limit值 //则 不会被转为base64格式的字符串,如果图片小于给定的limit值,则会被转为base64的字符串

    {test: /\.(ttf|eot|svg|woff|woff2)/, use: “url-loader”},/这是处理字体文件的loader配置/

    {test: /\.js$/, use: “babel-loader”, exclude: /node_modules/},/配置Babel来转换高级的ES语法/

    {test: /\.vue$/, use: “vue-loader”} /这是处理.vue文件的loader/ ]
    }, resolve: {
    alias: {
    //修改 vue 被导入时 包的路径
    _“vue$”: “vue/dist/vue.js”
    }
    }
    }



    总结-webpack 结合vue 使用的方式

    /总结 webpack使用__vue
    1. 安装vue的包 : cnpm i vue -S
    2. 由于 在webpack中推荐使用.vue件模板文件定义组件,所以需要安装能解析个文件的__loader
    cnpm i vue-loader vue-template-complier -D
    3. main.jsvue 块__ import Vue from ‘vue’
    4. 一个 .vue 尾的件,其中件由三部分成,template,script,style
    * 5.
    使用 import login from ‘./login.vue’ 6. vm 例,__ var vm = new Vue({el:’#app’,render:c=>c(login)})
    7. 面中 id app div元素,作vm_例要控制的区域
    /
    **


    05. exprot default 和 export 的 使用方式

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

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

    //在 ES6 中, 使用export default 和 export 向外暴露成员:
    export default {
    name: “张三”,
    age: 20
    }
    // 注意 : export default 向外暴露的成员可以使用 任意的变量来接收
    // 注意: 在一个模中, export default 只允许__向外暴露一次

    // 注意: 在一个模块中,可以同时使用 export default 和 export 向外暴露成员
    export var title = “小星星”
    export var content
    = “哈哈哈”
    // 注意: 使用export 向外暴露的成员只能使用{} 的形式来接收,这种形式 叫做【按需导出】
    // 注意: 如果 某些成员,我们在 import 的时候 不需要,则可以不在 {} 中定义 // 注意 : 使用 export 导出的成员 必须严格按照导出时候的名称 来使用 { } 按需接收 // 如果想 换名称接收 ,可以使用 as 起别名


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


    main.js中接收如下

    import m1 from “./test.js”
    console
    .log(m1)

    // export 向外暴露的成员只能通过{变量名} 形式接收,且 接收的变量名 必须和
    import {_title _as title123,content} from “./test”;
    console.log(title123+“—“+content)


    06. 结合webpack使用vue-router

    1. 安装路由

    cnpm install vue-router -S


    2. main.js中

    import Vue from “vue”

    //1. 导入vue-router包
    import VueRouter from “vue-router”
    //2. 手动安装 VueRouter
    _Vue.use(VueRouter)
    //导入 account组件
    import account from “./main/Account.vue”
    import
    goodList from “./main/GoodList.vue”

    //3. 创建路由对象 var router = new VueRouter({
    routes:[
    // account goodList
    {path:‘/account’,component:account},
    {path: ‘/goodlist’,component: goodList}
    ]
    })

    //导入app组件
    import app from ‘./App.vue’

    var
    vm = new Vue({
    el: “#app”,
    render: c => c(app),
    // render会把 el指定的容器中所有的内容覆盖,所以不能直接写到el所控制的元素中
    router //4.将路由对象挂在到vue实例上 })

    //注意: App 组件 是通过 VM 实例的 render 函数渲染出来的,render函数如果要渲染组件,渲染出来的组件只能放到el:”#app”\
    // 所指定的元素中
    // Account 和 GoodsList 组件,是通过路由匹配监听到的,所以这两个组件只能展示到属于
    // 路由的 中_


    3. App.vue中

    <template> <div> <h1>这是App组件</h1>
    <router-link to=”/account”>Account</router-link> <router-link to=”/goodList”>Goodlist</router-link>
    <router-view></router-view> </div> </template>
    <script>
    </script>
    <style>
    </style>

    07. 结合webpack实现children 子路由

    main.js中代码

    import Vue from “vue”

    //1. 导入vue-router包 import VueRouter from “vue-router”

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

    //导入 account组件 import account from “./main/Account.vue”
    import
    goodList from “./main/GoodList.vue”
    import
    login from “./subcom/login.vue”
    import
    register from “./subcom/register.vue”;
    //3. 创建路由对象 var router = new VueRouter({
    routes:[
    // account goodList
    {path:‘/account’,component:account,children:[ {path:‘login’,component:login},
    {path: ‘register’,component: register} ]},
    {path: ‘/goodlist’,component: goodList}
    ]
    })


    //导入app组件 import app from ‘./App.vue’

    var
    vm = new Vue({
    el: “#app”,
    render: c => c(app),
    // render会把 el指定的容器中所有的内容覆盖,所以不能直接写到el所控制的元素中 router //4.将路由对象挂在到vue实例上 })

    //注意: App 组件 是通过 VM 实例的 render 函数渲染出来的,render函数如果要渲染组件,渲染出来的组件只能放到el:”#app”\
    // 所指定的元素中 // Account 和 GoodsList 组件,是通过路由匹配监听到的,所以这两个组件只能展示到属于 // 路由的 中_



    父组件 Account.vue中代码

    <template> <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>
    </script> <style>
    </style>

    08 style中的lang属性和scoped属性

    1. scoped :子组件中,不添加scoped属性会将css样式应用到全局

    <template> <div> <h3>这是Account的登录子组件</h3> </div> </template>
    <script> export default {
    name: “”
    }
    </script>
    <style scoped> div{
    color: red;
    }
    </style>


    2. 使用其他 语言时设置lang属性


    <style scoped> body div{
    font-style: italic;
    }
    </style>


    09. 抽离路由模块


    1. router中代码

    //1. 导入vue-router包 import VueRouter from “vue-router”
    import
    Vue from “vue”

    //导入 account组件 import account from “./main/Account.vue”
    import
    goodList from “./main/GoodList.vue”
    import
    login from “./subcom/login.vue”
    import
    register from “./subcom/register.vue”;
    //2. 手动安装 VueRouter
    _Vue.use(VueRouter)

    //3. 创建路由对象 **export var _router = new VueRouter({
    routes:[
    // account goodList
    {
    path:‘/account’,component:account,children:[
    {
    path:‘login’,component:login},
    {
    path: ‘register’,component: register}
    ]},
    {
    path: ‘/goodlist’,component**: goodList}
    ]
    })




    2. main.js中代码

    import Vue from “vue”


    //导入app组件 import app from ‘./App.vue’
    import
    {router} from “./router.js”
    var
    vm = new Vue({
    el: “#app”,
    render: c => c(app), // render会把 el指定的容器中所有的内容覆盖,所以不能直接写到el所控制的元素中 router //4.将路由对象挂在到vue实例上 })

    //注意: App 组件 是通过 VM 实例的 render 函数渲染出来的,render函数如果要渲染组件,渲染出来的组件只能放到el:”#app”\
    // 所指定的元素中 // Account 和 GoodsList 组件,是通过路由匹配监听到的,所以这两个组件只能展示到属于 // 路由的


    Day06

    1. mintUI 安装

    npm install mint-ui -S


    2. 引入全部组件

    import Vue from “vue”
    import Mint from “mint-ui”
    Vue.use(Mint)


    3. 引入部分组件

    import {Cell,Checklist } from “minu-ui”
    Vue.component(Cell,name,Cell);
    Vue.component(Checklist,name,Checklist);


    2. MintUI 按钮的使用

    <template> <div> <h1>这是App组件</h1>
    <mt-button type=”danger”>default</mt-button> <mt-button icon=”more”>更多</mt-button> <mt-button icon=”back”>back</mt-button>



    <router-link to=”/account”>Account</router-link> <router-link to=”/goodList”>Goodlist</router-link>
    <router-view></router-view> </div> </template>
    <script>
    </script>
    <style>
    </style>


    3. MintUI Toast 组件的使用

    app.vue中

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

    <mt-button type=”danger” @click=”show>default</mt-button> <mt-button icon=”more”>更多</mt-button> <mt-button icon=”back”>back</mt-button>

    <router-link to=”/account”>Account</router-link> <router-link to=”/goodList”>Goodlist</router-link>
    <router-view></router-view> </div> </template>
    <script> // 导入Toast 组件 (js组件需要手动导入)
    import {Toast} from ‘mint-ui’;
    export default {
    data() {
    return {}
    }, methods: {
    show() {
    // Toast(“提示信息”)
    return Toast({
    message: “这是消息”,
    duration: -1, //显示时间- ? ms,如果是-1则弹出之后不消失
    position: “top”, //顶部弹出
    iconClass: “glyphicon glyphicon-heart”, //设置图标的类(来自bootstrap)
    className: “mytoast”//自定义Toast的样式,需要自己提供一个类名 })
    },
    getList() { //模拟获取列表的一个Ajax方法
    let instance = this.show(); setTimeout(() => {
    //在获取数据之前,立即弹出 Toast 提示用户正在加载数据
    //三秒过后,数据获取后把Toast移除 _instance.close()
    }, 3000)
    //延时器,模拟三秒延时 _}
    }, created() {
    this.getList() }
    }
    </script>
    <style>

    </style>


    main.js中

    import Vue from “vue”


    //导入app组件
    import app from ‘./App.vue’
    import
    {router} from “./router.js”


    //导入 bootstrap 样式
    import “bootstrap3/dist/css/bootstrap.css”
    //导入自定义样式
    import “./css/app.css”
    //导入Mint-ui 导入所有的MIntUI 组件
    import MintUI from ‘mint-ui’ //导入mint-ui样式,可以省略 node_modules 这层目录
    import “mint-ui/lib/style.css”

    //把 Mint-ui 安装到vue中 , 把所有的组件注册为全局的组件
    _Vue.use(MintUI)


    var vm = new Vue({
    el: “#app”,
    render: c => c(app),
    // render会把 el指定的容器中所有的内容覆盖,所以不能直接写到el所控制的元素中
    **_router //4.将路由对象挂在到vue实例上
    })

    //注意: App 组件 是通过 VM 实例的 render 函数渲染出来的,render函数如果要渲染组件,渲染出来的组件只能放到el:”#app”\
    // 所指定的元素中
    // Account 和 GoodsList 组件,是通过路由匹配监听到的,所以这两个组件只能展示到属于
    // 路由的

    **


    04. 按需导入

    1. 安装babel-plugin-component

    cnpm install babel-plugin-component -D


    2. 修改.babelrc

    | {
    “presets”: [
    “env”,
    “stage-0”
    ],
    “plugins”: [
    “transform-runtime”,
    [
    “component”,
    [
    {
    “libraryName”: “mint-ui”,
    “style”: true
    }
    ]
    ] ]
    } | | —- |


    3.main.js中

    | //按需导入MINT-UI组件
    import {Button} from “mint-ui”
    _// 使用Vue,component注册 按钮组件
    // Vue.component(“myBtn”,Button)
    _Vue.component(Button.name,Button) | | —- |


    4. app.vue中

    <mt-button type=”primary”>这是按需导入的button</mt-button>

    05.MUI 的 使用

    类似于bootstrap,import “路径” 后直接使用即可

    06.Promise 学习

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

    /

    //创建具体的异步操作,使用function指定具体的异步操作的函数3
    var promise = new promise(function () {
    //function内部写的就是具体的异步操作
    })
    /

    const fs = require(“fs”)

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

    //需求: 调用时才执行异步操作 // 返回文件读取到的内容
    function getFileByPath(filePath) {
    var promise = new Promise(function (resolve, reject) { //异步操作成功和失败之后的回调 _fs._readFile(filePath, ‘utf-8’, (err, dataStr) => {
    / if(err) throw err
    console.log(dataStr)
    /
    if (err) return reject(err) //如果失败了,执行reject并结束函数,如果没有失败 执行resolve
    _resolve(dataStr)
    })
    })
    return promise
    //返回一个promise,这样就可以给function传递resolve和reject参数 }

    var p = getFileByPath(“./test.txt”)
    p.then(function (data) {
    **_console
    .log(data + “成功”)
    },
    function (err) {
    console.log(err.message + “失败”)
    })

    _/

    执行步骤: 1.内存中生成了getFileByPath方法 2.调用了这个方法,返回了一个p对象(promise),注意: 这个时候可能new Promise中的方法还没有执 3.p.then 为p对象指定了两个参数,分别是resolve,reject [异步操作]
    4.p.then 执行完成之后,执行 promise中的function
    /_
    //改造后 function getFileByPath(filePath) {
    return new Promise(function (resolve, reject) { //异步操作成功和失败之后的回调 _fs._readFile(filePath, ‘utf-8’, (err, dataStr) => {
    / if(err) throw err
    console.log(dataStr)
    /
    if (err) return reject(err) //如果失败了,执行reject并结束函数,如果没有失败 执行resolve
    _resolve(dataStr)
    })
    })
    }

    getFileByPath(“./test.txt”).then(function (data) {
    **_console
    .log(data + “成功”)
    },
    function (err) {
    console.log(err.message + “失败”**)
    })


    07. 使用promise解决 回调地狱问题

    const fs = require(“fs”)
    //使用promise解决 回调地狱
    //改造后
    function getFileByPath(filePath) {
    return new Promise(function (resolve, reject) { //异步操作成功和失败之后的回调 _fs._readFile(filePath, ‘utf-8’, (err, dataStr) => {
    / if(err) throw err
    console.log(dataStr)
    /
    if (err) return reject(err) //如果失败了,执行reject并结束函数,如果没有失败 执行resolve
    _resolve(dataStr)
    })
    })
    }

    //需求 : 先读取文件1,再读取文件2,在读取文件3
    // 注意: 通过.then指定回调函数的时候,成功的回调函数必须传 // 但是失败的回调函数可以不传
    //读取文件1
    getFileByPath(“./test.txt”).then(function (data) {
    **_console
    .log(data)
    //读取文件2
    return getFileByPath(“./test2.txt”) })
    .then(
    function (data) {
    //操作的是 读取文件2
    console.log(data) //读取文件3
    return getFileByPath(“./test3.txt”) })
    .then(
    function (data) {
    //操作的读取文件3
    console**.log(data)
    })


    08. promise中捕获错误的两种方式

    const fs = require(“fs”)
    //使用promise解决 回调地狱
    //改造后
    function getFileByPath(filePath) {
    return new Promise(function (resolve, reject) { //异步操作成功和失败之后的回调 _fs._readFile(filePath, ‘utf-8’, (err, dataStr) => {
    / if(err) throw err
    console.log(dataStr)
    /
    if (err) return reject(err) //如果失败了,执行reject并结束函数,如果没有失败 执行resolve
    _resolve(dataStr)
    })
    })
    }

    //需求 : 先读取文件1,再读取文件2,在读取文件3
    // 注意: 通过.then指定回调函数的时候,成功的回调函数必须传 // 但是失败的回调函数可以不传
    //读取文件1
    getFileByPath(“./test.txt”).then(function (data) {
    **_console
    .log(data)

    //读取文件2
    return getFileByPath(“./test2.txt”)
    })
    .then(
    function (data) {
    //操作的是 读取文件2
    console.log(data)
    //读取文件3
    return getFileByPath(“./test3.txt”)
    },
    function (err) {
    console.log(err.message)
    console.log(“这是失败的结果”)
    return getFileByPath(“./test3.txt”) //不影响后续代码的执行 })
    .then(
    function (data) {
    //操作的读取文件3
    console.log(data)
    })

    _//当有这样的需求: // 前面的promise执行失败了,也不影响后续的promise的执行 // 此时,可以为每个promise 通过 .then 指定一个失败的回调
    //需求2: 如果后面的promise 依赖于前面的promise 执行的结果 // 如果前面的执行失败,后面就不用继续执行的时候 // 一旦有 报错,则立即终止 promise 的执行 //读取文件1
    _getFileByPath(
    “./test.txt”).then(function (data) {
    console.log(data)

    //读取文件2
    return getFileByPath(“./test2.txt”)
    })
    .then(
    function (data) {
    //操作的是 读取文件2
    console.log(data)
    //读取文件3
    return getFileByPath(“./test3.txt”)
    },
    function (err) {
    console.log(err.message)
    console.log(“这是失败的结果”)
    return getFileByPath(“./test3.txt”) //不影响后续代码的执行 })
    .then(
    function (data) {
    //操作的读取文件3
    console.log(data)
    })
    .catch(
    function (err) { //任何一个失败了都会进入catch里面进行捕获和处理 console.log(err.message**)
    })



    时间格式化的时候可以再pojo中加下面的注解

    @JsonFormat(pattern = “yyyy-MM-dd HH:mm:ss”, timezone = “GMT+8”)public java.sql.Timestamp getAddTime() {
    return addTime;
    }

    分页

    getUserComments() {
    this.$axios.get(‘/userComments/‘ + this.newsId + “/“ + this.pageIndex).then(res => {
    if (res.status === 200) {
    // this.userComments = res.data.message
    //每当获取新评论数据的时候,老数据不清空
    this.userComments = this.userComments.concat(res.data.message) } else {
    Toast(“加载数据失败,请检查网络连接”)
    }
    }).catch(function (err) {
    Toast(“数据交互发生错误,请联系管理员”)
    console.log(err)
    })

    post请求 需要用qs转换

    //配置全局请求头 axios.defaults.baseURL = http://localhost:10111; // 关键步骤–填写后台请求统一的地址 axios.defaults.headers.post[‘Content-Type’] = ‘application/x-www-form-urlencoded’; axios.defaults.withCredentials = true;
    //响应时间限制 // axios.defaults.timeout = 10000

    //配置post请求
    import qs from ‘qs’

    Vue.prototype.qs = qs;
    this.$axios.post(“/userComments/postComment/“ + this.newsId, this.qs.stringify({
    content: this.msg.trim()
    })).then(res => {
    console.log(res)
    })


    VueX

    概念

    vue配套的 公共数据管理工具,可以把一些共享的数据保存到vuex中,方便整个程序中的任何组件直接获取或者修改公共数据

    VueX是为了保证组件之间共享数据而诞生的,如果组件之间有要共享的数据,可以直接挂在到VueX中 而不必通过父子组件传值。(相当于一个 公共作用域) 如果组件之间的数据不需要共享,那就不需要放到vuex中

    安装 何使用

    npm install vue-x –save
    import Vuex from ‘vuex’
    Vue.use(Vuex)


    const store = new Vuex.Store({
    state:{ //类似于组件中的 data ,用来存储数据
    count:0
    },
    mutations:{ //类似于组件中的 methods,专门用来操作state中的数据
    increment(state){
    state.count
    }
    }

    })


    /配置vuex的步骤 1. npm i vuex -S
    2. 导入/
    import _Vuex _from ‘vuex’
    /3. 注册vuex到Vue中/
    _Vue.use(**_Vuex
    )
    /4. new Vuex.Store() 实例,得到一个数据仓储对象/
    var store = new Vuex.Store({
    state: {
    //类似于组件中的data,专门用来存储数据 // 如果在组件中想要访问store中的数据,只能通过 // this.$store.state
    // 只要挂在到了 vm上, 任何组件都能使用store来存储数据
    count: 0
    },
    mutations: {
    //类似于组件中的methods
    //注意: 如果要操作 store 中的state 值,只能调用mutatious中提供的方法才能操作对应的数组 //不推荐直接操作state 中的数据,以防发生数据紊乱 _increment(state, param) {
    //第一个参数固定式state
    _state.
    count += param
    /注意 在motations 的参数列表中最多支持两个参数/ /多参数可以传入 对象/数组的形式/ }
    /注意:如果组件想要调用 mutations中的方法,只能使用 this.$store.commit(‘方法名’)/
    // 有点类似于 this.$emit(‘父组件中的方法名’)类似
    },
    getters: {
    _//注意 getters 只负责 对外提供数据,不负责 修改数据 _optCount:
    function (state) { /第一个参数同样必须是state/ return ‘当前的数据是’ + this.count
    }
    }
    })


    var vm = new Vue({
    el: “#app”,
    data: {},
    methods: {},
    render: c => c(app),
    router, _//1.4 挂在路由对象到vm实例上 _beforeCreate() {
    document.querySelector(‘body’).setAttribute(‘style’, ‘background-color:white’*)
    }, store_/
    5.将vuex挂在到路由实例上*/ _})



    数组存储到localStorage中
    localStorage.setItem(‘car’,JSON.stringify(数据 ))
    数据取出

    //直接写在.js中即可
    var car = JSON.parse(localStorage.getItem(‘car’) || [])