纸上得来终觉浅,Vue3 新语法练起来

vue

搜集资源

Vue3 入门指南与实战案例
Vue在线演练场
Vue3.0中Ref与Reactive的区别是什么
Composition API RFC
Vue.js 中使用defineAsyncComponent 延迟加载组件
2022年必会Vue3.0学习 (强烈建议)

10.useSlots用法

父组件

<template>

<!-- 子组件 -->

<ChildTSX>

<!-- 默认插槽 -->

<p>I am a default slot from TSX.</p>

<!-- 命名插槽 -->

<template #msg>

<p>I am a msg slot from TSX.</p>

</template>

</ChildTSX>

</template>

<script setup lang="ts">

import ChildTSX from '@cp/context/Child.tsx'

</script>

子组件

<script lang="ts" setup>

// 注意:这是一个 .tsx 文件

import { useSlots } from 'vue'

const slots = useSlots()

const ChildTSX = ()=>{

// 渲染组件

return () => (

<div>

{/* 渲染默认插槽 */}

<p>{ slots.default ? slots.default() : '' }</p>

{/* 渲染命名插槽 */}

<p>{ slots.msg ? slots.msg() : '' }</p>

</div>

)

}

}

export default ChildTSX

</script>

9.jsx语法,要借助插件@vitejs/plugin-vue-jsx

<script lang="tsx" setup>

const jsxNode = () => {

return <div>text</div>;

};

</script>

<template>

<jsxNode />

</template>

8. 动态class的设置方法

<script setup>

import { ref } from 'vue'

const msg = ref('Hello World!')

</script>

<template>

<h1 :class="[`red ${msg === 'Hello World!' ? 'green':''}`]">{{ msg }}</h1>

<input v-model="msg">

</template>

<style scoped>

.red{

color:red;

}

.green{

color:green

}

</style>

7.父子组件通信 props/emit方式

父组件

<template>

<Child

ref="child"

title="用户信息"

:index="1"

:u

:user-name="userInfo.name"

@update-age="updateAge"

/>

</template>

<script lang="ts" setup>

import { ref, onMounted } from 'vue'

import Child from '@cp/Child.vue'

interface Member {

id: number,

name: string

}

const child = ref<typeof Child | null>(null)

const userInfo: Member = {

id: 1,

name: 'Petter'

}

onMounted(() => child?.value?.childMethod)

const updateAge = (age: number) => {

console.log(age);

}

</script>

子组件

<template>

<p>标题:{{ title }}</p>

<p>索引:{{ index }}</p>

<p>用户id:{{ uid }}</p>

<p>用户名:{{ userName }}</p>

</template>

<script lang="ts" setup>

import { withDefaults, defineProps, defineEmits, toRefs, defineExpose } from 'vue';

const props = withDefaults(defineProps<{

title: string;

index: number;

uid: number;

userName: string;

}>(), { userName: 'zhangsan' });

const { title, index, uid, userName } = toRefs(props);

const emit = defineEmits(['update-age']);

setTimeout(() => {

emit('update-age', 22);

}, 2000);

const childMethod = () => {

console.log('我是子组件的方法')

}

defineExpose({ childMethod })

</script>

6.使用ref操作dom

<template>

<!-- 挂载DOM元素 -->

<p ref="msg">留意该节点,有一个ref属性</p>

<!-- 挂载DOM元素 -->

</template>

<script lang="ts" setup>

import { onMounted, ref } from "vue";

// 定义挂载节点,声明的类型详见下方附表

const msg = ref<HTMLElement | null>(null);

// 请保证视图渲染完毕后再执行节点操作 e.g. onMounted / nextTick

onMounted(() => {

// 比如获取DOM的文本

console.log(msg?.value?.innerText);

});

</script>

5.props用法

<script lang="ts" setup>

import {withDefaults,defineProps} from 'vue';

const props = withDefaults(defineProps<{

btnName: string;

noBtn?: boolean;

doAction: () => void;

classStyle?: string;

}>(),{

noBtn:true, // 设置默认值

classStyle:''

});

const mActionClass=`m-action ${props.classStyle}`;

<script>

4.生命周期函数

vue2和vue3生命周期对比

beforeCreate -> 使用 setup()

created -> 使用 setup()

beforeMount -> onBeforeMount

mounted -> onMounted

beforeUpdate -> onBeforeUpdate

updated -> onUpdated

beforeDestroy -> onBeforeUnmount

destroyed -> onUnmounted

errorCaptured -> onErrorCaptured

<template>

<div class="home">

<p>{{ count }}</p>

<p>{{ state.a }}</p>

<button @click="add">加1</button>

</div>

</template>

<script lang="ts" setup>

import {

ref,

reactive,

onBeforeMount,

onMounted,

onBeforeUpdate,

onUpdated,

onBeforeUnmount,

onUnmounted,

onErrorCaptured,

onRenderTracked,

onRenderTriggered,

onActivated,

onDeactivated,

} from "vue";

const count = ref(1);

const state = reactive({ a: 10 });

const add = () => {

count.value += 1;

state.a = state.a + 1;

};

onBeforeMount(() => {

console.log("onBeforeMount");

});

onMounted(() => {

console.log("onMounted");

});

onBeforeUpdate(() => {

console.log("onBeforeUpdate");

});

onUpdated(() => {

console.log("onUpdated");

});

onBeforeUnmount(() => {

console.log("onBeforeUnmount");

});

onUnmounted(() => {

console.log("onUnmounted");

});

onErrorCaptured((evt) => {

console.log("onErrorCaptured", evt);

});

