setup语法糖
其中定义的普通数据不具备响应式能力;由reactive包裹的对象数据就具备了响应式能力。
响应式:数据发生变化时,vue会通知使用到该数据的代码。(数据 -> 视图更新。)
vue2中,在data中的对象是响应式的。但其中的数组及其属性不是(需要拦截其原型方法来实现响应式)。
vue2中声明了一个对象,但是又想给他新增属性的话,需要使用$set给他重新定义
setup语法糖:
闭包closure,一个函数及其捆绑的周边环境状态(词法环境)的引用的组合。
setup语法糖其中导入的模块可以直接使用,不需要在components中进行注册; 其中定义的数据也不需要通过return暴露,可以直接在当前闭包内使用。 也不需要写name,直接以文件名。
也不需要setup()
!!注意版本 vue 3.2.x
vue3响应式数据
vue3:引入ref、reactive来创建响应式数据
<template>
<h1>{{ title }}</h1> // 直接使用 title
<h2>{{ data.author }}</h2>
<h2>{{ age }}</h2>
</template>
<script>
import { ref, reactive, toRefs } from "vue";
export default {
setup() {
const title = ref("Hello, Vue 3!");
const data = reactive({
author: "sheben",
age: "20"
});
const dataAsRefs = toRefs(data)
const { age } = dataAsRefs
setTimeout(() => {
title.value = "New Title"; // 使用 title.value 来修改其值
}, 5000);
return { title, data };
}
};
</script>
ref将一个原始数据类型转换成一个响应式数据,String、Number、BigInt、Boolean、Symbol、Undefined、Null。
reactive的作用就是将一个对象转换成一个响应式对象
toRefs的作用是将一个响应式对象转化为一个普通对象,把其中每一个属性转化为响应式数据
vue3中,响应性数据在闭包中使用。
// vue3中数据的修改
<template>
<div>
{{ student.data.name}}
{{ student.data.age}}
</div>
</template>
<script>
import ...
export default defineComponent({
name: '',
components: '',
setup() {
const student = reactive({
data: {
name: "",
age: "",
},
});
// 模拟请求接口
setTimeout(() => {
// 接口数据
const data = {
name: "zhangsan",
age: 18,
}
student.data = data;
}, 2000)
}
})
</script>
vue3使用router和store
vue3 setup中不能使用this,所以获取路由和状态不能使用this.store
import { useStore } from 'vuex';
import { useRouter } from 'vue-router';
setup(){
const router = useRouter();
const store = useStore();
//某回调方法
const onFinish()=>{
store.commit("doit");
router.push("");
}
}
// html
<router-link to="">detail</router-link>
// js
import router from 'router路由的路径'
export default {
setup() {
const xxx = () => {
router.push('./detail')
}
return {
xxx,
}
}
}
router.push('./text') // 跳回指定的上一个页面
router.go(-1) // 回到上一页
history.go(-1) // 回到浏览器上一页
路由 - 解构的用法
<script>
import { useRouter } from 'vue-router'
export default ({
setup() {
const router = useRouter()
const goDetail = () => {
router.push({ path: '跳转路径' })
}
return {
goDetail
}
}
})
</script>
vue3的setup中使用$refs
<template>
<div class="container" ref="domRef"></div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
const domRef = ref(null)
onMounted(() => {
console.log(domRef.value) // 获取到div.container这个元素
})
</script>
ref将一个原始数据类型转换成一个响应式数据。【响应式原理】
vue3 全局挂载axios
vue2中会习惯性的把axios挂载到全局,以方便在各个组件或页面中使用this.$http请求接口。
vue2在入口文件main.js中配置
import Vue from 'vue' import router from '@/router' import store from '@vuex' import Axios from 'axios' import Utils from '@/tool/utils' import App from './App.vue' // ... /* 挂载全局对象 start */ Vue.prototype.$http = Axios; Vue.prototype.$utils = Utils; /* 挂载全局对象 end */ new Vue({ router, store, render: h => h(App) }).$mount('#app')
vue3全局挂载方法和属性
vue3中取消了Vue.prototype,在全局挂载方法和属性时,需要使用官方提供的globalPropertiesAPI
vue3同样在入口文件中配置
import { createApp } from 'vue' import router from './router' import store from './store' import Axios from 'axios' import Utils from '@/tool/utils' import App from './App.vue' // ... const app = createApp(App) /* 挂载全局对象 start */ app.config.globalProperties.$http = Axios app.config.globalProperties.$utils = Utils /* 挂载全局对象 end */ app.use(router).use(store); app.mount('#app')
全局使用:
vue2:this.$http
vue3:
<template>
<div class="box"></div>
</template>
<script>
import { ref, reactive, getCurrentInstance } from 'vue'
export default {
setup(props, cxt) {
// 方法一 start
const currentInstance = getCurrentInstance()
const { $http, $message, $route } = currentInstance.appContext.config.globalProperties
function getList() {
$http({
url: '/api/v1/posts/list'
}).then(res=>{
let { data } = res.data
console.log(data)
})
}
// 方法一 end
// 方法二 start
const { proxy } = getCurrentInstance()
function getData() {
proxy.$http({
url: '/api/v1/posts/list'
}).then(res=>{
let { data } = res.data
console.log(data)
})
}
// 方法二 end
}
}
</script>
vue $forceUpdate
函数中改变了页面中的某个值,但页面中没有及时刷新
使用this.$forceUpdate()强制刷新(数据层级过多,render函数未自动更新,需要手动刷新)
// vue2
this.$forceUpdate()
// vue3
import { getCurrentInstance } from "vue";
setup(){
//解构赋值 设置别名that 也可不写:that 直接ctx
let {ctx:that} = getCurrentInstance()
that.$forceUpdate()
}
// vue3 写法2
import {getCurrentInstance} from 'vue';
const instance = getCurrentInstance();
instance.proxy.$forceUpdate();
vue3组件命名
vue3 script setup语法糖
引入的组件直接使用,不用通过Components进行注册;
无法指定当前组件的名字,他会自动以文件名为主
解决Vue3中使用setup如何定义组件的name属性
不用再写name属性了,如果需要定义类型的name,在平级加一个script标签,在里面实现即可
<template>
<button>demo</button>
</template>
<script lang="ts">
export default {
name: "TButton",
};
</script>
<script lang="ts" setup>
</script>
<style scoped lang="less"></style>
vue3挂载汇总
全局方法挂载
app.config.globalProperties.方法名= 方法名
插件挂载
import tab from './tab'
export default function installPlugins(app){
app.config.globalProperties.$tab = tab
}
全局组件挂载
app.component('DictTag', DictTag)
参考: