一个简单的Vue项目的创建
- 创建一个UserList.vue组件
- 在App.vue中使用该组件
- 使用组件的第一步,导入组件
- 使用组件的第二部,申明这个组件
- 使用组件的第三步:引用组件
结果:
事件和插值语法
<template>
<div><!-- template只允许有一个唯一的孩子 --><h1>这是一个一级标题</h1><div>{{ username }}</div><div>性别{{ sex }} , 年龄{{ age }}</div><button @click="btnClick1">点我触发事件</button><hr><ul><li v-for="(user,index) of userList" :key="user.id">{{ index }}----{{ user.username }}</li></ul></div>
</template><script>export default { name: 'UserList',//名字是可以随便写的data(){return{username:'ZhangSan',sex:'男',age:18,userList:[{id:1,username:'ZhangSan',password:'123'},{id:2,username:'LiSi',password:'456'},{id:3,username:'WangWu',password:'789'}]}},methods:{btnClick1(){console.log("Hello Vue");}}}
</script>
结果:
ref属性
<!--ref属性的作用就是找组件对象这个对象是一个js对象
--><!-- 给h1添加一个ref="h1" -->
<h1 ref="h1">这是一个一级标题</h1>methods:{btnClick1(){var h1Element=this.$refs.h1console.log("找到的组件是"+h1Element.innerText)}
}
props
接收参数
- App.vue
<template>
<div id="app"><!-- 使用组件的第三步:引用组件 --><user-list name="ZhangSan" :age="18" title="个人信息"></user-list> </div>
</template><script>// 使用组件的第一步,导入组件import UserList from './components/UserList.vue';export default {name: 'App',//使用组件的第二部,申明这个组件components: {UserList}}
</script>
- UserList.vue
<template>
<div><h1>{{ title }}</h1><h1>{{ age }}</h1><h1>{{ name }}</h1></div>
</template><script>export default { name: 'UserList',//名字是可以随便写的data(){return{}},//第一种方式:数组式接收数据//props:["name","title","age"]//第二种方式:对象式// props:{// name:String,// age:Number,// title:String// }//第三种方式props:{name:{type:String,required:true},age:{type:Number,requestd:true},title:{type:String,required:true}}}
</script>
scoped
添加到style中,只有当前组件生效
<template>
<div><h1>{{ title }}</h1><h1>{{ age }}</h1><h1>{{ name }}</h1></div>
</template><script>export default { name: 'UserList',//名字是可以随便写的data(){return{}},//第一种方式:数组式接收数据//props:["name","title","age"]//第二种方式:对象式// props:{// name:String,// age:Number,// title:String// }//第三种方式props:{name:{type:String,required:true},age:{type:Number,requestd:true},title:{type:String,required:true}}}
</script>
<style scoped>div{color: aqua;}
</style>
结果:
localstorage和sessionstorage
<template>
<div><button @click="saveLocalStorage">向localstorage中存数据</button><br><br><button @click="deleteLocalStorage">向localstorage中删除数据</button><br><br><button @click="getLocalStorage">向localstorage中获取数据</button><br><br><hr><button @click="saveSessionStorage">向sessionstorage中存数据</button><br><br><button @click="deleteSessionStorage">向sessionstorage删除数据</button><br><br><button @click="getSessionStorage">向sessionstorage获取数据</button><br><br></div>
</template><script>export default { name: 'BrowerStorage',methods:{saveLocalStorage(){//向LocalStorage存数据localStorage.setItem("key1","val1")},deleteLocalStorage(){//LocalStorage删除数据localStorage.removeItem("key1")},getLocalStorage(){//获取LocalStorage数据var val = localStorage.getItem("key1")console.log(val)},saveSessionStorage(){//向SessionStorage存数据sessionStorage.setItem("key2","val2")},deleteSessionStorage(){//删除SessionStorage数据sessionStorage.removeItem("key2")},getSessionStorage(){//获取SessionStorage的数据var val = sessionStorage.getItem("key2")console.log(val)}}}
</script>
全局事件总线
- 在main.js中安装全局事件总线
import Vue from 'vue'
import App from './App.vue'Vue.config.productionTip = falsenew Vue({render: h => h(App),//生命周期的第一个钩子函数beforeCreate() {Vue.prototype.$bus = this //安装全局事件总线},}).$mount('#app')
- 在userList.vue中进行监听传过来的消息
<template>
<div>我喜欢的语言是:{{ language }}</div>
</template><script>export default { name: 'UserList',//名字是可以随便写的data(){return{language:''}},mounted(){//监听传递过来的消息this.$bus.$on("changeName",(newtext)=>{this.language=newtext;})},beforeDestroy(){this.$bus.$off ("changeName");}}
</script>
<style scoped>div{font-family: 楷体;font-size: 30px;}
</style>
- 在userSchool.vue中发送数据
<template>
<div><button @click="btnClick">点击查看</button></div>
</template><script>export default { name: 'UserSchool',//名字是可以随便写的methods:{btnClick(){//向某一个频道发送数据this.$bus.$emit("changeName","Java")}}}
</script>
结果:
代理服务器的配置和Axios的请求发送
什么是跨域
如何解决跨域问题
- 在服务器端写一个过滤器,将响应头设置为可信赖
- 在Vue端设置代理服务器
- 给整个tomcat设置允许跨域 实际的操作也是设置相应资源可信赖
代理服务器的配置(vue.config.js)
- 在vue.config.js中配置
module.exports = {assetsDir: 'static',productionSourceMap: false,devServer: {proxy: {'/api':{ target:'http://127.0.0.1:9090',changeOrigin:true,pathRewrite:{'/api':''}}}}
}
Axios的请求发送
- 请求发送第一步:导包
- 客户端发送请求(不带参数的GET请求)
- 服务器端响应
package com.wz.practice.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {private Integer id;private String username;private String password;
}
package com.wz.practice.servlet;import com.alibaba.fastjson.JSON;
import com.wz.practice.pojo.User;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;@WebServlet(urlPatterns = "/users")
public class UserServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("utf-8");String username = req.getParameter("username");String password = req.getParameter("password");System.out.println("获取到的数据是:username:"+username+"password"+password);//向客户端返回json格式的数据User user = new User(1, "用户名数据", "密码数据");String data = JSON.toJSONString(user);//向客户端返回数据resp.setContentType("text/html;charset=utf-8");PrintWriter writer = resp.getWriter();writer.write(data);writer.flush();writer.close();}
}
结果:
- 带参数的GET请求
ProxyAxios.vue
<template>
<div><button @click="btnClick1">发送get请求不带参数 </button><br><br><button @click="btnClick2">发送get请求带参数 </button><br><br><button @click="btnClick3">发送post请求不带参数</button><br><br><button @click="btnClick4">发送post请求带参数 </button><br><br></div>
</template><script>export default { name: 'ProxyAxios',methods:{btnClick1(){//发送get请求不带参数this.$axios.get("/api/users").then(response=>{var val = response.data;console.log("获取到的数据是:"+val)},error=>{console.log("失败"+error.message)})},btnClick2(){//发送get请求带参数this.$axios.get("/api/users",{params:{username:"ZhangSan",password:"123"}}).then(response=>{var val = response.data;console.log("获取到的数据是:"+val)},error=>{console.log("失败"+error.message)})},btnClick3(){},btnClick4(){}}}
</script>
结果:
- POST请求不带参数
- POST请求带参数
插槽slot
基本使用
- 在userList.vue中定义一个slot
<template>
<div><h1>这里是userList的页面</h1><!-- 在这里可以定义一个插槽,插槽就是占位符 --><slot>这里就是插槽要显示内容的地方</slot></div>
</template><script>export default { name: 'UserList',//名字是可以随便写的data(){return{language:''}},}
</script>
<style scoped>div{font-family: 楷体;font-size: 30px;}
</style>
- 在App.vue中使用
<template>
<div id="app"><user-list><div>插槽的具体使用者</div></user-list></div></template><script>// 使用组件的第一步,导入组件import UserList from './components/UserList.vue';export default {name: 'App',//使用组件的第二部,申明这个组件components: {UserList }}
</script>
结果:
具名插槽
<template>
<div><h1>这里是userList的页面</h1><!-- 在这里可以定义一个插槽,插槽就是占位符 --><slot name="slot1">这里就是插槽要显示内容的地方</slot><hr><slot name="slot2">这是第二个插槽</slot></div>
</template><script>export default { name: 'UserList',//名字是可以随便写的data(){return{language:''}},}
</script>
<style scoped>div{font-family: 楷体;font-size: 30px;}
</style>
<template>
<div id="app"><user-list><div slot="slot1">插槽的具体使用者AAAA</div><div slot="slot2">插槽的具体使用者BBBB</div></user-list></div></template><script>// 使用组件的第一步,导入组件import UserList from './components/UserList.vue';export default {name: 'App',//使用组件的第二部,申明这个组件components: {UserList }}
</script>
结果:
路由
路由是控制页面跳转的
- 导包
- 编写main.js
- HomePage.vue
<template>
<div style="background-color: pink;"><h1>这里是Home页面</h1><hr><div class="row"><div class="col-xs-2 col-xs-offset-2"><div class="list-group"><!-- Vue中借助router-link标签实现路由的切换 --><router-link class="list-group-item" active-class="active" to="/about">About</router-link> <router-link class="list-group-item" active-class="active" to="/message">Message</router-link></div></div></div><!-- 这个div主要是内容展示 --><router-view></router-view></div>
</template><script>export default { name: 'HomePage'}
</script>
<style scope>div{font-family: 楷体;font-size: 30px;}
</style>
- AboutPage.vue
<template>
<div style="width: 100%; height: 200px; background: skyblue;">这是About页面</div>
</template><script>export default { name: 'AboutPage',data(){return{language:''}},}
</script>
<style scoped>div{font-family: 楷体;font-size: 30px;}
</style>
- MessagePage.vue
<template>
<div style="width: 100%; height: 200px; background: rosybrown;">这是Message页面</div>
</template><script>export default { name: 'MessagePage'}
</script>
<style scoped>div{font-family: 楷体;font-size: 30px;}
</style>
- App.vue
<template>
<div id="app"><home-page></home-page></div>
</template><script>// 使用组件的第一步,导入组件import HomePage from './components/HomePage.vue';export default {name: 'App',//使用组件的第二部,申明这个组件components: {HomePage}}
</script>
结果:
多级路由
需求:在Message页面中增加两个按钮,点击之后,在Message页面中显示内容
- DetailPage.vue
<template>
<div style="width: 100%; height: 200px; background: yellowgreen;">这是Detail页面</div>
</template><script>export default { name: 'DetailPage',data(){return{language:''}},}
</script>
<style scoped>div{font-family: 楷体;font-size: 30px;}
</style>
- NewsPage.vue
<template>
<div style="width: 100%; height: 200px; background: palevioletred;">这是News页面</div>
</template><script>export default { name: 'NewsPage',data(){return{language:''}},}
</script>
<style scoped>div{font-family: 楷体;font-size: 30px;}
</style>
- 在index.js中配置路由
//把路由导进来
import VueRouter from "vue-router";
//将要配置的路由的组件引进来(点击之后要跳转的都要配)
import AboutPage from "../components/AboutPage"
import MessagePage from "../components/MessagePage"
import DetailPage from "../components/DetailPage"
import NewsPage from "../components/NewsPage"//创建并暴露一个路由器
export default new VueRouter({routes:[{path:'/about',component:AboutPage},{path:'/message',component:MessagePage,//在那里显示就在哪里配置children:[{path:"detail",name:"detail",component:DetailPage},{path:"news",name:"news",component:NewsPage}]}]
})
- 在Message页面中实现跳转的功能
<template>
<div><div style="width: 100%; height: 500px; background: rosybrown;"><h1>这是Message页面</h1><hr><div class="row"><div class="col-xs-2 col-xs-offset-2"><div class="list-group"><!-- Vue中借助router-link标签实现路由的切换 --><router-link class="list-group-item" active-class="active" to="/message/detail">Detail</router-link> <router-link class="list-group-item" active-class="active" to="/message/news">News</router-link></div></div></div><div><!-- 这个div主要是内容展示 --><router-view></router-view></div></div></div>
</template><script>export default { name: 'MessagePage'}
</script>
<style scoped>div{font-family: 楷体;font-size: 30px;}
</style>
结果:
编程式路由
前进、后退、跳转到指定页面
- HomePage.vue
<template>
<div style="background-color: pink;"><h1>这里是Home页面</h1><div><button @click="btnForward">前进</button> <button @click="btnBack">后退</button> <button @click="btnForwardAndBack">前进/后退</button> <button @click="btnJump">跳转到指定页面</button> </div><hr><div class="row"><div class="col-xs-2 col-xs-offset-2"><div class="list-group"><!-- Vue中借助router-link标签实现路由的切换 --><router-link class="list-group-item" active-class="active" to="/about">About</router-link> <router-link class="list-group-item" active-class="active" to="/message">Message</router-link></div></div></div><!-- 这个div主要是内容展示 --><router-view></router-view></div>
</template><script>export default { name: 'HomePage',methods:{btnForward(){//前进this.$router.forward();},btnBack(){//后退this.$router.back();},btnForwardAndBack(){//前进或者后退this.$router.go(-1);},btnJump(){//跳转//第一种跳转方式push,有历史,可以后退// this.$router.push({// name:"news",// query:{// username:"ZhangSan",// password:"123"// }// })//第二种跳转方式replace,没有历史this.$router.replace({name:"news",query:{username:"ZhangSan",password:"123"}})}}}
</script>
<style scope>div{font-family: 楷体;font-size: 30px;}
</style>
-
跳转页面发送的数据是可以取出来的
-
NewsPage.vue
<template>
<div style="width: 100%; height: 200px; background: palevioletred;">这是News页面</div>
</template><script>export default { name: 'NewsPage',data(){return{language:''}},mounted(){var username = this.$route.query.usernamevar password = this.$route.query.passwordconsole.log("username:"+username+"---password:"+password)}}
</script>
<style scoped>div{font-family: 楷体;font-size: 30px;}
</style>
结果: