vue3.0初体验简单实现父子传值,计算属性和监听的使用

tech2025-10-12  8

首先要使用vue-cli3.0新建一个项目,网上很多就不贴代码了

vue3.0 api文档: https://vue-composition-api-rfc.netlify.app/zh/api.html 1, 新建项目后安装vue-next,会自动安装插件vue-cli-plugin-vue-next ,并且升级vue和vuex,vue-router到4.x

vue add vue-next // 安装之后package.json "dependencies": { "@vue/composition-api": "^1.0.0-beta.11", "core-js": "^3.6.5", "vue": "^3.0.0-beta.1", "vue-router": "^4.0.0-alpha.6", "vuex": "^4.0.0-alpha.1" }, "devDependencies": { "@vue/cli-plugin-babel": "~4.5.0", "@vue/cli-plugin-router": "~4.5.0", "@vue/cli-plugin-vuex": "~4.5.0", "@vue/cli-service": "~4.5.0", "@vue/compiler-sfc": "^3.0.0-beta.1", "less": "^3.0.4", "less-loader": "^5.0.0", "vue-cli-plugin-vue-next": "~0.1.3" }

2,vue不在使用构造函数方式创建实例,而使用createApp 方法去创建 router和vuex也是一样

import { createApp } from 'vue'; import App from './App.vue' import router from './router' import store from './store' createApp(App).use(router).use(store).mount('#app')

3,上面的配置都会在使用命令直接创建好,下面开始正题 先看下新的属性setup是在beforeMount之前执行,vue3.0去掉了betoreCreate和created两个钩子函数 如果想操作DOM,需要在onMounted里面操作,钩子函数都必须在setup里面调用

<template> <span ref="dom">{{state.count}}</span> </template> import { reactive, onMounted, ref } from 'vue' setup (props, context) { const state = reactive({count: 0}) const dom = ref(null) onMounted(() => { console.log(dom.value) // 打印出来是<span ref="dom">{{state.count}}</span> }) return { state, dom } }

上面使用到两个新属性reactive和ref,都是声明一个响应式数据的方法,而ref还可以声明空值让其绑定在ref上,实现dom的响应式,ref声明普通类型数据要使用.value获取数据,在heml中使用可以直接用count

<template> <div class="hello"> <p>{{count}}</p> </div> </template> import { ref } from 'vue' export default { setup (props) { import { reactive, ref, inject, watch } from 'vue' const count = ref(0) console.log(count.value) // 0 return { count } } }

4,computed的使用

<template> <div class="hello"> <p>基础数据{{count}}</p> <p>计算后的数据{{compCount}}</p> <button @click="clickAdd">计数</button> </div> </template> import { ref, computed } from 'vue' export default { setup (props) { // 两种方式声明响应式数据 const count = ref(0) // const count = reactive({value: 0}) console.log(count.value) // 0 const clickAdd = () => count.value++ const compCount = computed(() => count.value * 2 + 1) return { count, compCount, clickAdd } } }

5,watch监听,第一个参数是要监听的变量,第二个是一个回调函数,数据变化后执行

<template> <div class="hello"> <p>基础数据{{count}}</p> <p>计算后的数据{{compCount}}</p> <button @click="clickAdd">计数</button> </div> </template> import { ref, computed, watch } from 'vue' export default { setup (props) { // 两种方式声明响应式数据 const count = ref(0) // const count = reactive({value: 0}) console.log(count.value) // 0 const clickAdd = () => count.value++ const compCount = computed(() => count.value * 2 + 1) watch(() => propMsg.msg, () => { console.log(count.value) }) return { count, compCount, clickAdd } } }

watch也可以监听多个数据,一地个参数使用数组,第二个参数通过传递参数,第三个值是对象深度监听和是否第一次执行deep immediate

<template> <div class="hello"> <p>基础数据{{count}}</p> <p>计算后的数据{{compCount}}</p> <button @click="clickAdd">计数</button> <button @click="setMsg">改变msg</button> </div> </template> <script> import { ref, computed, watch, reactive } from 'vue' export default { setup (props) { // 两种方式声明响应式数据 const count = ref(0) // const count = reactive({value: 0}) console.log(count.value) // 0 const clickAdd = () => count.value++ const compCount = computed(() => count.value * 2 + 1) const msgData = reactive({msg: '变化前的数据'}) const setMsg = () => msgData.msg = '改变后的数据' // 要监听的值必须是一个ref数据,或者是一个函数()=> refData.value watch([count, () => msgData.msg], ([], []) => { console.log(count.value, msgData.msg) }) return { count, compCount, clickAdd, setMsg } } } </script>

6,父子传值,可以使用props,也可以使用inject和provide 先使用props 父组件

<template> <div ref="home" class="home rem"> <HelloWorld ref="helloWord" :name="name"> </HelloWorld> <button @click="setMsg">按钮</button> </div> </template> <script> // @ is an alias to /src import HelloWorld from '@/components/HelloWorld.vue' import { reactive, ref, provide, onMounted } from 'vue' export default { name: 'Home', components: { HelloWorld }, setup () { const name = ref('父组件传值') const setMsg = () => { name.value = '父组件改变值' } const helloWord = ref(null) return { helloWord, name } } } </script>

子组件

<template> <div class="hello"> <p>{{props.name}}|{{propMsg.msg}}</p> <slot /> </div> </template> <script> import { reactive, ref, inject, watch } from 'vue' export default { name: 'HelloWorld', props: { msg: Object, name: { type: String, default: '' } }, setup (props) { const propMsg = props.msg return { propMsg, props } } } </script>

provide和inject方式,用法和vue2.x一样 父组件

<template> <div ref="home" class="home rem"> <img alt="Vue logo" src="../assets/logo.png"> <HelloWorld ref="helloWord"> </HelloWorld> <span>{{state.msg}}</span> <button @click="setMsg">按钮</button> </div> </template> <script> // @ is an alias to /src import HelloWorld from '@/components/HelloWorld.vue' import { reactive, ref, provide } from 'vue' export default { name: 'Home', components: { HelloWorld }, setup (props, context) { const state = reactive({msg: "123"}) provide('proMsg', state) const helloWord = ref(null) return { state, setMsg } } } </script>

子组件

<template> <div class="hello"> <h1>{{ newMsg.msg }}</h1> <slot /> </div> </template> <script> import { reactive, ref, inject, watch } from 'vue' export default { name: 'HelloWorld', setup (props) { const newMsg = inject('proMsg', ref('none')) return { newMsg } } } </script>

总结,vue3.x下代码逻辑更加清晰了,使用更加灵活,对后期维护别人代码更加便捷,还有很多不常用的属性还需要自己去探索,看着3.0的改变,迫不急的想在项目中使用了,哈哈

最新回复(0)