精宏技术部试用期学习笔记(vue)
父子通信
什么是通信 / 为什么要通信
通信即在不同组件之间传输数据
-
当在 复用组件 时,需要传递不同数据达成不同的表现效果
-
能够根据其他组件的行动,响应式 的做出变化
Props
功能: 让父组件信息传递到子组件
code:
假定 index.vue 已经通过 router 挂载在了 '/' 路由下
html
//index.vue
<script setup>
import { ref } from 'vue';
import vue1 from '../components/vue1.vue';
const num1 = ref(15);
const increase = () => {
num1.value += 1;
}
</script>
<template>
<h1>Index Page</h1>
<span>num1 = {{ num1 }}</span>
<button @click="increase">increase</button>
<vue1 :numFa="num1"></vue1>
</template>
html
//vue1.vue
<script setup>
defineProps({
numFa: Number
})
</script>
<template>
<h2>这是vue1组件</h2>
<span>numFa: {{ numFa }}</span>
</template>
关于解构
定义之后直接使用就是响应式的
但如果解构之后不用 toRefs 则变成无法响应
html
<script setup>
import { toRefs } from 'vue';
const props = defineProps({
numFa: Number
})
// const { numFa = "none" } = props;
//解构1 无法响应
//const { numFa = "defualt" } = toRefs(props);
//解构2 但是可以响应
</script>
注意点:
- 父组件在定义传递参数时需要使用响应式(ref)
- 传递参数时,元素内要用 "v-bind:" 来连接响应式变量
ex 其他写法:
js
//非 <script setup> 写法
export default {
props: {
numFa: Number
}
}
ts
//ts写法
<script setup lang="ts">
defineProps<{
title?: string
likes?: number
}>()
</script>
Emit
原理
子元素触发 事件1 -> emit(传值) -> 父元素 事件2(监听-事件1) -> 获得子元素传值
code
html
//index.vue
<script setup>
import { ref } from 'vue';
import vue2 from '../components/vue2.vue';
const sonInfo = ref("");
const sonsetInfo = (value) => {
sonInfo.value = value;
alert(sonInfo.value);
}
</script>
<template>
<h1>Index Page</h1>
<vue2 @getText="sonsetInfo"></vue2>
</template>
html
//vue2.vue
<script setup lang="ts">
import { ref } from 'vue';
const emit = defineEmits(["getText"]);
const text = ref("defualt");
const getText = () => {
emit("getText", text.value);
};
</script>
<template>
<h2>这是vue2组件</h2>
<div>text: {{ text }}</div>
<input type="text" v-model="text"><br>
<button @click="getText">updata text</button>
</template>
pinia 组件通信
为什么使用 pinia
props 和 emit 是依托于父子组件的关系来传递变量
但在两个不相关的组件之间传递变量就会很麻烦
因此需要 pinia 来大统一变量
如何使用 pinia
1 安装 pinia
cmd
pnpm i pinia
安装好后能在 package.json 中查看
2 挂载 pinia
流程类似于 vue-router
这里对 pinia 进行了一个封装
让 mian.ts 高度精炼
同时创建了 stores文件夹
用来存放 pinia 相关文件
ts
//./stores/index.ts
import { createPinia } from "pinia";
const pinia = createPinia();
export default pinia;
ts
//main.ts
import pinia from './stores/index.ts';
app.use(pinia);
3 创建 pinia库
在 stores 中创建文件 transStore.ts
ts
import { defineStore } from "pinia";
import { ref } from "vue";
const transStore = defineStore("trans", () => {
const name = ref("Rosyr");
//在库中定义响应式变量
const setName = (nvalue: string) => {
name.value = nvalue;
};
//使用setName函数 暴露name变量 (即让外界能访问到
return {
name,
setName,
};
//用 return 进行开放store内部
});
export default transStore;
4 在 vue组件 中使用 pinia
ts
import transStore from '../stores/transStore';
先导入库
ts
const newTransStore = transStore();
创建变量存放库
- 非响应式读取pinia库中的值
ts
const namevalue = newTransStore.name;
- 响应式读取pinia库中的值
ts
import { storeToRefs } from 'pinia';
const {name} = storeToRefs(newTransStore);
pinia + vue-router
在 app 挂载的时候 router总会比pinia先挂载
因此要在router中使用pinia来实现路由守卫
需要在router中手动引入pinia
ts
import { createPinia } from "pinia";
import transStore from '../stores/transStore';
const pinia = createPinia();
const newTransStore = transStore(pinia);
//...