本文最后更新于:2025年2月11日 晚上
为了应付一些课设的要求,就去B站找了个培训机构 的视频学习了一下Vue2,这是当时记的笔记
vue基础 MVVM MVC
M:model V:view C:controller
MVVM
M:model V:view VM:view model
VM的实现原理 view model中定义了一个Observer(观察者)
ViewModel能够观察到数据的变化,并对视图对应的内容进行更新
ViewModel能够监听到视图数据的变化,并能够通知数据发生变化
——MVVM通过VM实现了双向数据绑定
一.vue快速开始 1.获得vue的cdn文件 https://www.bootcdn.cn/vue/2.6.12/
2.在页面中使用vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="utf-8" > <title > Title</title > </head > <body > <div id ="app" > 欢迎你!{{name}} </div > </body > <script src ="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.js" > </script > <script > new Vue ({ el : '#app' , data : { name : 'jens' } }); </script > </html >
3.vue对象 new Vue({
el:’’ // 该对象绑定在哪个div上
data:{
} // 提供数据,里面存放键值对
})
二.差(插)值表达式 差值表达式是用在html被绑定的元素中的。目的是通过差值表达式来获取vue对象中的属性和方法。
插值表达式不能作为html标签中的属性的值,转到v-bind
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <body > <div id ="app" > 我是一位{{major}}程序员 {{[0,1,2,3,4][3]}}<br /> {{ {name:'jens', age:20}.name }} {{ sayHi() }} </div > </body > <script src ="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.js" > </script > <script > new Vue ({ el : '#app' , data : { major : 'java' }, methods : { sayHi : function ( ) { alert ('Hello' ) } } }) </script >
三.vue关键字 1.v-model:双向数据绑定 将标签中的value值与vue实例中的data属性值进行绑定
1 2 3 4 5 6 7 8 9 10 11 12 13 <div id ='app' > 请输入你的专业:<input type ='text' v-model ='major' /> <br > ==============================<br > 我是一位 {{major }} 程序员 </div > new Vue({ el: '#app', data: { major: 'java' } })
2.v-on:事件绑定 通过配合具体的事件名来触发绑定的vue实例中的函数
v-on:事件名 =’函数名() ‘
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <div id='app' > 请输入你的专业:<input type ='text' v-on :input ="changeMajor" /><br> </div> new Vue({ el : '#app' , data: { major: 'java' }, methods: { sayHi: function () { alert('Hello' ) }, changeMajor: function () { console.log ('changed' ) } } })
event 内置参数对象 event.target.value 在响应函数中,可以指明使用event作为参数,该对象表示当前事件,可以通过event.target.value来获得当前事件对象的value的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <input type ='text' v-on :input ="changeMajor" />new Vue({ el : '#app' , data: { major: 'java' }, methods: { changeMajor: function (event) { // 效果为在input 标签中输入后动态改变major的值 this.major = event.target.value } } })
this的用法 this表示当前vue对象,可以通过this来调用当前对象的属性和方法
v-on的简写 @ v-on:input=”” ==> @input=””
3.v-bind:属性绑定 <… v-bind:属性名 =”vue中的键名 “ …>
1 2 3 4 5 6 7 8 <a v-bind:href="link" >百度</a> new Vue ({ el: '#app' , data: { link: 'https:/www.baidu.com' } })
v-bind 简写 : 1 <a v-bind:href ="link" >百度</a> ===> <a :href ='link' >
4.v-once 指明该标签中的差值表达式只获取一次数据。之后的数据变化不影响该表达式的值。
1 2 3 4 <p v-once > {{link }} </p > <input type ="text" v-model ="link" >
5.v-html 和 v-text v-html会将vue中的属性的值作为html的元素来使用
v-text会将vue中的属性的值只作为纯文本来使用
1 <span v-html='mylink'></span><span v-text='mylink'></span>new Vue({ el: '#app', data: { link: 'https:/www .baidu.com', mylink: '<a href="https:/www.baidu.com" >baidu</a>' } })
四.vue中的事件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 <div id ="app" > {{ count > 10 ? '大于10' : '小于10' }} <br > {{count }} <br > <button type ="button" @click ="addbtn()" > 增加</button > <button type ="button" @click ="relsbtn()" > 减少</button > <input type ="text" v-model ="mystep" /> <br > <p @mousemove ="mymo" > {{x }} <br > {{y }} <span @mousemove.stop > 停止鼠标移动事件</span > </p > </div > new Vue({ el: '#app', data: { count: 0, mystep: 1, x: 0, y: 0 }, methods: { addbtn: function () { this.count += this.mystep - 0 }, relsbtn: function () { this.count -= this.mystep - 0 }, mymo: function (event) { this.x = event.clientX this.y = event.clientY console.log(event) }, mystopmo: function (event) { event.stopPropagation() } } })
在事件处理程序中调用 event.preventDefault()
或 event.stopPropagation()
是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。
为了解决这个问题,Vue.js 为 v-on
提供了事件修饰符 。之前提过,修饰符是由点开头的指令后缀来表示的。
.stop
.prevent
.capture
.self
.once
.passive
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <a v-on:click.stop ="doThis" > </a > <form v-on:submit.prevent ="onSubmit" > </form > <a v-on:click.stop.prevent ="doThat" > </a > <form v-on:submit.prevent > </form > <div v-on:click.capture ="doThis" > ...</div > <div v-on:click.self ="doThat" > ...</div >
在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为 v-on
在监听键盘事件时添加按键修饰符:
1 <input v-on:keyup.enter ="submit" >
你可以直接将 KeyboardEvent.key
暴露的任意有效按键名转换为 kebab-case 来作为修饰符。
1 <input v-on :keyup.page -down="onPageDown" >
在上述示例中,处理函数只会在 $event.key
等于 PageDown
时被调用。
五.Vue改变内容 差值表达式 1 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Title</title > </head > <body > <div id ="app" > {{count}}<br > {{result}}<br > <button type ="button" @click ="addbtn(2)" > 增加</button > </div > </body > <script src ="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.js" > </script > <script > new Vue ({ el : '#app' , data : { count : 0 , result : "?" }, methods : { addbtn : function (step ) { this .count += step this .result = this .count > 10 ? "大于10" : "小于10" } } }) </script > </html >
computed 计算属性 什么是计算属性 计算属性是一个属性 ,其次,这个属性有计算 的能力,这里计算的方式为函数;具体来说,他就是一个将函数结果缓存起来的属性。
计算属性与方法的区别 计算属性更像是一个data,是静态的结果;方法是一个函数,是动态的
1 <div id='app' > {{getCurrentTime ()}}<br> {{getCurrentTime1}}</div>new Vue ({ el : '#app' , methods : { getCurrentTime : function ( ) { return new Date () } }, computed : { getCurrentTime1 : function ( ) { return new Date () } } })
watch 监控属性 通过在watch里给属性绑定函数,当属性的值发生变化时,该函数就会被调用。调用时可以接收两个参数,第一个参数是属性改变后的值,第二个参数是属性改变前的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <body > <div id ='app' > {{title}} <input type ="text" v-model ="title" > </div > </body > <script src ="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.js" > </script > <script > new Vue ( { el : '#app' , data : { title : "hello" }, watch : { title : function (newValue, oldValue ) { console .log ("title changed" ) console .log (newValue + '::' + oldValue) } } }) </script >
六.Vue 改变样式 1.class的动态绑定 通过给html元素的class属性绑定vue中的属性值,得到样式的动态绑定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" /> <title > Title</title > <style > .mydiv { width : 400px ; height : 220px ; background-color : gray; } .red { background-color : red; } .yellow { background-color : yellow; } .green { background-color : green; } </style > </head > <body > <div id ="app" > <div class ="mydiv" v-bind:class ="{red:temp}" > </div > <div class ="mydiv" > </div > <div class ="mydiv" > </div > <br /> <button type ="button" @click ="temp=!temp" > 点击</button > </div > </body > <script src ="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.js" > </script > <script > new Vue ({ el : "#app" , data : { temp : false } }); </script > </html >
2.加入computed 通过computed返回一个json对象,对象里放着多个键值对
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <body > <div id ='app' > <div class ="mydiv" v-bind:class ="{red:temp}" > </div > <hr > <div :class ="myClassStyle" class ="mydiv" > </div > <hr > <div class ="mydiv" > </div > <br > <button type ="button" @click ="temp=!temp" > 点击</button > </div > </body > <script > new Vue ({ el : '#app' , data : { temp : false }, computed : { myClassStyle : function ( ) { return { red : this .temp , myWidth : this .temp } } } }) </script >
3.通过v-model来改变样式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <div :class ="mycolor" class ="mydiv" > </div > <br > <input type ="text" v-model ="mycolor" > <script > new Vue ({ el : '#app' , data : { temp : false , mycolor : 'green' }, computed : { myClassStyle : function ( ) { return { red : this .temp , myWidth : this .temp } } } }) </script >
4.使用v-model绑定多个样式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <style > .red { background-color : red; } .myWidth { width : 450px ; } </style > <body > <div :class ="[mycolor,mywidth]" class ="mydiv" > </div > </body > <script > new Vue ({ el : '#app' , data : { temp : false , mycolor : 'green' , mywidth : 'myWidth' , }, }) </script >
5.在内嵌的css样式绑定Vue的键 style引用了Vue中的内容,因此是一个键值对,所以需要大括号;js中对象的键是不能出现”backgroud-color“这种形式的,应该改成backgroundColor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <div :style ="{backgroundColor: mycolor}" class ="mydiv" > </div > <hr /> <div :style ="myStyle" class ="mydiv" > </div > <hr /> <div :style ="[myStyle,{height:mw*2+'px'}]" class ="mydiv" > </div > <script > new Vue ({ el : "#app" , data : { temp : false , mycolor : "green" , mywidth : "myWidth" , mw : 450 }, computed : { myClassStyle : function ( ) { return { red : this .temp , myWidth : this .temp }; }, myStyle : function ( ) { return { backgroundColor : this .mycolor , width : this .mw * 2 + "px" }; }, }, }); </script >
七.Vue中的语句 1.分支语句
v-if
v-else-if
v-else
v-show : 实际上是让该元素的display属性为none,起到隐藏的效果。所以性能更好。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <body > <div id ="app" > <div v-if ="temp" > if</div > <div v-else-if ="temp1" > else-if</div > <div v-else ="temp2" > else</div > <button type ="button" @click ="temp=!temp" > 点我</button > </div > </body > <script > new Vue ({ el : '#app' , data : { temp : false , temp1 : false , temp2 : true , } }) </script >
2.循环语句
首先定义数据源,然后通过v-for遍历数据源,再通过差值表达式输出数据
只取值的for: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <body > <div id ="app" > <ul > <li v-for ="a in args" > {{a}} </li > </ul > </div > </body > <script > new Vue ({ el : '#app' , data : { args : [1 , 2 , 3 , 4 , 5 , 6 ], } }) </script >
带索引的for: v-for=”(value,key,index) in object”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <body > <div id ="app" > <ul > <li v-for ="(a,i) in args" :key ="i" > {{i}}--{{a}}</li > </ul > </div > </body > <script > new Vue ({ el : '#app' , data : { args : [1 , 2 , 3 , 4 , 5 , 6 ], } }) </script >
遍历对象: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <body > <div id ="app" > <ul > <li v-for ="(value,key,index) in student" > {{index}}--{{key}}--{{value}}</li > </ul > </div > </body > <script src ="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.js" > </script > <script > new Vue ({ el : '#app' , data : { args : [1 , 2 , 3 , 4 , 5 , 6 ], student : { name : 'xiaoming' , age : 20 } } }) </script >
遍历对象数组: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <body > <div id ="app" > <ul > <li v-for ="student in students" > <span v-for ="(value,key,index) in student" > {{index}}--{{key}}--{{value}}----</span > </li > </ul > </div > </body > <script src ="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.js" > </script > <script > new Vue ({ el : '#app' , data : { args : [1 , 2 , 3 , 4 , 5 , 6 ], students : [{ name : 'xiaoming' , age : 20 }, { name : 'xiaowang' , age : 18 }] } }) </script >
Vue进阶 1.基础开发 一.Vue实例 1.Vue对象操作 1.可以通过一个Vue对象操作另一个Vue对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <script > var v2 = new Vue ({ el : '#app2' , methods : { changeOtherVueTitle : function ( ) { v1.title = "Hello Vue" }, m1 : function ( ) { v1.toUpCase () } }, }); var v1 = new Vue ({ el : '#app1' , data : { title : "hello" }, methods : { toUpCase : function ( ) { this .title = this .title .toUpperCase () } }, computed : { toLowerCase : function ( ) { return this .title .toLowerCase () } }, watch : { title : function (n, o ) { console .log (n + ':' + o) } } }); </script >
2.Vue对象操作另一个Vue对象的内容,维度有两个,操作属性、操作方法 3.Vue的实例属性 直接通过“对象.属性”的方式调用的属性,是来自于data或computed中的属性,但是Vue对象中的el,data等等这些键也称为属性,这些属性就是Vue对象中的实例属性。
1 var data = { arg1 : "arg1 value" }var v2 = new Vue ({ el : "#app" , data : data,})
实例属性还能这么调用:v1.$data.title 相当于v1.title
2.实例属性 ref 在Vue中往往使用ref属性来代替id属性的使用。那么就可以快速的通过调用ref的值来获得页面中的某个元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <body > <div id ="app2" > <button type ="button" ref ="mybtn1" @click ="showVueObject" > 点击</button > <button type ="button" ref ="mybtn2" @click ="showVueObject" > 点击</button > </div > </body > <script > var v2 = new Vue ({ el : "#app2" , methods : { showVueObject : function ( ) { this .$refs .mybtn1 .innerHTML = "hello" ; }, }, }); </script >
3.动态绑定Vue实例到页面中 实现了页面元素和Vue对象的动态绑定,之前都是通过el的方式来绑定;也可以通过mount实例属性进行绑定
1 2 3 4 5 6 7 8 9 <body > <div id ="app" > </div > </body > <script > var v1 = new Vue ({ template : "<h1>hello</h1>" , }); v1.$mount("#app" ); </script >
二.Vue组件 1.Vue组件 组件化:可以将Vue对象作为一个组件,反复使用
要想实现组件化,需要在页面中注册组件:关于注册的方式有两种,分别是全局注册和本地注册
1.注册组件(全局注册) 1 Vue.component("组件名",{vue对象})
2.使用组件 在被Vue绑定了的html元素中才能使用组件。如果一个div没有被绑Vue绑定,那么这个div中不能使用之前注册组件
1 2 3 4 5 6 7 <body > <div id ="app" > <model1 > </model1 > </div > </body > <script src ="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.js" > </script > <script > Vue .component ("model1" , { template : "<div>{{title}}<button type='button' @click='btnfn'>点击</button></div>" , data : function ( ) { return { title : "hello" } }, methods : { btnfn : function ( ) { alert ("hello" ) } } }) new Vue ({ el : "#app" , }) </script >
3.作为组件的Vue对象的特点 特点1 Vue.component("组件名",{vue对象})
,这个Vue对象和之前的Vue对象是有的data实例属性的写法是有区别的
单独的Vue对象 $\Downarrow$
1 new Vue({ data:{ name:"xm", age:29}})
作为组件的Vue对象 $\Downarrow$
1 { data : function () { return { name :"xm" , age:29 } }}
特点2 这种组件中template的写法
template是将内容展现在页面上的一个键,他的值是一个字符串
注意:template里必须有且只能有一个根元素
1 template: "<div > {{title }} <button type ='button' @click ='btnfn' > 点击</button > </div > "
2.Vue的生命周期
3.Vue组件的本地(局部)注册 vue的组件全局注册后,在html页面的每一个被Vue绑定的div中都能使用
vue的组件本地注册后,只能在对应vue实例绑定的div中使用
1 2 3 4 5 6 7 8 9 <body > <div id ="app" > <model11 > </model11 > </div > <hr /> <div id ="app1" > <model2 > </model2 > </div > </body > <script src ="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.js" > </script > <script > var model1 = { template : "<div>{{title}}<button type='button' @click='btnfn'>点击</button></div>" , data : function ( ) { return { title : "hello" } }, methods : { btnfn : function ( ) { alert ("hello" ) } } } new Vue ({ el : "#app" , components : { "model11" : model1 } }) new Vue ({ el : "#app1" , components : { "model2" : model1 } }) </script >
三.Vue开发模式 1.vue-cli脚手架 2.vue文件的组成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 <template> <div id="app"> <img src="./assets/logo.png" /> <h1>{{ msg }}</h1> <h2>Essential Links</h2> <ul> <li><a href="https://vuejs.org" target="_blank">Core Docs</a></li> <li><a href="https://forum.vuejs.org" target="_blank">Forum</a></li> <li> <a href="https://chat.vuejs.org" target="_blank">Community Chat</a> </li> <li><a href="https://twitter.com/vuejs" target="_blank">Twitter</a></li> </ul> <h2>Ecosystem</h2> <ul> <li><a href="http://router.vuejs.org/" target="_blank">vue-router</a></li> <li><a href="http://vuex.vuejs.org/" target="_blank">vuex</a></li> <li> <a href="http://vue-loader.vuejs.org/" target="_blank">vue-loader</a> </li> <li> <a href="https://github.com/vuejs/awesome-vue" target="_blank" >awesome-vue</a > </li> </ul> </div></template > <script> export default { name: "app", data() { return { msg: "Welcome to Your Vue.js App" }; }, }; </script> <style lang="scss"> app { font-family: "Avenir", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } h1, h2 { font-weight: normal; } ul { list-style-type: none; padding: 0; } li { display: inline-block; margin: 0 10px; } a { color: #42b983; } </style>
1.在App.vue组件中使用另一个vue组件 1) 全局注册 在main.js中,通过import和Vue.component配合,来将一个.vue文件注册成为一个标签。该标签可以在整个项目中使用
1 2 3 4 import Header from './components/Header.vue' import Content from './components/Content.vue' import bottom from './components/bottom' Vue .component ('MyHeader' , Header )Vue .component ("MyContent" ,Content )Vue .component ("MuBottom" , bottom)
2) 本地注册 在组件的内部去注册另外一个组件,成为一个标签,这个标签只在该组件的内部使用,而不能在其他组件内使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <template> <div id="app"> <Myheader></Myheader> <MyContent></MyContent> <MyBottom></MyBottom></div ></template> <script> import Header from "./components/Header" import Content from "./components/Content" import Bottom from "./components/bottom" export default { name: 'app', components: { "Myheader": Header, "MyContent": Content, "MyBottom": Bottom } } </script>
2.各组件之间的参数传递 1.父传子 通过子组件的props,来指明可以接收的参数,父组件通过在标签中写明参数的键值对来传递参数
props
写法
props:[参数列表]
props:[‘MyProps1’,’MyProps2’,…]
props:{参数对象}
props: {
‘MyProps1’:{ // 参数名
type:String, // 类型
required:true, // 是否是必须传递的参数
default:’…’ // 默认值
},
…
}
子组件设参props
1 <script > export default { name : "Content" , props: ["MyTitle" ] } </script >
父组件使用子组件并传参
1 <MyContent :MyTitle="msg" ></Mycontent>
2.子传父
以事件发射的方式来实现子传父的效果
在子组件中,使用this.$emit("键","值)
在父组件中,在子组件的标签中使用@键="msg=$event"
其中$event就能得到发射的值,msg是父组件中vue的属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <template > <div id ="app" > <MyContent :MyTitle ="msg" @newName ="msg=$event" > </Mycontent > </div > </template > <script > import Content from "./components/Content" export default { name : 'app' , data ( ) { return { msg : "Hello vue" } }, components : { "MyContent" : Content }, methods : { FCfn : function (m ) { this .msg = m } } } </script > <style > </style >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 <template > <div > 商品列表 {{MyTitle }} <button type ="button" @click ="doClick" > 点击</button > </div > </template > <script > export default { name : "Content" , props : { 'MyTitle' : { type : String , required : true , default : 'xx' } }, methods : { doClick ( ) { this .$emit('newName' , 'hello, js' ); } } } </script > <style > </style >
四.Vue中发送Ajax请求 1) 安装axios vue-axios 1 2 npm install --save axios vue-axios npm install
2) 在main.js中引入 1 2 3 4 import axios from 'axios' import VueAxios from 'vue-axios' Vue .use (VueAxios , axios)
3) 发送ajax请求
发送get请求
1 2 3 4 5 6 7 this.axios({ method: 'get', url: 'http://localhost:8090/regist?mail='+this.mail+'&password='+this.password }) .then(function(response){ console.log(response.data) })
发送post请求
1 2 3 4 5 6 7 8 9 10 11 this .axios({ method: 'post' , url: 'http://localhost:8090/regist' , data :{ mail: this .mail, password: this .password } }) .then(function(response){ console.log(response.data ) })
4) 解决跨域问题 跨域是浏览器对javascript的一种安全限制,浏览器的页面去访问其他服务器上的资源时,就会出现跨域。同源策略,指的是协议、域名、端口完全相同才是安全的
在spring-mvc.xml中加入如下代码
1 2 3 4 5 6 7 <mvc:cors> <mvc:mapping path="/**" allowed-origins="http://domain1.com,http://domain2.com" allowed-methods="GET , PUT , OPTIONS , DELETE , PUT , PUSH" allowed-headers="Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With" allow-credentials="true" /> </mvc:cors>
在spring-web项目中的解决办法 在注解为@SpringBootConfiguration
的config文件中重写addCorsMappings方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 @SpringBootConfiguration public class MyWebConfigurer implements WebMvcConfigurer { @Bean public LoginInterceptor getLoginInterceptor () { return new LoginInterceptor (); } @Override public void addInterceptors (InterceptorRegistry registry) { registry.addInterceptor(getLoginInterceptor()).addPathPatterns("/**" ).excludePathPatterns("/index.html" ); } @Override public void addCorsMappings (CorsRegistry registry) { registry.addMapping("/**" ) .allowedOrigins("*" ) .allowedMethods("*" ) .allowedHeaders("*" ); } }
5) 解决axios无法传递data中的参数问题 原因:默认情况下发送axios时请求头中的内容类型为:
1 Content -Type :application/json ;charset=UTF -8
而实际服务端需要的是:
1 Content -Type :application/x-www-form-urlencoded
因此,使用axios的qs内置库中的方法进行内容类型的转换
1 2 3 4 5 6 7 8 9 import Qs from 'qs' this .axios({ method:'post' , url:'http://locahost:8080/Login' , transformRequest:[function(data ){ return Qs.stringify(data ) }], })
6) 路由 在Vue中的路由,能够在一个Vue组件中实现其他组件的切换
也就是说,可以通过路由模块,将指定的组件显示在路由视图中。
1.安装路由模块 1 npm install vue-router -s
2.设计路由界面 创建components文件夹,文件夹内分别创建user、Home组件
1 2 3 4 5 <template> <div> user </div> </template>
1 2 3 4 5 <template> <div> Home </div> </template>
3.创建静态路由表 在src下创建routes.js
1 2 3 4 5 6 7 import Home from '@/components/Home.vue' import User from '@/components/user/user.vue' export const routes = [ {path :'/' , component :Home }, {path :'/user' , component :User } ]
4.引入路由模块并使用 在main.js中引入路由模块并使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import Vue from 'vue' import App from './App.vue' import VueRouter from 'vue-router' import {routes} from './routes' Vue .use (VueRouter ); const router = new VueRouter ({ routes :routes })new Vue ({ el : '#app' , router, render : h => h (App ) })
5.使用
1 2 3 4 5 6 7 8 9 10 <template> <div class="container"> <div class="row"> <div class="col-xs-12 col-sm-8"> <h1>Routing</h1> <router-view></router-view> </div> </div> </div> </template>
改变url,发现<router-view></router-view>
中的内容发生改变
向router实例中添加mode属性
“hash”: url带# 适用于调试模式
“history”: url不带#
6.链接路由的实现 创建Header.vue
1 2 3 4 5 6 <template> <ul class="nav nav-pills"> <router-link to="/" tag="li" active-class="active" exact><a>Home</a></router-link> <router-link to="/user" tag="li" active-class="active"><a>User</a></router-link> </ul> </template>
修改App.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <template> <div class="container"> <div class="row"> <div class="col-xs-12 col-sm-8"> <h1>Routing</h1> <Home></Home> <router-view></router-view> </div> </div> </div> </template> <script> import Home from './components/Header.vue' export default{ components:{'Home':Home} } </script>
e.g.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 <template> <div id="app"> <div class="container"> <div class="row"> <ul class="nav nav-tabs"> <li role="presentation"> <router-link to="/Home">首页</router-link> </li> <li role="presentation"> <router-link to="/Products">商品列表</router-link> </li> </ul> </div> <div class="row" id="rv"> <router-view></router-view> </div> </div> </div> </template> <script> export default { name: 'app', data() { return { } }, } </script> <style> #rv { border: 1px soid red; } </style>
7.路由之间的参数传递 Header.vue传入参数
1 2 3 4 5 6 <template> <ul class="nav nav-pills"> <router-link to="/" tag="li" active-class="active" exact><a>Home</a></router-link> <router-link to="/user/10" tag="li" active-class="active"><a>User</a></router-link> </ul> </template>
路由表:router.js
1 2 3 4 export const routes = [ {path:'/', component:Home}, {path:'/user/:id', component:User} ]
修改user.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <template> <div> <div>user</div> <p>userId:{{id}}</p> </div> </template> <script> export default{ data(){ return{ id:this.$route.params.id } } } </script>
设置子路由并监听可以刷新同一父路由下的参数值的变化 6) 路由之间跳转的方式 1. <router-link>
通过HTML中的路由链接<router-link to="路由地址">
进行跳转
1 2 3 <li role ="presentation" > <router-link to ="/Products/1" > 手机</router-link > </li >
2.通过js实现路由跳转 this.$router.push("/Products/1")
1 2 3 4 5 6 7 8 9 10 11 12 <tempate>... <button type ="button" @click="btnfn" >点击</button>... </template>... methods: { btnfn() { this.$router.push("/Products/1" ) } }
7.scoped:Vue中组件样式表的作用范围 如果vue组件中的style标签没有带上scoped属性,那么这个style的样式将会作用在整个页面中,而不是当前子组件中
8.资源打包 dist目录
五. webpack 1.创建工程 1 2 3 4 5 6 7 8 9 10 11 npm init webpack myvuedemo ? Project name myvuedemo ? Project description A Vue.js project ? Author Jens <1587198543 @qq.com> ? Vue build standalone ? Install vue-router? No ? Use ESLint to lint your code? No ? Set up unit tests No ? Setup e2e tests with Nightwatch? No ? Should we run `npm install` for you after the project has been created? (recommended) no
2.安装依赖 需要vue-router
、element-ui
、axios
、sass-loader
、node-sass
四个插件
1 2 3 4 5 npm install vue-router --save-dev npm i element-ui -S npm install --save axios vue-axios npm install sass-loader node-sass --save-dev npm install //安装依赖
3.配置路由 1)创建路由表 在src下创建router文件夹,里面创建index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import Vue from 'vue' import VueRouter from 'vue-router' import Login from '../views/Login.vue' Vue .use (VueRouter );export default new VueRouter ({ routes : [ { path : '/Login' , name : 'Login' , component : Login } ] })
2)在main.js中配置路由表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import Vue from 'vue' import App from './App' import VueRouter from 'vue-router' import router from './router' Vue .use (VueRouter )Vue .config .productionTip = false new Vue ({ el : '#app' , router, components : { App }, template : '<App/>' })
3)在App.vue中创建路由视图 1 2 3 4 5 <template> <div id="app"> <router-view></router-view> </div> </template>
4)在项目中使用element-ui 官方指南
完整引入 在 main.js 中写入以下内容:
1 2 3 4 5 6 7 8 9 10 11 import Vue from 'vue' ;import ElementUI from 'element-ui' ;import 'element-ui/lib/theme-chalk/index.css' ;import App from './App.vue' ;Vue .use (ElementUI );new Vue ({ el : '#app' , render : h => h (App ) });
以上代码便完成了 Element 的引入。需要注意的是,样式文件需要单独引入。
五.嵌套路由(子路由) 在路由显示的组件内部,又嵌套着路由,称为子路由
1.配置路由表 修改路由js文件,在对应父路由下添加children
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import Vue from 'vue' import VueRouter from 'vue-router' import Login from '../views/Login.vue' import Home from '../views/Home.vue' import ProductList from '.......' Vue .use (VueRouter );export default new VueRouter ({ routes : [ { path : '/Login' , name : 'Login' , component : Login }, { path : '/Home' , name : 'Home' , component : Home , children :[ { path : '/productlist' , name : 'Productlist' , component : ProductList } ] } ] })
2.使用嵌套路由 1 <router-link to ="/productlist" > 商品列表</router-link >
六.路由的重定向 直接调用另一个已配置好的路由对象即可
1 2 3 4 5 6 7 8 9 10 11 routes: [ { path : '/Login' , name: 'Login' , component: Login }, { path : '/Logout' , redirect: '/Login' } ]
七.传参的两种方式 `
路由钩子 router hook
beforeRouteEnter
:在进入路由前执行
beforeRouteLeave
:在离开路由前执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 export default { props : ['id' ], name : "UserProfile" , beforeRouteEnter : (to, from , next ) => { console .log ("准备进入个人信息页" ) next ( console .log ("进入到目标页面之后调用的函数" ) ) }, beforeRouteLeave : (to, from , next ) => { console .log ("准备离开个人信息页" ) next () } }
八.Mock数据 easy mock官方网站已下线
2.vue-element-admin 1.路由和侧边栏 整个项目的侧边栏是通过路由表动态生成的,可以调整路由表中的内容来改变侧边栏的内容
具体参考官方文档
官方文档
1) 改变侧边栏标题 修改src/router/index.js,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 { path : '/example' , component : Layout , redirect : '/example/table' , name : 'Example' , meta : { title : 'Example' , icon : 'el-icon-s-help' }, children : [ { path : 'table' , name : 'Table' , component : () => import ('@/views/table/index' ), meta : { title : 'Table' , icon : 'table' } }, { path : 'tree' , name : 'Tree' , component : () => import ('@/views/tree/index' ), meta : { title : 'Tree' , icon : 'tree' } } ] },