一个简单的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.h1
console.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 = false
new 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 {
@Override
protected 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.username
var password = this.$route.query.password
console.log("username:"+username+"---password:"+password)
}
}
</script>
<style scoped>
div{
font-family: 楷体;
font-size: 30px;
}
</style>
结果: