动画与过渡
Test.vue
<template><div><button @click="isShow = !isShow">显示/隐藏</button><transition name="hello" appear><h1 v-show="isShow">你好啊!</h1></transition><transition appear><h1 v-show="isShow">尚硅谷</h1></transition><!--没有name都和v-enter-active关联--></div>
</template><script>
export default {name: "Test",data(){return {isShow: true}}
}
</script><style scoped>h1{background: orange;}.hello-enter-active{animation: anim linear 0.5s;}.hello-leave-active{animation: anim linear 0.5s reverse;}@keyframes anim {from {transform: translateX(-100%);}to{transform: translateX(0px);}}
</style>
Test2.vue
<template><div><button @click="isShow = !isShow">显示/隐藏</button><!--transition 只能包裹一个元素而transition-group可以包含多个元素--><transition-group name="hello" appear><h1 v-show="isShow" key="1">你好!</h1><h1 v-show="isShow" key="2">Shanghai</h1></transition-group></div>
</template><script>
export default {name: "Test2",data(){return {isShow: true}}
}
</script><style scoped>h1{background: orange;}/*进入的起点,离开的终点*//*h1{transition:0.5s linear;}.hello-enter{transform: translateX(-100%);}.hello-enter{transform: translateX(0);}*/.hello-enter,.hello-leave-to{transform: translateX(-100%);}/*进入的过程,离开的过程*/.hello-enter-active,.hello-leave-active{transition: linear .5s;}/*进入的终点,离开的起点*/.hello-enter-to,.hello-leave{transform: translateX(0);}</style>
一般是引入第三方动画版,效果会很好
Test3.vue
<template><div><button @click="isShow = !isShow">显示/隐藏</button><!--transition 只能包裹一个元素而transition-group可以包含多个元素--><transition-groupappearname="animate__animated animate__bounce"enter-active-class="animate__swing"leave-active-class="animate__backOutUp"><h1 v-show="isShow" key="1">你好!</h1><h1 v-show="isShow" key="2">Shanghai</h1></transition-group><!--从右上角下来的不能在h1的样式里写transition了,使用.hello-enter-active,.hello-leave-active写 --></div>
</template><script>
import 'animate.css';
export default {name: "Test3",data(){return {isShow: true}}
}
</script><style scoped>h1{background: orange;}
</style>
集成第三方动画
Animate.css
animate.style打不开
下载后引入
通过给 transition-group元素设置 tag 属性,指定 transition-group 渲染为指定的元素,如果不指定 tag 属性,默认渲染为 span 标签
网络配置-配置ajax代理
在文件夹中有nodejs,cmd中node server1,server1在5000端口。同样的方式可以5001端口
学完ajax promise 和axios
1.xhr
new XMLHttpRequest() xhr.open() xhr.send()
不常用
2.jQuery 80-20的比例,get post
3.axios 好好好很好很好好
4.fetch,axios只需要通过一次请求 fetch做任何事情都需要让你通过两次,但兼容性垃圾
步骤
npm i axios
import axios from 'axios'
协议 域名 端口号:因为5000和8080,8080端口访问5000端口,跨域了,这个不对,服务器没有把数据给浏览器,而是一开始有一个域检测,再那里就没通过
jsonp解决跨域,但是不用,因为必须前后端一起配置
解决方法一:代理服务器
1.配置类方式(实现WebMvcConfigurer) 2.使用@CrossOrigin注解 3.使用nginx反向代理解决跨域 4.Vue中配置cli代理服务器
配置参考 | Vue CLI (vuejs.org)
浏览器是访问8080端口,而不是占用端口,8080上只有一个代理服务器在监听。我们打开5000服务器
<template><div><button @click="getStudents">获取学生信息</button><button @click="getCars">获取汽车信息</button></div>
</template><script>
import axios from 'axios';
export default {name: "App",methods:{getStudents(){axios.get('/api/students') //其实这里就是请求http://localhost:8080/students只不过把请求转移给了端口5001.then(res => console.log(res.data)).catch(e => console.log(`msg: ${e.message}, stack: ${e.stack}`));},getCars(){axios.get('/demo/cars') //同理.then(res => console.log(res.data)).catch(e => console.log(`msg: ${e.message}, stack: ${e.stack}`));}}
}
</script>
所处的位置是8080,代理服务器是8080,存储的数据在5000。什么时候不把请求转发给8080吧?当你请求的资源8080本身就有,就不会把请求转发5000
解决方法二:多重代理
因为只能只能配置一个代理,一个请求,无法使用第二个服务器;其次是无法灵活控制
vue.config.js
//common js 暴露
module.exports = {pages: {index: {//入口entry: 'src/main.js',},},//关掉默认的语法检查lintOnSave: false,// //开启代理服务器(方式一)// devServer:{// proxy: 'http://localhost:5001', //将请求转发给端口号5001,注意这里只能配置单个代理,不能配置多个代理// }//开启代理服务器(方式二) 多个代理devServer: {proxy: {//当请求的前缀是api,直接转发请求到服务器5001端口'/api': {target: 'http://localhost:5001',ws: true, //用于支持websocketchangeOrigin: true, //用于控制请求头中host的值pathRewrite:{//把请求中含有的api替换成空字符串'^/api': '',}},'/demo': {target: 'http://localhost:5002',//不写 ws和changeOrigin默认为truepathRewrite: {'^/demo':'',}}}}
}
//引入Vue
import Vue from "vue";
//引入App
import App from './App';//关闭Vue的生产提示
Vue.config.productionTip = false;new Vue({el: '#app',render: h => h(App),
});
App.vue
<template><div><button @click="getStudents">获取学生信息</button><button @click="getCars">获取汽车信息</button></div>
</template><script>
import axios from 'axios';
export default {name: "App",methods:{getStudents(){axios.get('/api/students') //其实这里就是请求http://localhost:8080/students只不过把请求转移给了端口5001.then(res => console.log(res.data)).catch(e => console.log(`msg: ${e.message}, stack: ${e.stack}`));},getCars(){axios.get('/demo/cars') //同理.then(res => console.log(res.data)).catch(e => console.log(`msg: ${e.message}, stack: ${e.stack}`));}}
}
</script>
总结一下,两种代理方式,前端写代码常用DevServer正向代理,代理浏览器,仅限开发阶段,项目上线后,使用Nginx反向代理,代理服务器,后端人员编写
097_尚硅谷Vue技术_配置代理_方式二_哔哩哔哩_bilibili断了一次未曾听懂
GitHub用户搜索案例
静态界面
App.vue
<template><div class="container"><Search/><List/></div>
</template><script>
import Search from "@/components/Search";
import List from "@/components/List";
export default {name: "App",components:{Search,List}
}
</script>
<style lang="css">
</style>
List.vue
<template><div class="row"><!--展示用户列表--><div v-show="info.users.length" class="card" v-for="user in info.users" :key="user.login"><a :href="user.html_url" target="_blank"><img :src="user.avatar_url" style='width: 100px'/></a><p class="card-text">{{ user.login }}</p></div><!---欢迎词--><h1 v-show="info.isFirst">Welcome!</h1><!--加载中---><h1 v-show="info.isLoading">Loading...</h1><!---错误信息--><h1 v-show="info.errMsg">Something has been wrong, errorMessage: {{ info.errMsg }}</h1></div>
</template><script>
export default {name: "List",data(){return {info : {isFirst: true, //是否为第一次使用users:[],isLoading: false, //是否在加载中errMsg: '',}}},mounted() {this.$bus.$on('updateListData', (dataObj) => {// console.log(`我是list,接到了数据data:`, users);// this.isFirst = isFirst;// this.isLoading = isLoading;// this.errMsg = errMsg;// this.users = users;this.info = { ...this.info, ...dataObj };});}}
</script><style scoped>
.album {min-height: 50rem; /* Can be removed; just added for demo purposes */padding-top: 3rem;padding-bottom: 3rem;background-color: #f7f7f7;
}.card {float: left;width: 33.333%;padding: .75rem;margin-bottom: 2rem;border: 1px solid #efefef;text-align: center;
}.card > img {margin-bottom: .75rem;border-radius: 100px;
}.card-text {font-size: 85%;
}
</style>
Search.vue
<template><section class="jumbotron"><h3 class="jumbotron-heading">Search Github Users</h3><div><input type="text" placeholder="enter the name you search" v-model="keyword"/> <button @click="searchUsers">Search</button></div></section>
</template><script>
import axios from "axios";
export default {name: "Search",data() {return {keyword: '',}},methods:{//使用全局事件总线在组件间传递数据searchUsers(){this.$bus.$emit('updateListData', {isFirst: false,isLoading: true,errMsg: '',users: []})axios.get(`https://api.github.com/search/users?q=${this.keyword}`).then(res => {console.log(res.data.items);this.$bus.$emit("updateListData", {isLoading: false,errMsg: '',users: res.data.items});}).catch(e => {console.log(`请求失败:${e.message}`)this.$bus.$emit("updateListData", {isLoading: false,errMsg: e.message,users: []});});}}
}
</script><style scoped></style>
只要import用了bootstarp这种外部插口,vue脚手架会进行严格的检查,只要不存在就报错
图片加载不出来的,是因为老师用的网络路径,原路径换了,把/image去掉就行,图片链接cn前加上v2.就行了,scoped是样式只在当前组件生效
动态组件
主要是data(){}以及5,6行的v-model和@click="searchUser",methods的axios后端数据传递,模板字符串请用ESC下方的英文顿号包裹字符串,否则不生效,这不屁话吗
我们用到三个返回值,avatar_url ,html_url, login分别是头像地址,个人主页,用户名字
因此使用v-for遍历生成图标,不再多个list
<template><div class="row"><div class="card" v-for="user in users" :key="user.login"><a :href="user.html_url" target="_blank"><img :src="user.avatar_url" style='width: 100px' /></a><p class="card-text">{{ user.login }}</p></div></div>
</template><script>
export default {name: 'List',data() {return {isFirst:true,isLoading:false,errMsg:'',users: []}},mounted() {this.$bus.$on('getUsers', (users) => {console.log('我是 List 组件,收到数据:', users)this.users = users})},
}
</script>
这时欢迎使用还在呈现,因此点击搜索后isFirst就false,isLoading就true,
完善部分!!!!😭😭😭😭😭😭😭😭😭😭完蛋了!