Vue3 语法

Vue3 语法

<template> 中使用的语法,Vue3 和 Vue2 几乎没有差别。但是在 <script> 中使用的语法,Vue3 有比较大的变化。

一、template 根节点

在 Vue3 中,<template> 不再需要根节点。

<template>
    <div></div>
    <h1></h1>
</template>

二、子组件渲染

在 Vue3 中,父组件中如果要渲染子组件,只需要“引入”和“渲染”两个步骤。

<template>
    <HelloWorld />
</template>

<script setup>
    import HelloWorld from './components/HelloWorld.vue';
</script>

三、setup

Vue3 从最早的测试版,然后到正式版,以及正式版后续的新提案,每一个版本的 setup 的语法都不太一样。目前我们采用最新版的语法:

<script setup>

</script>

在 VSCode 中,可以通过快捷键 v3 来自动生成该版本的组件基本代码。

四、组件的数据

1、ref

<template>
    <h1>计数器:{{ count }}</h1>
</template>

<script setup lang="ts">
import { ref } from 'vue';
const count = ref(0);
console.log(count.value);
</script>

语法说明:

  1. Vue3 的组件中可以通过 ref() 来定义组件内部数据;
  2. 每个组件中使用 ref 时,都需要先引入;
  3. 在调用 ref() 方法,可以传递一个参数来作为组件内部数据的初始值;
  4. ref() 定义的数据,在 template 中使用时,可以直接通过变量名来访问;
  5. ref() 定义的数据,在 script 中使用时,必须通过 变量名.value 来访问;

2、reactive

<template>
    <h1>计数器:{{ state.count }}</h1>
</template>

<script setup lang="ts">
    import { reactive } from 'vue';
    const state = reactive({
        count: 0
    });
    console.log(state.count);
</script>

语法说明:

  1. Vue3 的组件中可以通过 reactive() 来定义组件内部数据;
  2. 每个组件中使用 reactive 时,都需要先引入;
  3. 在调用 reactive() 方法,需要传递一个数组或对象来作为组件数据的初始值;
  4. reactive() 定义的数据,在 templatescript 中的访问方式是一样的;
  5. 通过 reactive() 定义的数组或对象,在修改时不能修改数组或对象的地址

五、组件的事件

<template>
    <button @click="increment">+1</button>
</template>

<script setup lang="ts">
const increment = () => {
    console.log("事件方法");
}
</script>

六、计算属性

<script setup lang="ts">
    import { computed } from 'vue';
    const 变量 = computed(() => {
        return 计算结果;
    })
</script>

七、侦听器

<script setup lang="ts">
import { ref, watch } from 'vue';
const count = ref(0);
watch(() => count.value, (newValue, oldValue) => {
    console.log('count.value 发生变化了', newValue, oldValue);
});
</script>

https://blog.csdn.net/m0_49515138/article/details/128250061

语法说明:

  1. watch() 在使用前需要先引入;
  2. watch() 接收两个函数作为参数,第一个函数的返回值就是需要侦听的数据,当侦听的数据发生变化时,会执行第二个函数;

深度侦听和立即侦听

watch(() => count.value, (newValue, oldValue) => {
    console.log('count.value 发生变化了', newValue, oldValue);
}, {
    immediate: true,
    deep: true
});

八、watchEffect

<script setup lang="ts">
import { ref, watchEffect } from 'vue';
const count = ref(0);
watchEffect(() => {
    console.log('你好', count.value);
})
</script>

语法说明:

  1. watchEffect() 在使用前需要先引入;
  2. watchEffect() 需要接收一个函数作为参数;
  3. watchEffect() 会自动监听函数中用到的所有数据,当函数中任意数据发生改变时,watchEffect() 都会重新执行;

watch 和 watchEffect 的区别

  1. 默认情况下,watchEffect 在页面首次刷新时会执行一次,而 watch 不会;
  2. watch 可以接收到数据变化前后的值,而 watchEffect 没有;
  3. watch 需要指定侦听的数据,watchEffect 是自动侦听函数中用到的数据;