// 只执行一次,有几个响应式api,执行几次

onRenderTracked((evt) => {

console.log("onRenderTracked", evt);

});

// 行为如同onUpdated,每次有数据更新都会执行

onRenderTriggered((evt) => {

console.log("onRenderTriggered", evt);

});

onActivated(() => {

console.log("onActivated");

});

onDeactivated(() => {

console.log("onDeactivated");

});

</script>

4. shallowReactive, shallowRef, readonly,shallowReadonly,toRaw,markRaw函数区别

shallowReactive、shallowRef的之间的区别

shallowReactive:浅监视

shallowRef:不做监视

readonly和shallowReadonly

readonly:只读属性的数据,深度只读

const state2 = readonly(state)

shallowReadonly:只读的数据,浅只读的

toRaw和markRaw

toRaw将代理对象变成普通对象,数据变化,界面不会进行更新

const user = toRaw(state);

markRaw标记的对象数据,从此以后都不能在成为代理对象了

const likes = ['吃',‘喝’]

state.likes = markRaw(likes)

<template>

<h4>

<button @click="triggerShallowReactiveRender">

改变第一层才会渲染

</button>

</h4>

<p>{{ shallowReactiveState.a }}</p>

<h4>

<button @click="triggerShallowRefRender">

失去响应式

</button>

</h4>

<p>{{ shallowRefState.a }}</p>

</template>

<script setup>

import { readonly,reactive, shallowReactive, shallowRef, toRaw } from "vue";

// shallowRef 与shallowReactive

// shallowRef 与shallowReactive创建的是非递归的响应对象,shallowReactive创建的数据第一层数据改变会重新渲染dom

const shallowReactiveState = shallowReactive({

a: "initShallowReactiveState",

b: {

c: "c",

},

});

//如果不改变第一层 只改变其他的数据 页面不会重新渲染,例如:

shallowReactiveState.b.c = 2;

//改变第一层的数据会导致页面重新渲染

const triggerShallowReactiveRender=()=>{

shallowReactiveState.a = "changeShallowReactiveState";

}

// shallowRef创建的对象没有响应式特性

const shallowRefState = shallowRef({

a: "initShallowRefState",

b: {

c: "c",

},

});

const triggerShallowRefRender=()=>{

//失去响应式--除非对整个对象重新赋值或者使用triggerRef(shallowRefState)触发页面更新

shallowRefState.a = "changeShallowRefState";

}

// toRaw ---只修改数据不渲染页面

var obj = { name: "test" };

var toRawState = reactive(obj);

var raw = toRaw(toRawState);

//并不会引起页面的渲染,而obj.name,toRawState.name的值均已改变

setTimeout(()=>raw.name = "zs",2000);

// 不允许修改对象的值

const readonlyState = readonly({a:1,b:2});

// 赋值会引起警告

readonlyState.a=2;

</script>

3. toRefs和toRef的用途

借助toRefs可以在template部分,直接使用结构后的对象单个键值,写法简洁,却不失响应式。

toRef是转换reactive对象的单个值

<template>

<ul class="user-info">

<li class="item">

<span class="key">ID:</span>

<span class="value">{{ id }}</span>

</li>

<li class="item">

<span class="key">name:</span>

<span class="value">{{ name }}</span>

</li>

<li class="item">

<span class="key">age:</span>

<span class="value">{{ age }}</span>

</li>

<li class="item">

<span class="key">gender:</span>

<span class="value">{{ gender }}</span>

</li>

</ul>

</template>

<script lang="ts" setup>

import { reactive, toRef, toRefs } from "vue";

interface Member {

id: number;

name: string;

age: number;

gender: string;

}

// 定义一个reactive对象

const userInfo: Member = reactive({

id: 1,

name: "Petter",

age: 18,

gender: "male",

});

// 结构reactive对象,它的字段全部是ref变量

const { id, age, gender } = toRefs(userInfo);

const name: string = toRef(userInfo, 'name');

// 2s后更新userInfo

setTimeout(() => {

userInfo.id = 2;

userInfo.name = "Tom";

userInfo.age = 20;

}, 2000);

</script>

2. 响应式数据

ref可以定义任何类型的数据,但是定义数据和对象时,在script部分使用时,赋值和取值,不如reactive方便

reactive只能用于数组,对象类型。

ref的本质是通过reactive创建的,Ref(10)=>Reactive({value:10});

reactive的本质是将每一层的数都解析成proxy对象,reactive 的响应式默认都是递归的,改变某一层的值都会递归的调用一遍,重新渲染dom。

<template>

<p>{{count}}</p>

<button @click="add">加1</button>

<p>{{info.name}}</p>

<button @click="changeName">改姓名</button>

</template>

<script lang="ts" setup>

import { reactive, ref } from 'vue';

interface Info{

name:string;

age:number;

}

// 响应式基本类型用ref

const count = ref<number>(0);

// 响应式引用类型用reactive

const info:Info = reactive({ age: 100,name:'zhangsan' });

const add = () => {

// 基本类型赋值时,是赋值给value属性

count.value += 1;

};

const changeName = () => {

info.name="lisi";

};

</script>

1.路由取值和跳转

<script lang="ts" setup>

import { useRoute, useRouter } from 'vue-router';

const route = useRoute();

const router = useRouter();

// 获取路由信息

console.log(route.query.id);

// 编程式路由跳转

const jump = ()=> {

router.push({ path: `/about` , query:{id:'xxx}});

};

</script>

以上是 纸上得来终觉浅,Vue3 新语法练起来 的全部内容, 来源链接: utcz.com/z/379536.html

回到顶部