vue3 入门写法

VUE-3

生命周期钩子函数

import {defineComponent,onUnmounted,onMounted} from "vue";

export default defineComponent({
    setup() {
        console.log("setup");
        // 原vue2.0写法mounted(){'代码'}改为onUnmounted(()=>{'代码'});
        onUnmounted(()=>{
            console.log("onUnmounted");
        });
        onMounted(()=>{
            console.log("onMounted_1");
        })
        // 可以多次调用...
        onMounted(()=>{
            console.log("onMounted_2");
        })
        //.....其他的生命周期钩子函数自己去查一下
    },
    beforeCreate() {
        console.log("beforeCreate");
    },
    created() {
        console.log("created");
    },
})

// 结果为beforeCreate....setup....created....onUnmounted....onMounted_1....onMounted_2

data定义

Ref

定义各种类型的数据进行双向绑定...
const info_1 = ref(1); // 普通类型
const info_2 = ref({ // 复杂数据类型
    value : 1
})
const info_3 = ref([1,2,3,4]) // 复杂数据类型
获取ref值
const info_1 = ref(1);
/**
* ref获取值
* 在setup中一定要用 .value 去获取,在template模板中使用则不用,直接info_1就可以拿到
*/
let getInfo_1 = info_1.value;

reactive

只能定义对象类型数据进行双向绑定
const info_1 = reactive({
    value : 1
})
获取reactive值
const info_1 = reactive({
    value : 1
})
/**
* reactive获取值
* 无论在setup还是template模板都可以直接拿到
*/
let getInfo_1 = info_1;

具体使用场景

<template>
    {{viewInfo_1}}  <!-- 没有retrun是没办法在模板获取的-->
    {{viewInfo_2}}  <!-- 显示为2 -->
    {{viewInfo_3}}  <!-- 显示为3 -->
    {{viewInfo_4}}  <!-- 显示为4 -->
</template>
<script>
    import { defineComponent,ref,reactive} from "vue";
    export default defineComponent({
        setup(){
            let viewInfo_1 = 1; // 定义普通数据
            let viewInfo_2 = 2; // 定义普通数据
            const viewInfo_3 = ref(3); // 定义任何双向绑定数据
            const viewInfo_4 = reactive({ // 定义对象类型双向绑定数据
                value : 4
            });
            retrun {
                // 没有retrun是没办法在模板获取的...
                viewInfo_2,
                viewInfo_3,
                viewInfo_4,
            }
        } 
    )}
</script>

watch使用

import {defineComponent,watch,ref,reactive} from "vue";

export default defineComponent({
    const refValue = ref(1);
    const refValue2= ref(2);
    const refValue3 = reactive({
        value : 3
    });
    // 基本用法 
    watch(()=>console.log(refValue.value));
    // 指定数据源
    watch(refValue2,(Value2,oldValue)=>{
        console.log(Value2,oldValue);
    });
    // 监听reactive
    watch(() => refValue3.value, (value, oldValue) => {
        console.log(value, oldValue)
    });
    // 监听多个数据源
    watch(
      [refValue,refValue2],
      ([value,value2],[oldValue,oldValue2])=>{
          console.log('------')
      },
      {
        lazy:true, //组件第一次创建不调用
        deep:true, //深度监听
      }
    )
})

父子传值

import {defineComponent} from "vue";

export default defineComponent({
    // 必须在这里定义,下面的setup参数才有相对于的props值
    props: {
        propsValue1:{
            type:Number, // 类型,多类型可以这样写type:[String,Number,Boolean]
            required: true, // 是否必传
            default:1 // 默认值
        }
    },
    setup(props,{ emit }) { // 结构emit进行父子传值,感兴趣可以自己去输出看看第二个参数是什么...
        console.log(props.propsValue1);
        const value_ = 1;
        function(){
            emit("emitValue", value_);
        }
    },
})

// 输出为默认值 1

Refs获取Dom元素

<template>
    <div ref="domDiv"></div>

    <!-- VUe3是可以有多个根节点的,这样写没问题的 -->
    <div></div>
</template>
<script>
    import { defineComponent,ref,onMounted} from "vue";
    export default defineComponent({
        setup(){
            const domDiv = ref(null); // 一定要定义跟ref一样的字段才能获取到相对应Dom
            onMounted(()=>{
                domDiv.value.style.color = "red"
            });
            return{
                domDiv
            }
        }

    )}
</script>

组件使用

<template>
    <Mycomponent />
</template>
<script>
    import { defineComponent} from "vue";
    import Mycomponent form './Mycomponent.vue'
    export default defineComponent({
        setup(){
        },
        components:{
            Mycomponent
        }
    )}
</script>

nextTick使用

import { nextTick} from "vue";
setup(){
    nextTick(()=>{
        console.log('nextTick')
    })
}

路由获取参数

// 这里我用URL参数来做例子,路由参数也是同理
import { defineComponent,onMounted} from "vue";
import { useRoute } from "vue-router";
export default defineComponent({
    setup(){
        let params = useRoute().query; // URL参数,一定要写在setup函数第一层,不然则无效
        console.log(params); // {参数1:value1,参数2:value2};
        onMounted(()=>{
            let parmams2 = useRoute() // 在onMounted获取是undefined....
        });
        return{
        }
    }
)}

