总结 Vue3 项目基础1

Setup

执行时间是 beforeCreate 之前之前,且是自动执行

setuup 代码特点:

        定义数据 + 函数 最后以对象方式 return 出去

<script>
export default {
  setup() {
    //数据
    const messag = "ggg";
    //函数
    const logmessage = () => {
      console.log(messag);
    };
    //若想要在模板中用到该数据或者函数,必须以对象形式 return 出现
    return {
      messag,
      logmessage,
    };
  },
};
</script> 

<template>
  <div>
    {{ messag }}
    <button @click="logmessage">点我看看?</button>
  </div>
</template>

在setup中的this不再是指向组件实例,指向的是undefined

而如果有大量数据,岂不是要定义一个,在return一次,这里可以用到语法糖 <script setup> 非常方便! 

经过语法糖的封装可以更简单的使用组合式api

<script setup>
//数据
const messag = "ggg";
//函数
const logmessage = () => {
  console.log(messag);
};
</script>

组合式API中与响应有关的函数:reactive 和 ref 

类似于vue2中的data 都是用来生成相应数据

reactive

作用:接受对象类型数据的参数传入并返回一个响应式的对象

<script setup>
//导入
    import { reactive } from "vue";
//执行函数 传入参数 变量接收
    const state = reactive(对象数据类型);
</script>

例子:

<script setup>
//导入
import { reactive } from "vue";
//执行函数 传入参数 变量接收
const state = reactive({
  count: 0,
});

const addCount = () => {
  state.count++;
  console.log(state.count);
};
</script>

 <template>
  <div>
    <button @click="addCount">点击 count +1</button>
  </div>
</template>

 那么可以知道 reactive 针对的是对象类型的参数,而对于其他类型的参数,我们可以用到 ref

Ref

 作用:接收简单类型或者对象类型的数据传入并返回一个响应式的对象

<script setup>
//导入
import { ref } from "vue";
//执行函数 传入参数 变量接收
const state = ref(简单类型或者是复杂类型数据);
</script>

例子

<script setup>
//导入
import { ref } from "vue";
//执行函数 传入参数 变量接收
const count = ref(888);
const delCount = () => {
  //若在脚本区域修改有ref产生的响应式对象数据,必须通过 .value 属性
  count.value--;
  console.log(count.value);
};
</script>

 <template>
  <div>
    <button @click="delCount">点击 count +1</button>
  </div>
  <!-- 在模板中如果想用该数据 直接用这个变量即可 -->
  <input type="text" v-model="count" />
</template>

注意:

若在脚本区域修改有ref产生的响应式对象数据,必须通过 .value 属性

在模板中如果想用该数据 直接用这个变量即可

我们在脚本中直接打印 count 👇

组合式 API-computed 计算属性函数

计算属性基本思想和Vue2的完全一致,组合式API下的计算属性只是修改了写法

//导入
import { computed } from "vue";
// 执行函数 变量接收 在回调参数中return计算值
const computedState = computed(() => {
  return 基于响应式数据做计算之后的值;
});
</script>

例子:

<script setup>
//导入
import { ref } from "vue";
//执行函数 传入参数 变量接收
const arr = ref([1, 2, 3, 4, 5, 6, 7, 8]);
//导入
import { computed } from "vue";
// 执行函数 变量接收 在回调参数中return计算值
const computedArr = computed(() => {
  return arr.value.filter((item) => item > 3);
});
console.log(arr.value);

setTimeout(() => {
  arr.value.push(100);
}, 2000);
</script>

 <template>
  <div>原始数组:{{ arr }}</div>
  <div>去除3以下的数组: {{ computedArr }}</div>
</template>

2秒后:

 

注意:

计算属性应该是只读的,不应该去直接修改属性的值

API watch函数

作用: 侦听一个或者多个数据的变化,数据变化时执行回调函数

俩个额外参数: 1. immediate (立即执行) 2. deep (深度侦听)

基础使用 - 侦听单个数据

1.导入watch函数
2.执行watch函数传入要侦听的响应式数据(ref对象)和回调函数

<script setup>
//导入
import { watch, ref } from "vue";
const count = ref(888);

watch(count, (newVal, oldVal) => {
  //newVal 为变化后的新数据,oldVal 为旧数据
});
</script>

 例子:

<script setup>
//导入
import { watch, ref } from "vue";
const count = ref(0);

const addCount = () => {
  count.value++;
};

// 注意这里的 count 是不需要加 .vaule 属性的
watch(count, (newVal, oldVal) => {
  console.log("新数据" + newVal);
  console.log("老数据" + oldVal);
});
</script>

 <template>
  <div>
    <button @click="addCount">+1</button>
  </div>
</template>

基础使用 - 侦听多个数据

说明:同时侦听多个响应式数据的变化,不管哪个数据变化都需要执行回调

<script setup>
//导入
import { watch, ref } from "vue";
const count = ref(0);
const str = ref("agg");

const addCount = () => {
  count.value++;
};
const changeStr = () => {
  str.value = "bgg";
};

// 注意这里的 count 是不需要加 .vaule 属性的
watch([count, str], ([newCount, newStr], [oldCount, oldStr]) => {
  console.log("新的数据" + [newCount, newStr]);
  console.log("旧的数据" + [oldCount, oldStr]);
});
</script>

 <template>
  <div>
    <button @click="addCount">+1</button>
  </div>
  <div>
    <button @click="changeStr">改变字符</button>
  </div>
