全栈开发一条龙——前端篇
第一篇:框架确定、ide设置与项目创建
第二篇:介绍项目文件意义、组件结构与导入以及setup的引入。
第三篇:setup语法,设置响应式数据。
第四篇:数据绑定、计算属性和watch监视
第五篇 : 组件间通信及知识补充
第六篇:生命周期和自定义hooks
第七篇:路由
本文将详细讲述Vue3的种种参数传递,是做项目中必须熟练掌握的技能。
文章目录
- 一、有限(定向)组件传递参数
- 1.props父子组件传参
- 2.自定义事件
- 3. attrs
- 4. provide/inject 0打扰实现祖孙通信
- 二、任意组件通信
- 1、mitt(Vue3不推荐)
- 1.建立emitter
- 2.emitter操作事件
- 3.例子
- 2.pinia(重要)
- 1)引入pinia
- 2)存储和读取
- 1.count.ts
- 2.count.vue
- 3.getters
- 4.subscribe
- 3)pinia的组合式写法
一、有限(定向)组件传递参数
1.props父子组件传参
父–>子组件在调用子组件直接附上props传参即可。此处为了说接口已经提前讲过了,详细的可以看props传参参考
子–>父:这就麻烦一点,我们要先让父亲传一个获取变量的函数给子,子接收这个方法,然后子调用这个方法传入参数,这样父就能收到。
2.自定义事件
子–>父
haha是事件名(自定义事件),xyz是调用函数,左边为父组件,右边为子组件。
在父组件中先给子组件定义一个自定义事件haha,给他绑定上xyz方法。接下来,我们要编写haha的触发方法:在子组件中先用defineEmits接收haha,之后我们调用emit('haha')
就可以触发事件,haha后可以附上函数,左边父组件的xyz方法就可以收到。
emit('haha')
可以在任何地方调用,比如我想要子组件挂载3秒后触发,我就按照下面的写法 :
3. attrs
祖–>孙
观察这两页代码,上面的图片为祖父组件,下面的为父亲组件,祖父组件传递了abcdxy,但父亲一个都没接收。虽然儿子没接收,但祖父只要传递了,数据就一定存在,就存放在attrs这个属性中(如果父亲接收了a,那祖父传下来的attrs里就只有bcdxy了,即attrs里是祖父传了但父亲没用的东西)
儿子将attrs给孙子之后,孙子就可以直接用了
最后就实现了祖孙的信息传输。
孙–>祖
很简单,跟自定义方法类似,祖父将方法传下来,孙子接收到之后调用即可。
4. provide/inject 0打扰实现祖孙通信
provide可以向所有晚辈传数据(包括子、孙、曾孙等等)
使用了provide之后,任意晚辈可以用inject调用
这完全不需要中间(比如祖孙之间有其他父子关系的组件)操作,直接在孙子处调用即可,实现0打扰。
inject的第二个属性是默认值,如果没收到就需要加默认值 inject('money',666)
反向传输又是经典的用函数传
通过传递函数,可以实现反向数据传输。
二、任意组件通信
1、mitt(Vue3不推荐)
1.建立emitter
先在src下建立utils文件夹,创建emitter文件
在其中调用mitt
然后打开main.ts引入emitter
2.emitter操作事件
emitter.on
是绑定事件,emitter.emit('方法名')
是调用事件
以上代码可以实现每一秒调用依次test1和test2,setInterval是周期调用。在console栏里我们能看到
emitter.off
是接触绑定
我们写一个定时器,3秒之后解绑test1,就会出现下图这样,一开始周期调用test1和2,在三秒之后只调用2了。
同时解绑多个(清空函数): emitter.all.clear()
就可以将方法一键解绑。
3.例子
事实上,emit就相当于第三方写好的一个自定义方法的Api,各个模式都很像,差别是emit可以实现拥有emitter的组件都能通信。
注:别忘了释放emitter建立的通信
2.pinia(重要)
1)引入pinia
现在终端中输入npm i pinia
,然后重启Vscode
打开main.ts文件,然后引入pinia并创建
import { createPinia } from 'pinia'
const pinia = createPinia()
然后把pinia安装到我们的app上
app.use(pinia)
最后代码如图:
2)存储和读取
我们先随便写两个组件,我这里写了一个加和组件(count)和获取边牧图片组件(dog)。接下来,我们要将数据共享。
我们在src目录下建立 store文件夹,在其中建立count.ts(尽量与组件同名,方便你后期理解,但不强制)
1.count.ts
import { defineStore } from "pinia"
export const useCountStore = defineStore('count',{
//state真正存储数据
state(){
return {
sum:0
}
}
})
此处第一个参数为组件名,我们写count组件,第二个参数要求是一个函数,里面的返回值就是我们的数据。
2.count.vue
import { useCountStore } from '@/store/count';
const countStore = useCountStore()
在组件中,先引入我们刚刚写的,然后调用。之后我们就可以countStore.sum来读取修改它。
<h2>和为:{{ countStore.sum}}</h2>
function add(){
countStore.sum += n.value
}
与之前效果一致。
如果变量太多,可以用对象修改,数量不多直接按照.xx操作即可
第三种,如果你要把判断逻辑放在其他组件,让页面看上去干净的话,可以用函数修改。action与state同级。
action里还可以写其他函数,就理解为类函数就可以了。
3.getters
与action和state同级,我们还可以写getters,相当于计算属性
比如这样,就是把state当作参数收集过来,然后返回其中的sum属性*10,这样你就可以调用获得这个bigsum,与常用变量一样。当然,你也可以直接用this.sum,跟类私有变量其实差不多。
比如这样
如果遇到飘红,就加上这个:类型。
4.subscribe
pinia中的订阅函数的作用等同watch
mutate是本次修改的信息,state是数据,用state.xx就可以调用。
3)pinia的组合式写法
我们可以将第二个参数当作setup,然后按照组合式API的写法去写,这是最常用的。用法与之前完全一致,只有这个存储hooks的写法不一样。