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 H1BIG 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>
|
---|
14. v-if 和 v-show的使用
<!DOCTYPE html>这是用v-if控制的元素这是v-show控制的元素<!—方法只有一句话可以不在method中声明 —> |
---|
Day2
01. 品牌案例
<!DOCTYPE html> {{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> |
---|
后台代码为
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 |
---|
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.js中导入vue 模块__ 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’) || [])