九、生命周期函数

Vue2Vue3
beforeCreate
created
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeDestroyonBeforeUnmount
destroyedonUnmounted

示例代码:

import { onMounted } from 'vue';
onMounted(() => {
    console.log('组件挂载完成')
})

十、组件传值

1、父传子:prop

Vue3 中,和 Vue2 一样,也是通过 prop 来实现父组件给子组件传值。

父组件传递数据和 Vue2 的语法没有区别,但是子组件在接收 props 数据时,Vue3 的语法如下:

<template>
    <div>
        <h1>接收父组件传递的数据:{{ count }}</h1>
    </div>
</template>

<script setup lang="ts">
    const props = defineProps({
        count: Number
    });
    console.log(props.count);
</script>

2、子组件接受值

通过defineProps 来接受, defineProps是无须引入的直接使用即可

这是TS特有的:

<template>
    <div class="menu">
        菜单区域 {{ title }}
        <div>{{ data }}</div>
    </div>
</template>
 
<script setup lang="ts">
defineProps<{
    title:string,
    data:number[],
    obj:{
        type:Object,
        default(){
            return {}
        }
    }
}>()
</script>

3、TS 特有的默认值方式

withDefaults是个函数也是无须引入开箱即用,接受一个props函数第二个参数是一个对象设置默认值

type Props = {
    title?: string,
    data?: number[]
}
withDefaults(defineProps<Props>(), {
    title: "张三",
    data: () => [1, 2, 3]
})

4、子传父:自定义事件 defineEmits

Vue3 中,和 Vue2 一样,也是通过自定义事件来实现子组件给父组件传值。

父组件绑定自定义事件和 Vue2 的语法没有区别,但是子组件中触发自定义事件时,Vue3 的语法如下:

<template>
    <button @click="toFather">按钮</button>
</template>

<script setup lang="ts">
    const emit = defineEmits(['getData'])
    const toFather = () => {
        // 调用自定义事件,并传值
        emit('getData', 100);
    }
</script>
<template>
    <div class="menu">
        <button @click="clickTap">派发给父组件</button>
    </div>
</template>
 
<script setup lang="ts">
import { reactive } from 'vue'
const list = reactive<number[]>([4, 5, 6])
 
const emit = defineEmits(['on-click'])
const clickTap = () => {
    emit('on-click', list)
}
</script>

5、父组件接受子组件的事件

<template>
    <div class="layout">
        <Menu @on-click="getList"></Menu>
        <div class="layout-right">
            <Header></Header>
            <Content></Content>
        </div>
    </div>
</template>
 
<script setup lang="ts">
import Menu from './Menu/index.vue'
import Header from './Header/index.vue'
import Content from './Content/index.vue'
import { reactive } from 'vue';
 
const data = reactive<number[]>([1, 2, 3])
 
const getList = (list: number[]) => {
    console.log(list,'父组件接受子组件');
}
</script>

6、子组件暴露给父组件内部属性

通过defineExpose

我们从父组件获取子组件实例通过ref

 <Menu ref="menus"></Menu>
  const menus = ref(null)

这时候父组件想要读到子组件的属性可以通过 defineExpose暴露

const list = reactive<number[]>([4, 5, 6])
 
defineExpose({
    list
})

十一、ref、toRef、toRefs的区别

toRefs(obj):作用是将响应式对象中的所有属性转换为单独的响应式数据,原始数据变为普通对象,值是关联的

响应式数据展开后会失去响应式{}

<script lang="ts">
    import { reactive } from "vue";
    export default{
        setup(){
            const user = reactive<any>({
                name: "张三",
                age: 23,
                addr: {
                    province: "河南",
                    city: "郑州"
                }
            })
            return {
                ...toRefs(user);
                let name = toRef(user, "name")
            }
        }
    }
 </script>

