3.28

27 阅读2分钟

1. 标签样式实现

image.png

2.this函数的作用域/prototype/最简写法

2.1 普通函数和箭头函数的this作用域

image.png 代码演示;

const obj = {
  name: 'csq',
  fn() {
    setTimeout(() => {
      console.log(this.name);
    }, 1000);
  }
};

obj.fn(); // 输出csq

1.fn为普通函数,调用方式决定fn的this; 定时器内部为箭头函数,作用域为父级函数作用域;
2.调用obj.fn():箭头函数作用域为父级作用域:fn(); fn()被obj对象调用,则fn的this指向obj:最终输出obj.name

3.vue3生命周期-每个周期的执行操作

image.png

4.祖孙组件通讯--组件通讯拓展

grandparent.vue

<template>
  <div>
    <parent> </parent>
  </div>
</template>
<script setup>
import { ref, provide } from "vue";
import parent from "./parent.vue";
import son from "./son.vue";

// 1.通过响应式变量传值
const msg = ref("grandparents providing");
provide("msg", msg);

const add = ref(0);
setInterval(() => {
  if (add.value <= 5) {
    add.value++;
  }
}, 1000);
provide("add", add);
</script>
<style scoped>
div {
  padding: 20px;
  border: 2px solid red;
  margin: 10px;
}
</style>

parent.vue

<template>
  <div>
    parent: {{ add }}
    <son></son>
  </div>
</template>
<script setup>
import { inject } from "vue";
import son from "./son.vue";
const add = inject("add", 0);
</script>
<style scoped>
div {
  padding: 20px;
  border: 2px solid blue;
  margin: 10px;
  color: black;
}
</style>

son.vue

<template>
  <div>son: {{ msg }}</div>
</template>
<script setup>
import { inject } from "vue";
const msg = inject("msg", "default msg");
</script>
<style scoped>
div {
  padding: 20px;
  border: 2px solid green;
  margin: 10px;
  color: black;
}
</style>

结果;

image.png

5.slots插槽

5.1 默认插槽-一个组件只能有一个默认插槽

slotsparents.vue

<template>
  <div>
    <slotsson>
      <h2>我是父组件传来的信息</h2>
    </slotsson>
  </div>
</template>
<script setup>
import slotsson from "./slotsson.vue";
</script>
<style></style>

slotsson.vue

<template>
  <div class="slotsson">
    我是子组件,下面是插槽内容
    <slot></slot>
  </div>
</template>
<script setup></script>
<style>
.slotsson {
  background-color: red;
  color: white;
  padding: 20px;
}
</style>

结果:

image.png

5.2 具名插槽

slotsparents.vue

<template>
  <div>
    <slotsson>
      <template #title> 我是父组件传来的标题<br /> </template>
      <template #content> 我是父组件传来的内容 </template>
    </slotsson>
  </div>
</template>
<script setup>
import slotsson from "./slotsson.vue";
</script>
<style></style>

slotsson..vue

<template>
  <div class="slotsson">
    <!-- 具名插槽 -->
    <slot name="title"></slot>
    <slot name="content"></slot>
  </div>
</template>
<script setup></script>
<style>
.slotsson {
  background-color: red;
  color: white;
  padding: 20px;
}
</style>

结果:

image.png

5.3 作用域插槽(scoped slot)(最常用插槽类型)

子组件通过slot把数据暴露给父组件使用 slotsparents.vue

<template>
  <div>
    <slotsson v-slot="user">
      <h3>name:{{ user.user.name }} age:{{ user.user.age }}</h3>
    </slotsson>
  </div>
</template>
<script setup>
import slotsson from "./slotsson.vue";
</script>
<style></style>

slotsson.vue

<template>
  <slot :user="user"></slot>
</template>
<script setup>
const user = {
  name: "slotsson",
  age: 20,
};
</script>
<style>
.slotsson {
  background-color: red;
  color: white;
  padding: 20px;
}
</style>

结果:

image.png

6.v-if与v-show区别

主要区别:v-if为对dom的创建和销毁,v-show为对dom的显示与隐藏 image.png

7.vuerouter中的动态路由

7.1 params:必须声明动态路由

路由配置:

{
  path: '/user/:id',
  name: 'User',
  component: User
}

路由传参使用:(使用push)

router.push({
  name: 'User',
  params: { id: 123 }
})

7.2 query

路由配置:

{
  path: '/user',
  component: User
}

路由传参

router.push({
  path: '/user',
  query: { id: 123 }
})

8.使用ref进行父传子

实现:父组件中使用ref传入子组件的openmodel方法
model.vue--子组件

<!-- 弹窗组件 -->
<template>
  <div v-if="isVisible" class="modal">
    <div class="modal-content">
      <button @click="closeModal">关闭弹窗</button>
      <p>this is a model content</p>
    </div>
  </div>
</template>
<script setup>
import { ref } from "vue";
const isVisible = ref(false);
const closeModal = () => {
  isVisible.value = false;
};
const openModal = () => {
  isVisible.value = true;
};
// 把两个方法暴露给父组件
defineExpose({
  openModal,
  closeModal,
});
</script>
<style>
.modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
}
.modal-content {
  background: white;
  padding: 20px;
  margin: 50px auto;
  width: 300px;
}
</style>

slotsparents.vue

<template>
  <div>
    <button @click="openModal">打开弹窗</button>
    <model ref="modelRef" />
  </div>
</template>
<script setup>
import { ref } from "vue";
import model from "./model.vue";
// 使用ref获取子组件实例
const modelRef = ref(null);
//调用子组件的openmoadel方法
const openModal = () => {
  modelRef.value.openModal();
};
</script>
<style></style>

image.png

image.png