指令v-memo

常用场景:在v-for中使用可在数据源修改后对DOM的重构速度进行优化

文档:https://v3.cn.vuejs.org/api/directives.html#v-memo

Style特性

动态css样式

<template>
  <div class="text">hello</div>
</template>

<script>
export default {
  data() {
    return {
      color: 'red',
     
    }
  }
}
</script>

<style>
.text {
  color: v-bind(color);
}
</style>

Vue3 CSS v-bind 支持 JavaScript 表达式 (需要用引号包裹起来),所以 less 中拼接使用需要用引号引起来,用 + 号拼接即可,例如:

.tree-node-label-width-2 {
  width: v-bind("(treeContentWidth - 18 * 1) + 'px'");
}

VUE-3.2 + TS

setup单文件组件写法

<template>
    <div ref="test"></div>
</template>
<script setup lang='ts'> // Vue3.2 script标签写法
/**
*1.在这里面写的VUE3代码就不需要再retrun返回了...template中可以直接使用
*2.用setup单文件组件写出来的VUE模块默认是闭合的,其他组件是无法使用ref直接获取
*3.ref注意项---重点坑...若模板里如果定义了ref,脚本里要写上对应的变量。否则编译后会undefined错误
*  开发测试可能不会出错,在生产环境中即会报错导致页面打不开
*/ 
import { ref } from "vue";
// ts写法: const name = ref<类型定义>(默认值);
const test = ref<null|HTMLElement>(null); 
</script>

定义props/emit的方法和使用

props参数定义和使用

import { onMounted } from "vue";
// 基本定义---简单数据类型
const props = defineProps({
    foo:String
});
// 复杂数据类型
interface testStruct{
    name:string;
    value:number;
}; // ts定义一个接口
// 不带默认值
const props = defineProps<{
    testList: testStruct[];
    value: string;
}>();
// 带默认值
const props = withDefaults(defineProps<{
    testList: testStruct[];
    value: string;  
}>(), {
    testList:()=>[],
    value: '测试'
});
// ----------------------------------------
// 使用
onMounted(()=>{
    console.log(props.value); // 测试
})

emits事件定义和使用

<template>
    <div @click="clickHander(1)">按钮</div>
</template>
<script setup lang='ts'>
// 普通定义
const emits = defineEmits(["change","btnHander"]);
// TS定义写法   ps:其实在TS写法中使用一般普通定义就可以了,很少使用这种写法
const emits = defineEmits<{
  (e: 'change'): void
  (e: 'btnHander', id: number): void
}>()
// 上面按钮点击触发的方法
function clickHander(id:number){
    // 使用emits
    emits("btnHander",id);
}
</script>

组件传值

使用 <script setup> 的组件是默认关闭的,也即通过模板 ref 或者 $parent 链获取到的组件的公开实例,不会暴露任何在 <script setup> 中声明的绑定。

简单描述:若父组件想通过ref调用子组件或者子组件想通过$parent调用父组件中的变量和方法 必须使用以下定义,否则获取过来的ref为

子组件

<template>
    子组件
</template>
<script setup lang='ts'>
const ChildrenValue = ref(1);
function ChildrenFun (){
    console.log('我是子组件')
};
// 暴露方法和数据源
defineExpose({
    ChildrenValue,
    ChildrenFun
    });
// 暴露TS定义
export interface API {
    ChildrenValue: number;
    ChildrenFun: Function;
}
</script>

父组件

<template>
    <ChildrenVue ref="ChildrenRef" />
</template>
<script setup lang='ts'>
import { ref, nextTick } from "vue";
// 引入子组件,setup单文件组件中,不需要注册组件就可以直接使用
import ChildrenVue, {
  API as ChildrenAPI,
} from "./Children";
const ChildrenRef = ref<null|ChildrenAPI>(null);
nextTick(()=>{
    if(ChildrenRef.value){
        ChildrenRef.value.ChildrenFun(); // 输出‘我是子组件’
    }
})
</script>

await

<script setup>
// 可以直接使用await,编译后会自动识别为async setup()
const post = await fetch(api).then(r => console.log(r));
</script>

attrs 的接收方式变化

// 标准组件的写法
export default defineComponent({
  setup (props, { attrs }) {
    // attrs 是个对象,每个 Attribute 都是它的 key
    console.log(attrs.class);

    // 如果传下来的 Attribute 带有短横线,需要通过这种方式获取
    console.log(attrs['data-hash']);
  }
})
// 导入 useAttrs 组件
import { useAttrs } from 'vue'

// 获取 attrs
const attrs = useAttrs()

// attrs是个对象,和 props 一样,需要通过 key 来得到对应的单个 attr
console.log(attrs.msg);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,651评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,468评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,931评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,218评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,234评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,198评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,084评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,926评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,341评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,563评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,731评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,430评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,036评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,676评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,829评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,743评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,629评论 2 354

推荐阅读更多精彩内容