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>