第二周vue学习
单文件组件:
框架:

如果我们的组件为一个,通常采用默认暴露:export default school(名字)

上图中,name:“school”;组件名通常与xxx.vue名相同(name省略也可以运行,组件名则会被随便取)
app.vue:汇总全部组件

main.js:创建vue实例,并且指明为哪个容器服务

index.html:准备一个容器

render函数(在创建实例对象中):
关于不同版本的Vue:
1.vue.js与vue.runtime.xxx.js的区别:
(1)vue.js是完整版的Vue,包含:核心功能+模板解析器。
(2)vue.runtime.xxx.js是运行版的Vue,只包含:核心功能;没有模板解析器。
2.因为vue.runtime.xxx.js没有极板解析器,所以不能使用template配置项,需要使用render函数接收到的createElement函数去指定具体内容。
render函数完整写法;
render(createElement){
return createElement('h1','你好')
}
简写: render:h=>h('App'),
脚手架文件结构;

ref属性
1.被用来给元素或子组件注册引用信息(id的替代者)
2.应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)
3.使用方式:
打标识:<h1 ref="xxx">.....</h1> 或 <School ref="xxx"></Schoo1>
获取:this.$refs.xxx (拿到组件实例对象,而id是拿到id绑定的body结构)(这里this指vc)
props配置(父传子):
1.功能:让组件接收外部传过来的数据
父 :![]()
子 :

并且可以在子的template中使用该数据。
2.简单声明接收:
props:['name','age','sex']
3.接受的同时对数据进行限制:
props:{
name:{
type:String, //name类型是字符串
required:ture //name是必要的
}
age:{
type:Number,
default:99 //设置默认值
}
}
4.props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。
mixin(混入):
1.功能:可以把多个组件共用的配置提取成一个混入对象
2.使用方式:
第一步定义混合:例如:
{
data(){....},
methods:{·..·}
{
第二步使用混入,例如:
(1)全局混入:Vue.mixin(xxx)
(2)局部混入:mixins:["xxx"]

scoped样式:
1.作用:让样式在局部生效,防止冲突。
2.写法:<style scoped>
Todo-list案例:
组件化编码流程(通用):
1.实现静态组件:抽取组件,使用组件实现静态页面效果

2.展示动态数据:
2.1.数据的类型、名称是什么?
2.2.数据保存在哪个组件?
一堆数据用数组,每个数据用对象
[ {id='xx",
name='xx'},
{id='xxx',
name='xxx'}
{ }
]

根据数据数量遍历:
![]()
ps:随机生成id:nanoid
可以使用npm i nanoid 引入
import {nanoid} from 'nanoid'
使用时 id=nanoid()
3.交互-从绑定事件监听开始
父子之间传递数据:
父--->子:props
子---->父:父亲中定义一个函数,儿子调用父亲中函数
v-model="todo.done"也能实现勾选的同时传递数据,但不太推荐,因为有点违反规则,修改了props,只是是浅层次的,vue不会发现。
删除一个todo(过滤器):
在app中,deleteTodo(id){
this.todos=this.todos.filter((todo)=>{return todo.id!==id})
}
补充:
reduce( (pre,current)=>{ },0) //加粗部分,数组长度几,就调用几次
第二次调用函数,pre是第一次调用的返回值
最后一次调用函数的返回值是reduce的返回值
总结:
1.组件化编码流程:
(1)拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突。
(2)实现动态组件:考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用:
1)一个组件在用:放在组件自身即可。
2)一些组件在用:放在他们共同的父组件上(状态提升)。
(3)实现交互:从绑定事件开始。
2.props适用于:
(1)父组件==>子组件 通信
(2)子组件==>父组件通信(要求父先给子一个函数)
3.使用v-model时要切记:v-model绑定的值不能是props传过来的值,因为props是不可以修改的!
4.props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但不推荐这样做。
webStorage:
1.存储内容大小一般支持5MB左右(不同浏览器可能还不一样)
2.浏览器端通过Window.sessionStorage和 Window.localStorage 属性来实现本地存储机制。
3.相关API:
1. xxxxxStorage.setItem('key', 'value');
该方法接受一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值。
eg:存放对象:
let p={ name:'xx',age:18}
localStorage.setItem( 'person',JSON.stringify(p) )
2.xxxxxStorage.getItem('person');
该方法接受一个键名作为参数,返回键名对应的值。
eg:读取对象:
const result=localStorage.getItem( 'person' )
JSON.parse(result)
3.xxxxxStorage.removeItem('key'); //移除
该方法接受一个键名作为参数,并把该键名从存储中删除。
4.xxxxxStorage.clear() //清空
该方法会清空存储中的所有数据。
4.备注:
1.SessionStorage存储的内容会随着浏览器窗口关闭而消失。
2.LocalStorage存储的内容,需要手动清除才会消失。
3.|xxxxxStorage.getItem(xxx)如果xxx对应的value获取不到,那么getltem的返回值是null。
4.JSON.parse(nul1)的结果依然是null。
组件的自定义事件(在父组件中给子组件绑定自定义事件,事件回调在父中):
1.绑定事件:
在app中给实例对象studengt绑定atguigu事件(getStudentName无())

