【vue3】vue3的三种写法(附带provide/inject、toRefs说明、ref,reactive的区别)

写法一(vue3的写法)

<template>
  <HelloWorld />
  <h1>{{ a3 }}</h1>
  <h1>{{ b3 }}</h1>
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";
import { ref, provide, readonly, reactive, toRefs } from "vue";
export default {
  name: "App",
  components: {
    HelloWorld,
  },
  setup() {
    const a3 = ref("1000");
    const obj3 = reactive({ // 建立响应式映射
      b3: 'bbb'
    })

    provide("a3", readonly(a3)); // readonly设置provide指定属性名为只读
    provide("obj3", obj3);

    setTimeout(() => {
      a3.value = "2000";
      obj3.b3 = "bbbbbb";
    }, 3000);
    
    return { // 返回值给到setup
      a3,
      ...toRefs(obj3) // 结构reactive内的对象属性,具体作用参考下面的截图
    };
  },
};
</script>
toRefs定义:

toRefs可以将对象(只能接收rective对象)中的属性变成响应式。

正常reactive对象数据也是响应式的,如果用toRefs解构出去会更加方便。

toRefs什么时候用?

数据量如果很多, 我们一般会用解构来简化代码, 那么在vue3 中如果使用对象的解构, 会让改对象失去响应式, 所有一般解构的时候 借助 toRefs 来解构仍然带有响应式。

解构后, 我们就不需要 用 对象.属性了, 而是可以直接使用属性,来简化。

<h3>{{name}}</h3>
let obj = reactive({ name:'kebi' })
return {
	...toRefs(obj)
}

写法二(vue2的写法)

扩展:Vue使用provide各种传值后inject获取undefined的问题及解决
vue2的写法是函数式写法,如果以vue3的写法例如:

// 父组件
mounted () {
	provide("obj3", obj3);
}
// 子组件
mounted () {
	const list = inject('list');
}

则会产生inject获取后打印log undefined 这个问题,解决办法是写成函数式的,如下:

<template>
  <div>
    <div>Son1的msg:{{ msg }}</div>
    <Son2></Son2>
  </div>
</template>

<script>
import Son2 from './Son2.vue';
import { inject, provide, readonly } from 'vue';

export default {
  name: 'Son1',
  components: {
    Son2,
  },
  data () {
    return {
      sMsg: '',
    }
  },
  provide () {
    return {
      msg: readonly(inject('msg') + '->son1'),
    }
  },
  inject: ['msg'],
  mounted () {
    // this.sMsg = inject('msg') + '->son1';
    // console.log('this.sMsg', this.sMsg)
  }
};
</script>

写法三(vue3的写法)

父组件provide/inject
<template>
  <!-- child component -->
  <child-components></child-components>
  <!-- parent component -->
  <div class="child-wrap input-group">
    <input
      v-model="value"
      type="text"
      class="form-control"
      placeholder="Please enter"
    />
    <div class="input-group-append">
      <button @click="handleAdd" class="btn btn-primary" type="button">
        add
      </button>
    </div>
  </div>
</template>
<script setup>
	import { ref, provide } from 'vue'
	import ChildComponents from './child.vue'
	const list = ref(['JavaScript', 'HTML', 'CSS'])
	const value = ref('')
	// Provide data to child components.
	provide('list', list.value)
	// event handling function triggered by add
	const handleAdd = () => {
	  list.value.push(value.value)
	  value.value = ''
	}
</script>
子组件provide/inject

<template>
  <ul class="parent list-group">
    <li class="list-group-item" v-for="i in list" :key="i">{{ i }}</li>
  </ul>
</template>
<script setup>
	import { inject } from 'vue'
	// Accept data provided by parent component
	const list = inject('list')
</script>
ref,reactive的区别:

在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hzxOnlineOk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值