toRef(obj, key):作用是将响应式对象中的某一个属性转换为响应式数据,接受两个参数,第一个是哪个对象,第二个是哪个属性

十二、isref() unref()

isref()检查一个值是否为ref对象
unref()如果参数是一个ref则返回它的value,否则返回参数本身
unref():是 val = isRef(val) ? val.value : val 的语法糖。


const valueRef = ref('');
const value = unref(valueRef);
if (!value) {
   console.warning('请输入要拷贝的内容!');
   return;
}

十三、defineExpose()

defineExpose():使用<script setup>的组件默认是关闭的,可以通过模板引用或者$parent链获取到组件的公开实例,不会暴露任何在 <script setup> 中声明的绑定

可以通过defineExpose()编译器宏来显示指定在<script setup>组件中要暴露出去的属性

<script setup>
import { ref } from 'vue'
const a = 1
const b = ref(2)

defineExpose({a, b})
</script>

十四、defineComponent()

在定义Vue组件时提供类型推导的辅助函数

十五、获取节点的原生dom对象

 <infoCard v-show='showInfoWindow' :ref="(el) => infoWindow = el"  />

 <script setup lang="ts">
     import { ref,  getCurrentInstance  } from "vue";
// 获取页面的实例对象
// const pageInstance = getCurrentInstance();

// 定义信息窗口
      window.infoWindow = new AMap.InfoWindow({
        // 使用自定义窗体
        isCustom: true,
        // 只有当组件渲染完毕后,拿到原生的dom对象
        content: infoWindow.value.$el, 
       // 只有当组件渲染完毕后,通过pageInstance才能拿到原生的dom对象
       //  content: pageInstance?.refs.infoWindow, 
        anchor: "bottom-left",
        offset: new AMap.Pixel(30, 0),
      });
 </script>

十六、toRaw获取原始对象

使用vue3.0时,因为底层是使用proxy进行代理的所以当我们打印一些值得时候是proxy代理之后的是Proxy
对象,Proxy对象里边的[[Target]]才是真实的对象。

1、通过vue中的响应式对象可使用 toRaw() 方法获取原始对象
//第一种获取target值的方式,通过vue中的响应式对象可使用toRaw()方法获取原始对象
import { toRaw } from 'vue'
let obj=toRaw(props.formAllValue)
2、通过json序列化之后可获取值
//第二种获取target值的方式,通过json序列化之后可获取值
JSON.parse(JSON.stringify(store.getters.menuList))

十七、getCurrentInstance

// 此段代码写入main.js中
app.config.globalProperties.$t = i18n.global.t;

import { getCurrentInstance  } from "vue";
const _this = getCurrentInstance()?.appContext.config.globalProperties ;

console.log(_this)

十八、h() createVNode()

h()函数和createVNode()函数都是创建dom节点,他们的作用是一样的,但是在VUE3中createVNode()函数的功能比h()函数要多且做了性能优化,渲染节点的速度也更快

h(标签, {属性},内容)
h(标签, {属性},[可以继续嵌套h()])
createVNode(标签, {属性},内容)
createVNode(标签, {属性},[可以继续嵌套createVNode()])
createVNode() 或者 h()中 设置ref

开发环境下可以正常使用,生产环境中报错Cannot read properties of null (reading 'refs')

解决方案:使用函数包含返回

<template>
  <el-button :plain="true" @click="openVn">VNode</el-button>
</template>
<script lang="ts" setup>
import { ref, h } from 'vue'
import { ElMessage } from 'element-plus'
const messageRef = ref()
const openVn = () => {
  ElMessage({
    message: () => h('div', { ref: messageRef }, [
      h('span', null, 'Message can be '),
      h('i', { style: 'color: teal' }, 'VNode'),
    ]),
  })
}
</script>

十九、markRaw()/shallowRef()/shallowReactive()