在methods中定义事件

在实例对象student中
![]()

给谁绑,谁触发!!
2.子----->父两种方式:
(1)父组件给子组件传递函数类型的props实现
(2)父组件给子组件绑定一个自定义事件实现:
1)使用@或v-on
![]()
2)使用ref

绑定自定义事件(app中)

一次性的事件将 $on 改成 $once
ref可以实现定时器功能:

3.解绑
解绑一个:this.$off('atguigu')
解绑多个:this.$off( ['atguigu','demo'] )
this.$destroy() //销毁了当前student组件的实例,销毁后所有student实例的自定义事件全部不奏效。
注:
(1)组件上也可以绑定原生DOM事件,需要使用native修饰符
eg:@click.native="show"
(2)通过this.$refs.xxx.$on('atguigu”,回调)绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出问题。
全局事件总线(任意组件中通信):
1.在main.js中,安装全局事件总线

this指vm,bus总线,$bus就是当前应用的vm
2.使用全局事件总线
(1)接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身。
methods(){
demo(data){......}
}
mounted(){
this.$bus.$on('xxxx',this.demo)
}
(2)提供数据:this.$bus.$emit('xxxx',数据)
3.最好在beforeDestroy钩子中,用this.$bus.$off(事件)去解绑当前组件所用到的事件。
父---------------------------------props-------------------------------------->子
<---------props(函数)、自定义事件、全局事件总线-----------
消息订阅与发布(第三方库pubsub.js)
安装:npm i pubsub-js
引入(哪用哪引入)import pubsub from 'pubsub-js'
pubsub.subscribe( 消息名,function(消息名,真正参数))
接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身。
methods(){
demo(data){ }
}
mounted(){
this.pid=pubsub.subscribe('xxx',this.demo)//订阅消息
)
}
提供数据:pubsub.publish(*xxx',数据)
最好在beforeDestroy钩子中,用PubSub.unsubscribe(pid) 去取消订阅
nextTick
1.语法:this.$nextTick(回调函数)
2.作用:在下一次DOM更新结束后执行其指定的回调。
3.什么时候用:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行。
动画效果
@keyframes 名{ }

元素进入的样式:
1.v-enter:进入的起点
2.v-enter-active:进入过程中
3.v-enter-to:进入的终点
元素离开的样式:
1.v-leave:离开的起点
2.v-leave-active:离开过程中
3.v-leave-to:离开的终点
使用<transition>包裹要过度的元素,并配置name属性:(加了name,则以上的v要换成name中的名字)
<transition name="hello">
<h1 v-show="isShow">你好啊!</h1>
</transition>
备注:若有多个元素需要过度,则需要使用:<transition-group>,且每个元素都要指定key值。
解决跨域问题的3种方法:
1.cors
2.json
3.代理服务器:
(1)在vue.config.js中添加如下配置:
devServer:{ proxy:'服务器网址' }//开启代理服务器
1.优点:配置简单,请求资源时直接发给前端(8080)即可。
2.缺点:不能配置多个代理,不能灵活的控制请求是否走代理。
3.工作方式:若按照上述配置代理,当请求了前端不存在的资源时,那么该请求会转发给服务器(优先匹配前端资源)
(2)编写 vue . config . js 配置具体代理规则:

1.优点:可以配置多个代理,且可以灵活的控制请求是否走代理。
2.缺点:配置略微繁琐,请求资源时必须加前缀。

前缀:紧跟8080(或其他数字)eg:.....8080/atguigu/students........
devServer:{
proxy:{
'/atguigu',
pathRewrite:{'^/atguigu' : ' '} //可以保证5000服务器请求的资源不是来自atguigu/student,而是/student
}
}
第三方库引进可以放在src下的assets下的文件夹中
返回数据:

可以把axios.get(.......)改成this.$http.get(...)
slot插槽
1.作用:让父组件可以向子组件指定位置插入 html 结构,也是一种组件间通信的方式,适用于父组件===>子组件
2.分类:默认插槽、具名插槽、作用域插槽
3.使用方式:
1)默认插槽:

2)具名插槽:
<... slot="xx">可以追加,不会覆盖
将一大段内容放在<template>中时,可以将<template slot="xx"换成v-slot:xx
3)作用域插槽:
1.理解:数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定。( games 数据在 Category 组件中,但使用数据所遍历出来的结构由 App 组件决定)
2.具体编码:



案例:

使用:listData(命名)=”数据名“,接收时只要props:['listData']即可,不需要太多遍。

红框部分会被塞到<slot>中去,<slot>默认值,未设置塞入内容时出现,有内容插入则不出现</slot>

浙公网安备 33010602011771号