Vue3基础
Vue3学习笔记
目录
按需导入:defineComponent
import {defineComponent} from 'vue' export default defineComponent({})
定义变量
setup
变量需要在setup中定义,在生命周期beforeCreated之前执行,且只执行一次,在组件还没有加载时就生成,所以this无法使用,不能通过this去调用data、computed、methods、props;并且所有的compostionAPI相关回调函数都不可用
返回值:返回值是一个对象,内部的属性和方法是给html使用的
返回对象中的属性会与data函数返回对象的属性合并为组件对象属性/方法
setup不能是async含函数,:返回值不再是return对象,而是promise,模板看不到return对象中的属性数据
ref
1.一般用来定义一个基本数据类型的响应式数据,js中需要操作使用ref.value获得数据,模板中不需要.value
2.获取页面中的元素
<input ref="inputRef" />
setup(){ const inputRef = ref<HTMLElement|null>(null)
onMounted(()=>{inputRef.value && inputRef.value.focus()}) }
reactive
定义多个数据的响应式
返回一个proxy代理对象,被代理者就是reactive中的对象
不能直接结构出代理对象的属性,否则会丢失响应式,需要使用toRefs来结构
//ref方式,需要先引入ref,
import {defineComponent,ref} from 'vue'
export default defineComponent({})
setup(){
let name = ref('tom'),
let age = ref(18),
return {//必须返回
name,
age
}
}
// reactive方式,可搭配toRefs使用
import {defineComponent,reactive,toRefs} from 'vue'
export default defineComponent({})
setup(){
let data = reactive({
name:'tom',
age:19
})
return {//必须返回
data //直接返回data
...toRefs(data) //结构出data中的属性
}
}
方法的定义和使用
方法定义在setup中需要return出去
如果使用ref定义变量x则取值时需要x.value,使用reactive定义对象只需正常取值即可
<template>
<div>
<div @click="nameClick">{{name}}</div>
<div @click="ageClick">{{age}}</div>
</div>
</template>
<script>
import { defineComponent,ref,reactive,toRefs } from "vue";
export default defineComponent({
name: "setupDemo",
props: {},
components: {
},
setup(props, ctx) {
let name = ref('Tom')
const data = reactive({
age:99,
gender:'男'
})
let nameClick = ()=>{
console.log(name.value);//ref定义的变量,取值需要变量.value
}
let ageClick = ()=>{
console.log(data.age);//reactive定义的对象,正常取值即可
}
return{
name,
...toRefs(data),
nameClick,//导出方法,调用方法与vue2相同
ageClick
}
},
});
</script>
父子组件传值
{immediate:true,deep:true}
immediate默认会执行一次watch,deep:深度监视
//父组件
<template>
<div>
<div>这是父组件</div>
<child :msg="msg" @send="send"></child>
</div>
</template>
<script>
import { defineComponent, ref } from "vue";
import child from "../children/Child.vue";
export default defineComponent({
components: {
child,
},
setup(props, ctx) {
let msg = ref("parent");
let send = (val)=>{
console.log(val)
}
return {
msg,
send
};
},
});
</script>
//子组件
<template>
<div>
<div>父->子组件的值{{msg}}</div>
<button @click="send">子->父组件的值</button>
</div>
</template>
<script>
import { defineComponent ,ref} from "vue";
export default defineComponent({
props:{
msg:{
type:String,
default:'默认值'
}
},
setup(props,ctx){
console.log(props.msg)
let childMsg = ref('子组件的数据')
let send=()=>{
ctx.emit('send',childMsg.value) //通过ctx.emit分发事件
}
return {
childMsg,
send
}
}
})
</script>
//stroe.js
import { createStore } from 'vuex'
export default createStore({
state: {
list:[
{ title: "吃饭", complete: true },
{ title: "睡觉", complete: false },
{ title: "敲代码", complete: false },
]
},
getters: {
},
mutations: {//同修改
addTodo(state,data){
state.list.push(data)
},
delList(state,data){
state.list.splice(data,1)
},
clear(state,data){
state.list = data
}
},
actions: {//异步修改
},
modules: {
}
})
//home.vue
<template>
<div class="container">
<div>
<nav-header></nav-header>
<nav-main></nav-main>
<nav-footer></nav-footer>
<button @click="toPage">跳转</button>
</div>
</div>
</template>
<script>
import { useStore } from "vuex";//引入vueStore
import { defineComponent, computed ,ref} from "vue";
export default defineComponent({
name: "Home",
setup(props, ctx) {
let ref = ref('Jack')
let store = useStore();
let router = useRouter();
//获取state时使用计算属性
let list = computed(() => {
return store.state.list;
},{immediate:true},deep:true);
let toPage = () => {
//使用query,可以用path/name来表示router的地址
router.push({
path: "/setupDemo",
query:{
name:name.value,
obj:JSON.stringify(obj)
}
});
//使用params只能使用name表示route地址
router.push = ()=>({
name:'setupDemo',//params跳转需要用name
params:{name:name.value,age:19,gender:'女'}
})
};
return {
store,
list,
toPage,
};
},
</script>
监听器
immediate默认会执行一次watch,deep:深度监视(使用watchEffct则无需添加改属性)
watch(()=>{ {immediate:true,deep:true} })
监听多个变量且变量不为响应式的值时使用[()=>变量1,()=>变量2,()=>{函数体}]
watch([() => num1, () => num2], () => { console.log("====="); });
生命周期
export default defineComponent({
name: "AA",
setup() {
console.log("setup");
onBeforeMount(() => {
console.log("onBeforeMount");
});
onMounted(() => {
console.log("onMounted");
});
onBeforeUpdate(() => {
console.log("onMounted");
});
onUpdated(() => {
console.log("onUpdated");
});
onBeforeUnmount(() => {
console.log("onBeforeUnmount");
});
onUnmounted(() => {
console.log("onBeforeUnmount");
});
},
});
Hook函数
//hook函数
import { ref, onMounted, onBeforeUnmount } from "vue";
export default function () {
const x = ref(-1);
const y = ref(-1);
const clickHandler = (event: MouseEvent) => {
x.value = event.pageX;
y.value = event.pageY;
};
onMounted(() => {
window.addEventListener("click", clickHandler);
});
onBeforeUnmount(() => {
window.removeEventListener("click", clickHandler);
});
return {
x,
y,
};
}
//getPageXY.vue
<template>
<h2>自定义Hook函数</h2>
<h2>x:{{ x }},y:{{ y }}</h2>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import clickHandler from "@/hooks/useEventPage";
export default defineComponent({
name: "getPageXY",
setup() {
const { x, y } = clickHandler();
return {
x,
y,
};
},
});
shallowReactive和shallowRef
shallowReactive:只处理对最外层属性的响应式(浅响应式);结构较深且内层对象不会变化时使用
shallowRef:只处理value的响应式,不处理reactive的对象;产生的新对象替换当前对象
readonly和shallowReadonly
readonly:对象深度只读
shallowReadonly:对象浅只读,二层及更深层的数据都是可更改的
toRaw和markRaw
toRaw:把代理对象变为普通对象,数据已经变化,但是界面无响应
markRaw:被markRaw标记的对象数据从此之后都不能再成为代理对象
provide和inject
跨层级组件的数据传递
//父组件 provide('唯一标识',传递的变量) //子组件/孙子组件 inject('对应父组件的唯一标识')
响应式数据的判断
isRef、isReactive、isReadonly、isProxy
Suspense(不确定的)
等待异步组件渲染时的额外内容,提高用户体验
//parent.vue
<template>
<h1>Suspense组件的使用</h1>
<Suspense>
<!-- 异步组件 -->
<template #default>
<!-- <AsyncComponent></AsyncComponent> -->
<AsyncAddress></AsyncAddress>
</template>
<!-- 等待时显示的内容 -->
<template v-slot:fallback> <div>loading...</div> </template>
</Suspense>
</template>
<script lang="ts">
import { defineComponent } from "vue";
// vue2的动态引入方法在vue中无法使用
// const AsyncComponent = () => import("./components/Child.vue");
// vue3动态引入组件写法
// const AsyncComponent = defineAsyncComponent(
// () => import("./components/Child.vue")
// );
// import AsyncComponent from "./components/Child.vue";
import AsyncAddress from "./components/AsyncAddress.vue";
export default defineComponent({
name: "APP",
components: {
// AsyncComponent,
AsyncAddress,
},
setup() {
console.log(111);
},
});
</script>
<style scope lang="scss"></style>
//child.vue
<template>
<h1>AsyncAddress组件</h1>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import axios from "axios";
export default defineComponent({
name: "APD",
setup() {
return axios.get("/data/address.json").then((res) => {
return res.data;
});
},
});
</script>
<style scope lang="scss"></style>
更多推荐
所有评论(0)