</template>

immediate

说明:在侦听器创建时立即触发回调,响应式数据变化之后继续执行回调

watch(
  count,
  () => {
    console.log(count.val);
  },
  {
    immediate: true,
  }
);

deep

默认机制:通过watch监听的ref对象默认是浅层侦听的,直接修改嵌套的对象属性不会触发回调执行,需要开启deep选项。

<script setup>
//导入
import { watch, ref } from "vue";
const count = ref({ num: 0 });

const addCount = () => {
  //直接修改属性 -> 不会触发回调
  count.value.num++;
};

watch(count, () => {
  console.log("变化");
});
</script>

开启 deep 后

<script setup>
//导入
import { watch, ref } from "vue";
const count = ref({ num: 0 });

const addCount = () => {
  //直接修改属性 -> 不会触发回调
  count.value.num++;
};

watch(
  count,
  () => {
    console.log("变化");
  },
  {
    deep: true,
  }
);
</script>

 <template>
  <div>
    <button @click="addCount">+1</button>
  </div>
</template>

 注意:当count 修改如下,当sum值修改也会触发 监听造成浪费。所提实操中最好尽量不开启deep,这样容易造成性能损耗

const count = ref({ num: 0, sum: 100 });

精确侦听对象的某个属性

需求:在不开启deep的前提下,侦听sum的变化,只有sum变化时才执行回调

可以把第一个参数写成函数的写法,返回要监听的具体属性

<script setup>
//导入
import { watch, ref } from "vue";
const count = ref({ num: 0, sum: 100 });

const addNum = () => {
  count.value.num++;
};
const addSum = () => {
  count.value.sum++;
};

watch(
  () => count.value.sum,
  () => {
    console.log("sun变化");
  }
);
</script>

 <template> 
  <div>
    <button @click="addCount">num+1</button>
  </div>
  <div>
    <button @click="addSum">sum+1</button>
  </div>
</template>

点击num不响应,点击sum控制台有响应

生命周期函数

 生命周期函数是可以执行多次的,多次执行时传入的回调会在时机成熟时依次执行

组合式API 父传子

基本思想
1.父组件中给子组件绑定属性
2.子组件内部通过props选项接收

 defineProps({属性名: 类型})

例子:

 结果:

 

如果传过来的是响应式数据

啥是 defineProps "编译器宏”

 类似于 vue2 的申明方式

组合式API 子传父

基本思想
1.父组件中给子组件标签通过@绑定事件

2.子组件内部通过 $emit 方法触发事件

defineEmits(['事件名称']) 

例子

 组合式API 模板引用

通过ref标识获取真实的dom对象或者组件实例对象

<script setup>
//1.调用 ref 函数得到 ref 对象
const h1Ref = ref(null);
</script>

<template>
  <!-- 2. 通过 ref 标识绑定 ref 对象 -->
  <h1 ref="h1Ref">我是H1</h1>
</template>

例子 (获取模板引用的时机是 组件挂在完毕)

<script setup>
import { onMounted, ref } from "vue";
import sonCom from "./son-com.vue";
//1.调用 ref 函数得到 ref 对象
const h1Ref = ref(null);
const comRef = ref(null);

onMounted(() => {
  console.log(h1Ref.value);
  console.log(comRef.value);
});
</script>

<template>
  <!-- 2. 通过 ref 标识绑定 ref 对象 -->
  <h1 ref="h1Ref">我是H1</h1>
  <sonCom ref="comRef" />
</template>

defineExpose()

默认情况下在<script setup>语法糖下组件内部的属性和方法是不开放给父组件访问的,可以通过defineExpose编译宏指定哪些属性和方法允许访问

作用:显示暴露组件内部的属性和方法

新增蓝框内容

请注意观察红框变化 

 什么是pinia

Pinia 是 Vue的专属的最新状态管理库,是 Vuex 状态管理工具的替代品

优势:

  • 提供更加简单的API(去掉了 mutation,之前的 Vuex 里面既有 mutation 又有 action )
  • 提供符合组合式风格的API (和 Vue3新语法统一)
  • 去掉了 modules 的概念,每一个 store 都是一个独立的模块4.搭配TypeScript 一起使用提供可靠的类型推断
import { createApp } from 'vue'
import App from './App.vue'

//1. 导入 createPinia
import { createPinia } from 'pinia'

//2. 执行方法,得到实例
const pinia = createPinia();

//3. 把 Pinia 实例加到 app 应用中
createApp(App).use(pinia).mount('#app')

如何定义 store 并且使用?

定义store

组件使用store 

 例子

getters实现

Pinia中的 getters 直接使用 computed函数 进行模拟

action如何实现异步

action中实现异步和组件中定义数据和方法的风格完全一致

storeToRefs

使用storeToRefs函数可以辅助保持数据(state + getter)的响应式解构

如果我们直接用解构赋值的方法去得到该数据,是不行的,响应式丢失

const { count, doubleCount } = counterStore;

用 storeToRefs 即可! 保持响应式

import { storeToRefs } from "pinia";
const { count, doubleCount } = storeToRefs(counterStore);

打印两值式响应式对象

 以上是对于数据相关的处理,而对于方法呢 可以直接从原本的 counterStore 中解构赋值

const { addCount } = counterStore;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值