markRow():标记一个对象,使其永远不会变成一个响应式对象,跳过proxy代理;

toRaw():将一个由reactive生成的响应式对象转换为普通对象;

shallowRef():只处理基本数据类型的响应式,不进行对象的响应式处理;

shallowReactive():只处理对象最外层属性的响应式(浅响应式);

二十、 UnwrapRef()

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
二、Vue的数据驱动---mvvm模式的介绍 Vue是一款轻量级的渐进式前端框架,主要功能: 1、模板渲染/数据同步 2、组件化、模块化 3、扩展功能:路由 等等 Vue资源: 中文官网:https://cn.vuejs.org/ Github源码:https://github.com/vuejs/vue MVVM: M:Model数据模型 负责数据存储 V:View视图 负责页面的显示 VM:View Model负责业务处理,对数据进行加工,之后交给视图 Vue1 下载地址:http://v1-cn.vuejs.org/js/vue.js Vue2 下载地址:https://unpkg.com/vue@2.2.1/dist/vue.js 三、Vue常见指令介绍上 1、插值表达式 {{}} 当模型中的数据发生改变时,那么视图中的数据也对应的发生改变。 2、v-text 将一个变量的值渲染到指定的元素中 3、v-html 可以真正输出html元素 4、v-model 实现双向数据绑定 5、v-build 绑定页面中元素的属性 6、v-if和v-show v-if 作用:判断是否加载固定的内容,如果是真,就加载,如果是假,就不加载; 语法:v-if='判断表达式' v-show 作用:判断是否显示内容 语法:v-show='判断表达式' v-if和v-show的相同点和不同点 1.相同点:都可以实现对于一个元素的显示与隐藏操作 2.不同点:v-if是将元素添加或移出dom树模型中,v-show只是在这个属性上添加display:none而已。 3.v-if有更高的切换小号,安全性高。v-show初始化消耗大点。所以,如果需要频繁切换并对安全性没有要求时, 可以用v-show。如果在运行时,条件不可能改变的话,使用v-if更好点。 7、v-for 作用:控制html元素中的循环 语法:v-for="item in 集合" 8、v-on 作用:对页面中的事件进行绑定 语法:v-on:事件类型 = '监听器' 缩写@事件类型='监听器' 四、Vue常用的组件使用 组件是vue.js中一个非常强大的功能,可以扩展HTML元素,封装可重用的代码。 1、将组件内容定义到template模板中 2、组件中实现指令以及事件绑定 五、组件间的传值 1、父组件传值给子组件 2、子组件传值给父组件 六、Vue-router路由的基本使用上 在一个系统或App中,由多个页面组成,通常会使用vue中的组件来实现,那么从一个页面跳转到另一个页面时, 通过url路径来实现的,哪个url对应哪个页面,在vue中是通过vue-router来实现 Vue-router在vue2.0中的使用、 配合vue1.0使用的版本的帮助文档地址: https://github.com/vuejs/vue-router/tree/1.0/docs/zh-cn 配合vue1.0使用的vue-router下载地址: https://cdnjs.doubflare.com/ajax/libs/vue-router/0.7.10/vue-router.min.js 配合vue2.0使用的版本的帮助文档地址:http://router.vuejs.org/zh-cn/installation.html 配合vue2.0使用的vue-router下载地址:https://unpkg.com/vue-router/dist/vue-router.js 七、路由的传值 vue2.0的路由参数定义实现url的传值 八、ECMAScript6 九、let使用 let是申明变量的关键字 1、在相同的作用域内,let不能重复申明一个变量 2、let申明的变量不会被预解析 3、暂时性死区(变量在let声明前都不能访问,为了防止先调用后声明这个现象) 十、let与for的使用 1.块级作用域 let声明的变量拥有块级作用域,块级作用域是一对大括号 块级作用域可以直接些一堆大括号,以后就不用写自执行函数了 2.var与for循环 3.let与for循环 十一、const的用法 const声明一个常量,一旦声明后就不能修改了 1.如果声明后再去修改的话就会报错 2.只声明不赋值也会报错 3.只能先声明后使用,不会被提前解析 4.不能重复声明一个常量 注意:const声明的对象中属性是可以修改的 十二、结构赋值-数组 结构赋值 按照一定的模式,从数组或者对象中把数据拿出来,对变量进行赋值 数组结构赋值 等号左边与右边必须都是数组,数组的结构赋值要一一对应。如果对应不上的话就是undefind 十三、对象结构赋值 对象结构赋值 等号左边与右边必须都是对象,名字要一一对应,顺序不需要对应,对应不上的值结果是undefind 十四、字符串模板 1.字符串需要用一堆反引号包裹起来,它可以定义多行字符串,只用一堆反引号 2.要拼进去的数据需要放在${}里面 3.大括号里面还可以进行运算 4.大括号里面可以调用函数 十五、箭头函数 语法: 1.function用var、let、const来表示 2.参数要卸载第一个等号后面 a.如果没有参数,需要写一堆空的小括号 b.只有一个参数,那就直接写,不用加括号 c.参数有多个,需要加一个小括号,参数用逗号隔开 3.函数的主题内容是放箭头后面, 如果语句只有一条,那就直接写; 如果语句有多条,需要把他们放在一堆大括号里 。 十六、rest参数 rest参数 ...变量名 rest参数是一个数组,他的后面不能再有参数,不然会报错 扩展方法... 1.三个点后面是一个类数组,它的作用是把这个类数组转成真正的数组,但是它需要放到一对中括号里面 2.三个点后面是一个真正的数组,它的作用是把数组转成一个普通集合数据,不需要加中括号 十七、Symbol介绍 新增的第7中数据类型,表示独一无二。用来作为属性名,能保证不会与其他的属性名冲突 1.它是通过Symbol函数生成的 2.它的前面不能用new,因为它生成的是一个原始类型的数据,不是对象 3.它可以接受一个参数,为了便于区别。及时长的一样他们也不同 4.它不能与其他的值进行运算,没有隐式转换 5.它的值可以被转换成布尔值或字符串,不能转换成数字 十八、set数据结构 set数据结构,类似数组,所有的数据都是唯一的,没有重复的值。它本身是一个构造函数 size数据长度 add()添加一个数据 delete()删除一个数据 has()查找某条数据,返回一个布尔值 clear()删除所有数据 十九、map数据结构 map数据结构,类似于对象。键值对的集合,所有输一局都是唯一的,不会重复。每条数据都需要放在一个数组中 它本身就是一个构造函数 size()数据的长度 set()添加一条数据 delete()删除一条数据 get()获取一条数据 has()查找某条数据,返回一个布尔值 clear()删除所有数据 二十:教学视频
对于vue3语法高亮混乱的问题,你可以尝试以下解决方法。首先,确保你已经安装了Vetur插件。然后,按照以下步骤进行设置。打开VSCode,点击左下角的齿轮图标,进入设置。在搜索框中搜索"setting",点击"字体",然后再setting.json文件中进行编辑。在文件中添加如下代码: ``` "files.associations": { "*.vue": "html" } ``` 保存文件后,重启VSCode,你应该能够看到vue文件的语法高亮效果恢复正常了。如果问题仍然存在,你可以尝试恢复VSCode的初始设置。你可以找到VSCode的配置文件,并注释掉其中的所有内容,然后在文件中添加以下代码: ``` { "editor.fontSize": 16 } ``` 保存文件后,重启VSCode,这样应该能够解决语法高亮混乱的问题。希望对你有所帮助!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [vscode开发vue项目 代码高亮/语法提示 失效解决方法](https://blog.csdn.net/qq_39167720/article/details/125936962)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* [vscode之.Vue文件高光显示及报错问题](https://blog.csdn.net/z914020826/article/details/126941441)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值