Vue3 setup语法糖勾子函数使用简易教程

您所在的位置:网站首页 state函数如何调用 Vue3 setup语法糖勾子函数使用简易教程

Vue3 setup语法糖勾子函数使用简易教程

#Vue3 setup语法糖勾子函数使用简易教程| 来源: 网络整理| 查看: 265

Vue3 setup语法糖勾子函数使用简易教程 1. 新生命周期(setup)

vue3删除了create生命周期,其他方法前面加上on进行访问,例如onMounted、onUpdated,同时新增setup属性(比created更早执行,同时setup中this不会指向实例),更贴近于html写法,这个方法在onBeforeMounted之前被调用,同时vue3在生命周期中也删除了this指向,所有的方法必须自己在vue实例中调用

123 //setup写法,自带语法糖(推荐) //在setup中没有this,所有的方法必须引入后使用 import {ref} from 'vue' let up =ref(123)

等同于(使用语法糖后系统自动renturn,更方便)

123 import {ref} from 'vue' export default{ setup() { //定义数据需要在数据前面加ref包裹,后面会具体详解 let up=ref(123) return{ up } } }

使用生命周期必须在vue实例中引用,销毁实例变为onUnmounted,与vue2的destroy作用一致

import {onMounted,onUnmounted} from 'vue' //所有的生命周期用法均为回调函数 onMounted(()=>{ console.log('我创建了'); }) // 销毁实例变为onUnmounted,与vue2的destroy作用一致 onUnmounted(()=>{ console.log('我销毁了'); }) 2. VUE3的数据、方法绑定 2.1使用ref定义数据

ref在vue3中是将数据转换成响应式数据结构的一种,因为vue3中没有了data(){},那么就没办法劫持数据做到响应式数据,那么怎么办呢?在vue3中新出现了ref这个新方法,可以将数据变成响应式数据。

为了区别使用ref和不使用ref的区别,我写了下面两个demo做对比

{{num}} //不使用ref定义 let num=1

我们定义了一个不使用ref的数据,可以看出视图也渲染成了我们想要的状态

image.png

但是如果我们加上一个按钮,每次让num+1,又是什么效果呢?

{{ num }} num+1 //不使用ref定义 let num = 1; let addNum = ()=>{ num+=1; console.log('我执行了,现在的num是'+num); } image.png

可以看出,num确实被修改了,但是为什么视图不更新呢?那是因为数据在{}或者[]中才可以被劫持,现在的num就是一个字符串,字符串修改可不能被objectdefineproperty或者proxy劫持,压根视图就不会被修改,那么如何做让视图变成响应式的呢?就加一个ref就行。

代码修改如下,我们看一下视图以及num变成了什么样子

{{ num }} num+1 import { ref } from "vue"; let num = ref(1); let addNum = () => { //注意,使用ref变成响应式数据的时候,必须通过.value才可以拿到定义的数据 num.value = num.value + 1; console.log("我执行了,现在的num是" + num.value); console.log(num); }; image.png

可以看到,数据变成响应式的了,同时num变成了对象,这样只要数据改变,数据就会被劫持,视图就会改变,需注意拿取ref的数据必须加上.value

2.2 使用ref拿取DOM元素

在vue2中大家都用ref拿取dom元素对吧,那么现在在vue3中如何拿取dom元素呢?

{{ num }} import { ref,nextTick ,onMounted} from "vue"; let num = ref(1); // 需要拿取box这个元素,那么只需要定义一个名字为上方ref相同的名字即可 let box =ref(); // 这么拿取的话会是undefined,需要等dom渲染完成后才能拿取到,因为setup时候dom还没渲染 console.log(box.value);//undefined nextTick(()=>{ console.log('我是nextTIck执行'); console.log(box.value); }) onMounted(()=>{ console.log('我是mouted执行'); console.log(box.value); }) image.png 2.3 使用reactive定义数据

每次都使用.value是不是有点麻烦,神器来了,reactve可以将整个对象变成响应式数据

{{ data.name }} 修改名字 import { reactive } from "vue"; let data = reactive({ name: "张三", age: 13, sex: "男" }); function setName() { // 调用时更像vue2,不用.value去调用 data.name = "李四"; data.age = 35; data.sex = "女"; } 2.4 方法绑定 template> // 以下方法都可以定义函数,按自己开发习惯定义一种即可 let setFn = ()=>{ console.log("我是匿名函数"); } function setFn(){ console.log('我是普通函数'); } 2.5 computed使用 {{add}} import { computed, ref } from "vue"; let num1 = ref(13); let num2 = ref(13); // 设置个变量接收 let add = computed(() => { return num1.value * num2.value; }); 2.6 watch使用 2.6.1单属性监听 import { watch, ref } from "vue"; // 用户名 let user = ref(); // watch监听接收两个或者三个匿名函数,第一个是监听的数值,第二个是处理监听函数,第三个是否开启深监听(可选) watch( () => user.value, (newVal, oldVal) => { console.log("新值:" + newVal + "旧值:" + oldVal); }, // 可选项,是否开启深监听 { deep: true } ); image.png 2.6.2多属性监听(方法1) import { watch, ref } from "vue"; // 用户名 let user = ref(); let password = ref(); // 监听user watch( () => user.value, newVal => { console.log("用户名:" + newVal); }, // 可选项,是否开启深监听 { deep: true } ); // 监听password watch( () => password.value, newVal => { console.log("密码:" + newVal); } ); 2.6.3多属性监听(方法2)

第二种方法相比第一种方法更直接,同时监听多个值只要其中一个值变化,就会触发方法。

import { watch, ref } from "vue"; // 用户名 let user = ref(); let password = ref(); // 同时监听user和password,只要user或者password其中一个值变化,就会触发下面的方法 watch(()=>[user.value, password.value],([newUser, newPassword],[oldUser, oldPassword])=>{ console.log('我是新的user值'+newUser); console.log('我是旧的的user值'+oldUser); console.log('我是新的pass值'+newPassword); console.log('我是旧的的pass值'+oldPassword); }) image.png 2.7 onMounted使用 import { onMounted } from 'vue'; onMounted(() => { tablesDatas(); getList(); }); 2.8 vue2和vue3勾子函数对应转换关系 image.png 3.路由 3.1路由跳转

在vue2中使用this.$router.push进行跳转,在vue3中,setup中没有this,那么怎么处理呢?

跳转首页 // 切记是在vue-router中引入useRouter import {useRouter} from 'vue-router' const router = useRouter() let jumpNewPage = ()=>{ // 切记不可将router定义在方法中,这样他不是响应式数据,会报错 // const router = useRouter() router.push({path: '/'}) } 3.2 路由传参 // 记住是在vue-router中引入useRouter import {useRouter} from 'vue-router' const router = useRouter() let jumpNewPage = ()=>{ // 有两种传参方式,query和params,两者写法不一样,请注意 // query更像get传参,是显性传参,前面跳转加path路径即可,刷新也还在, router.push({path: '/',query: {name:'首页'}}) // params更像post,是隐性传参过去,跳转需注意,不使用path跳转,而是用路由中跳转组件的name进行跳转,否则拿不到params router.push({name: 'Home',params: {name:'首页'}}) } 3.3路由接参数

元素使用params跳转,使用params接收即可

// 引入useRoute,获取是route import {useRoute} from 'vue-router' import {onMounted} from 'vue' const route = useRoute() onMounted(()=>{ console.log(route.params);//结果为{name:'首页'} })

元素使用query跳转,使用query接收即可

// 引入useRoute,获取是route import {useRoute} from 'vue-router' import {onMounted} from 'vue' const route = useRoute() onMounted(()=>{ console.log(route.query);//结果为{name:'首页'} }) 4.组件 4.1组件引用

组件在props里直接引入就可在template里直接使用,无需再进行注册。

// 引入后无需注册 import vChild from '../components/child.vue' 4.2 defineProps传参(父传子)

父元素传递给子元素的数据,子元素使用defineProps进行接收

//父元素 //子元素 我是子组件 import {defineProps} from 'vue' // 在接收时候也得注意,vue3 props接收必须规定数据类型,如果父元素数据类型出错,那么会报错 const props = defineProps({msg:String}) //typeScript interface Props { msg:String: string; } const props = withDefaults(defineProps(), { msg:String: '' }); 作者:howe 链接:https://juejin.cn/post/7111969216885948429 来源:稀土掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 console.log(props); // Proxy {msg: '我给子元素带的一段话'} console.log(props.msg) 4.3 defineEmits传值(子传父) //子组件 我是子组件 import {defineEmits,onMounted} from 'vue' const emit = defineEmits() onMounted(()=>{ emit('getChildMsg','我是子元素,给父元素传的话') emit('secChildMsg','我是子组件,这是传给父组件的第二句话') }) //父组件 // 引入后无需注册 import vChild from "../components/child.vue"; let getMsg = e => { console.log(e); //我是子元素,给父元素传的话 }; const hSecChildMsg = e => { console.log(e); // 我是子组件,这是传给父组件的第二句话 }; 4.4defineExpose(父拿子方法) //子组件 {{val}} import {ref,defineExpose} from 'vue' let val = ref('我是子组件') let fn = ()=>{ val.value='我改变了子组件' } // 暴露val和fn defineExpose({ val,fn }) //父组件 // 引入后无需注册 import vChild from "../components/child.vue"; import {ref,onMounted} from 'vue'; // 获取child实例 let child = ref() onMounted(()=>{ console.log(child.value.val);//直接打印:我是子组件,并不需要加.value // 执行子组件的fn函数 child.value.fn() }) 5.vuex

在新的vue3中,肯定也猜到了,不是使用this.$store调用的了,是引入调用,下面就是教大家如何在vue3中如何使用vuex

//vuex import { createStore } from 'vuex' export default createStore({ state: { num:1 }, mutations: { /** * @description: 修改num成新的num * @param {*} state 上方的state对象 * @param {Number} newNum 新的num数值 * @return {*} none */ setNum(state,newNum) { state.num = newNum } }, actions: { // 异步递增num addAsync(store){ setTimeout(()=>{ console.log(store.state.num+=10); },1000) } }, modules: { } }) import {useStore} from 'vuex' import {onMounted} from 'vue' // vuex实例 const store =new useStore(); onMounted(()=>{ // 调用state中的title,并且加1 store.state.num+=1 store.state.num+=1 console.log(store.state.num);//3 // 调用mucation里的setNum方法,第二个参数为setNum方法里的第二个参数 store.commit('setNum',10); console.log(store.state.num);//已经修改成10了 // 调用action里的addAsync方法 store.dispatch('addAsync')//输出结果:20 })

同时也可以使用分发(…mapActions,…mapState等方法),具体参照Vuex官网

转自:https://blog.csdn.net/qq_30351747/article/details/124105847 https://blog.csdn.net/qq_30351747/article/details/123998301



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3