vue3使用

本文详细介绍了如何使用create-vue创建Vue项目,然后深入讲解了Vue3的组合式API,包括ref、reactive、computed和watch的用法,以及生命周期的理解。同时,文章还涵盖了组件间的通信方法,如父传子、子传父,以及如何通过Pinia进行状态管理。
摘要由CSDN通过智能技术生成

1.使用create-vue创建项目

1.前提环境条件
检查node.js 16.0或者更高版本
2.创建一个vue项目
npm init vue@latest
这一指令会安装并执行create-vue

2.使用组合式API入口-setup

<script lang="ts">
import {defineComponent,ref} from 'vue'
export default defineComponent({
  setup() {
    const msg = ref<number>(123);
    const arr = ref([12,123,777]) 
    const abc = ()=>{
      //修改msg的值
      msg.value = 888
    }
    return {msg,arr,abc}
  }
})
</script>

使用reactive声明变量

<script setup>
//1.导入reactive函数
import { reactive } from 'vue';
//2.执行函数,传入一个对象类型的参数 变量接收
const state = reactive({
  count: 0
})
const jia = () => {
  state.count++
}
</script>

使用ref声明变量

可以接受简单类型或者复杂类型的数据

<script>
//1.导入ref函数
import { ref } from 'vue';
//2.执行函数 传入参数【简单类型+对象类型】变量接收
const state = ref(1)
const jia = () => {
  console.log(state);
//脚本区域修改ref产生的响应式对象数据,必须通过.value属性
  state.value++
}
</script>

3. computed使用、watch使用

计算属性computed的使用

<script setup>
//1.导入computed
import { computed, ref } from 'vue';
const list = ref([1, 2, 3, 4, 5, 6, 7, 8])
//2.执行函数 return计算之后的值 变量接收
const computeds = computed(() => {
  return list.value.filter((item) => item > 2)
})
setTimeout(() => {
  list.value.push(9, 10)
}, 3000)
</script>
//总结
//1.计算属性不应该有副作用
//比如说请求 |修改dom  
//2.避免直接修改计算属性的值
//计算属性应该是只读的

watch监听的使用

单个监听

<script setup>
//1.导入computed
import { ref, watch } from 'vue';
//watch监听单个数据源
//ref对象不需要加 .value vue3自己处理
const count = ref(0)
const btn = () => {
  count.value++
}
//第一个监听的对象,newval新的,oldval旧的
watch(count, (newval, oldval) => {
  console.log(newval, oldval);
})
</script>

多个监听

<script setup>
//1.导入computed
import { ref, watch } from 'vue';
const count = ref(0)
const str = ref(1)
const btn = () => {
  count.value++
}
const add = () => {
  str.value = 123
}
//多个侦听
watch([count, str], ([newcount, newstr], [oldcount, oldstr]) => {
  console.log([oldcount, oldstr]); //新值
  console.log([newcount, newstr]); //旧值
}, {
  immediate(印美的啊特): true //立刻执行回调
  deep:true 深度监听
})
</script>

不开启deep,对某个层次比较深的属性变化执行回调怎么做

<script setup>
//1.导入computed
import { ref, watch } from 'vue';
//watch监听单个数据源
const count = ref({ a: 1 })
const btn = () => {
  count.value.a++
}
//第一个写成函数方法,返回要监听的具体属性
watch(
  () => count.value.a,
  () => {
    console.log('变化了');
  }
)
</script>

deep性能耗损,尽量不适用deep
 

4.生命周期

 1、setup() : 创建组件之前,在 beforeCreate 和 created 之前执行,创建的是 data 和 method

2、onBeforeMount() : 组件挂载到节点上之前执行的函数;

3、onMounted() : 组件挂载完成后执行的函数;

4、onBeforeUpdate(): 组件更新之前执行的函数;

5、onUpdated(): 组件更新完成之后执行的函数;

6、onBeforeUnmount(): 组件卸载之前执行的函数;

7、onUnmounted(): 组件卸载完成后执行的函数;

5.组合式API组件通讯

父传子

父组件
<script setup>
import { ref } from 'vue'
//语法糖下局部组件无需注册直接可以使用  引入即可
import HEkkoWord from '../components/HelloWorld.vue'
const username = ref({ a: 123 })
const num = ref(123)
</script>
<template>
  <div>
    <!-- 父子局给子组件绑定属性 -->
    <HEkkoWord :username="username" :abc="num"></HEkkoWord>
  </div>
</template>
子组件
<script setup>
//在子组件里面创建一个defineProps接收数据
const props = defineProps({
  username: Object,// 二种都行
  abc: {
    type: Number,
    required: true  //二种都行
  }
})
//在js中使用传过来的数据
console.log(props.abc);
</script>

<template>
  <div class="greetings">
    {{ username }}
    {{ abc }}
  </div>
</template>

子传父

子组件里面
<script setup>
import { ref, defineEmits } from 'vue'
const str = ref('你好,我是李某人')
//1.通过defineEmits(['abc'])  emit('abc', str)
const emit = defineEmits(['abc'])
const btn = () => {
  emit('abc', str)
}

</script>

<template>
  <div class="greetings">
    <button @click="btn">子组件</button>
  </div>
</template>

父组件
<script setup>
//语法糖下局部组件无需注册直接可以使用  引入即可
import HEkkoWord from '../components/HelloWorld.vue'
const getbtn = (msg) => {
  console.log(msg.value, 123);
}
</script>
<template>
  <div>
    <!-- 绑定事件 子组件事件->父组件事件 -->
    <HEkkoWord @abc="getbtn"></HEkkoWord>
  </div>
</template>
<style></style>

6.组合式API,模板引用 ref操作dom

<script setup>
import HelloWorld from '../components/HelloWorld.vue';
import { onMounted, ref } from 'vue';
//调用ref函数-> ref对象
const str = ref(null)
const cover = ref(null)
const getbtn = () => {

}
//组件挂载完毕之后才能获取
onMounted(() => {
  str.value.style.color = 'red'
  console.log(str.value);
  console.log(cover.value); //打印组件内容
})
</script>
<template>
  <div>
    <!-- 通过ref标识绑定ref对象-->
    <div ref="str">123s</div>
    <HelloWorld ref="cover"></HelloWorld>
  </div>
</template>

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

<script setup>
import { ref, defineEmits } from 'vue'
const str = ref('你好,我是李某人')
//1.通过defineEmits(['abc'])  emit('abc', str)
const emit = defineEmits(['abc'])
const btn = () => {
  emit('abc', str)
}
defineExpose({
  str
})
</script>

7.跨层传递普通数据 (爷组件->跳过儿组件直接传给孙组件)

顶层组件传递:provide ('data-key',传的对象)(普ruai的)

<script setup>
import { provide, ref } from 'vue';
import HelloWorld from '../components/HelloWorld.vue';
//传递数据
provide('data-key', '我是爷爷传过来的')
//传送响应式数据
const count = ref(0)
provide('num-key', count)
setTimeout(() => {
  count.value = 123
}, 3000)
</script>
<template>
  <div>
    <!-- 通过ref标识绑定ref对象-->
    <div ref="str">孙子</div>
    <HelloWorld ref="cover"></HelloWorld>
  </div>
</template>

底层组件接收:inject('data-key')  //包括 儿子组件 孙子组件

<script setup>
import { inject } from 'vue';
//获取顶层组将传过来的数据 inject
const message = inject('data-key')
const num = inject('num-key')
</script>
<template>
  <div>
    孙组件:{{ message }}------{{ num }}
  </div>
</template>

底层组件调用方法修改底层组件中的数据

<script setup>
import { provide, ref } from 'vue';
import HelloWorld from '../components/HelloWorld.vue';
provide('data-key', '我是爷爷传过来的')
const count = ref(0)
//传过去一个函数
provide('num-key', count)
const fun = () => {
  count.value++
}
provide('setfun', fun)
</script>

底层通过按钮调用这个函数

<script setup>
import { inject } from 'vue';

const message = inject('data-key')
const num = inject('num-key')
const setfun = inject('setfun')
console.log(setfun);
</script>
<template>
  <div>
    孙组件:{{ message }}------{{ num }}
    <button @click="setfun">点击</button>
  </div>
</template>

8.pinia(皮妮儿)状态管理库,是vuex状态管理工具的替代品

创建一个store/counter.js

import { ref, computed } from "vue";
import { defineStore } from "pinia";

export const useCounterStore = defineStore("counter", () => {
  //定义数据
  const count = ref(1);
  //定义修改数据的方法(action 同步+异步)
  const doubleCount = computed(() => count.value * 2);
  function increment() {
    count.value++;
  }
  //已对象的方式return供组件使用
  return { count, doubleCount, increment };
});

导入组件

<script setup>
import { useCounterStore } from '../stores/counter.js'
const counter = useCounterStore()
console.log(counter.doubleCount, 123);
</script>
<template>
  <div class="about">123s
    <h1>{{ counter.doubleCount }}</h1>
    <button @click="counter.increment">{{ counter.count }}</button>
  </div>
</template>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值