Vue2+3 - 尚硅谷Vue技术全家桶
(天禹老师主讲) 笔记 Part3
2.7 TodoList案例
- 创建静态页面与 VC。
- 确认数据添加在哪里。MyList。id记得用字符串,因为int有尽头。
- MyList传递数据给MyItem,props。:checked=‘todo.done’。
- MyHeader 回车添加data。
- uuid插件,nanoid小一点的生成id插件 > npm i nanoid > id:nanoid();
- 数据在MyList上无法实现,移到 App上去。MyList通过props获得数据。
- MyHeader 传递数据给 App。子 传递给 父亲。
- 父亲定义一个函数 receive, 并传递给 子 VC。
- 子 VC 通过 props 获取函数,把数据通过函数传回给 父元素。
- 完善添加功能
2.8 浏览器本地存储 WebStorage
localStorage 搜索的历史记录
localStorage.setItem(‘key1’,‘data2’) JSON.stringify(obj)
localStorage.getItem(‘key1’) JSON.parse(‘str’)
localStorage.removeItem(‘key1’)
localStorage.clear();
sessionStorage 浏览器一关,数据就没有了
把local的全部换成session
2.9 TodoList_本地存储
watch todos,把todos数据记录到localStorage里面去,如果是空则传递 [].
2.10 组件自定义事件
父传子:通过props
子传父:
1. 通过props传递一个方法过去。
1. 自定义组件 <Student v-on:customVCEvent="getStudentName" />
- customVC是自定义组件的名字,绑定到了Student的VC实例对象上面了。
- 简写:<Student @customVC=“getStudentName” />
- 在Student 调用 this.$emit(‘customVCEvent’, this.name)
3. 自定义组件 另外一种绑定写法
```js
<Student ref="student" />
mounted() {
this.$refs.student.$on('customVCEvent', this.name)
}
```
4. 自定义组件两种写法,后面的写法更加灵活,还能异步绑定。
自定义事件
-
调用 this.$emit(‘customEvent’)
-
解绑:this.$off(‘customEvent’) 解绑一个自定义事件
this.$off([‘customEvent1’, ‘customEvent2’]) 解绑多个自定义事件
this.$off() //解绑所有自定义事件
注意点:
-
如果想用click等原生的DOM事件,需要加上native修饰符
<Student ref=“student” @click.native=“show” />
-
2. 父组件中,绑定自定义事件的回调函数如果直接写需要使用箭头函数。
2.11 TodoList_自定义事件
把Header和Footer改一下
2.12 全局事件总线 $bus
-
在main.js中添加
new Vue({ el:'#app', render: h => h(App), beforeCreate() { Vue.prototype.$bus = this // 安装全局事件总线 } })
-
在School里面接收数据,当Student触发了hello事件,这边就能收到数据
mounted() { this.$bus.$on('hello',()=>{ 处理数据...}) } beforeDestroy() { this.$bus.$off('hello') // 因为bus一直在,所以销毁School时记得销毁事件 }
-
在 Student 里面触发,发送数据
this.$bus.$emit('hello', this.name)
-
2.13 TodoList_事件总线
App与MyItem组件使用全局事件总线
2.14 消息订阅与发布 pubsub.js库
-
npm i pubsub-js
-
import pubsub from ‘pubsub-js’
-
在订阅的 VC 中写入:
mounted() { var pubid = pubsub.subscribe('hello', (msgName, data) => { // 订阅消息 }) } beforeDestroy() { pubsub.unsubscribe(this.pubId) }
-
在发布消息的地方写入:
pubsub.publish('hello',666)
2.15 TodoList_pubsub
把MyItem的删除改成消息订阅方式
2.16 TodoList_nextTick
handlerBlur(todoObj, $event)
e.target.value // 获取input里面的值
todoObj.hasOwnProperty.call(‘isEdit’) 判断是否有这个属性
this.$set(todoObj, ‘isEidt’, true),// 动态添加属性
this.$nextTick(function(){
this.$refs.inputTitle.force()
}) //这个回调函数会在 重新解析模板,在整个DOM更新完之后再执行
2.17 过度与动画
- 普通动画
.com {
animation: test 1s;
}
.go {
animation: test 1s reverse; //反着模仿动画
}
@keyframes test {
from {
transform: translateX(-100%)
}
to {
transform: translateX(0px)
}
}
-
Vue里边的动画实现
-
把标签用transition包裹起来
-
v-show=“isShow”
-
样式名字
v-enter-active
v-leave-active
-
如果
那么动画样式写 hello-enter-active hello-leave-active
-
初始化的时候就播放进入的动画效果
简写:
-
-
过度
/* 进入的起点、离开的终点 */ .hello-enter,.hello-leave-to{ transform: translateX(-100%); } .hello-enter-active,.hello-leave-active{ transition: 0.5s linear; //相当于h1{ transition: .5s linear;} 动画只要这个属性 } /* 进入的终点、离开的起点 */ .hello-enter-to,.hello-leave{ transform: translateX(0); } 多个元素需要动画效果,用transition-group, 子元素需要加key属性 <transition-group name="hello" appear> <h1 v-show="!isShow" key="1">你好啊!</h1> <h1 v-show="isShow" key="2">你好啊!</h1> </transition-group>
-
第三方的动画库 animate.css
-
npm i animate.css
-
引入 import ‘animate.css’
-
参考 https://animate.style/
-
给transition-group两个属性
enter-active-class
leave-active-class 选择什么样的样式
-
-
2.18 TodoList_动画
给添加,删除的Item添加动画
2.19 配置代理服务器
解决跨域问题
- 准备工作,打开 D:\66\web\05-vue\尚硅谷Vue技术全家桶(天禹老师主讲)\资料(含课件)\05_其他\test_proxy_server, 运行 node server1,访问 http://localhost:5000/students
node server2, http://localhost:5001/cars
常用的发送ajax请求的方法:
-
xhr new XMLHttpRequest()
-
jQuery $$ . get $.post
-
axios 请求拦截器,相应拦截器
-
fetch 原生就有的,缺点:包了两层,IE不兼容fetch
-
vue-resource Vue1.0用的多,现在已经不维护了,对xhr的封装
解决跨域问题:
1. cors 不用前端,服务器响应时加特殊响应头
1. jsonp 借助script src属性,但用得少,前后端都需要配合,只能解决GET请求
1. 配置一个代理服务器,像中介 1.nginx 难 2.vue-cli 选择
Vue-cli 配置代理服务器:
第一种方法:****
-
配置 vue.config.js
https://cli.vuejs.org/zh/config/#devserver
module.exports = { devServer: { proxy: 'http://localhost:5000' } }
-
修改请求地址,把5000 改成 8080
getStudent() {
axios.get('http://localhost:8080/students').then(
response => {
console.log("请求成功!"+response.data)
}
,err => {
console.log("请求失败!"+ err.message)
})
}
-
缺点:前提是我们项目 public文件夹下面没有student文件,
而且不能配置多个代理
第二种配置代理的方式:
- 修改vue.config.js 文件
// 开启代理服务器 方式二:
devServer: {
proxy: {
'/api1': {
target: 'http://localhost:5000',
pathRewrite: {
'^/api1':''}, //不能少,让5000上的url更正过来
ws: true, // 用于支持 websocket
changeOrigin: true // 用于控制请求头中的host值,对5000撒谎,说我也是 5000端口发送过来的请求
},
'/api2': {
target: 'http://localhost:5001',
pathRewrite: {
'^/api2':''}, //不能少,让5000上的url更正过来
ws: true, // 用于支持 websocket
changeOrigin: true // 用于控制请求头中的host值,对5000撒谎,说我也是 5000端口发送过来的请求
},
}
-
修改代码
getStudents() { axios.get('http://localhost:8080/api1/students').then( response => { console.log("请求成功!"+response.data) } ,err => { console.log("请求失败!"+ err.message) }) }, getCars() { axios.get('http://localhost:8080/api2/cars').then( response => { console.log('请求成功!' + response.data) }, err => { console.log('请求失败!' + err.message) } ) }
2.20 github搜索案例
-
bootstrap 样式的引入
public > css > bootstrap.css 放这里
-
在index.html里面引入 bootstrap.css, 使用 BASE_URL的路径
-
对象赋值时,有一些属性不想让他动的写法
this.info = {…this.info, …dataObj}
重名属性以dataObj为主,没有的info保持不变,顺序也可以不用考虑
2.21 github搜索案例_vue-resource
用的不多了,这是Vue的插件
npm i vue-resource
import vueResource from ‘vue-resource’
Vue.user(vueResource )
把 axios.get()… 替换成
this.$http.get()…就行
2.22 插槽 Slot
- 普通插槽
父组件中
<Category>
<div>
结构及内容。。。
</div>
</Category>
子组件Category
<template>
<div>
<slot>当没有内容填充时,默认显示的内容</slot>
</div>
</template>
- 具名插槽
父组件中
<Category>
<div slot="center">
结构及内容。。。
</div>
</Category>
或者
<Category>
<div v-slot:footer>
结构及内容。。。
</div>
</Category>