【Vue2+Vue3】props参数赋值给data属性【如何实现响应式变化-如何解决值传递无法响应式的问题】
程序员文章站
2024-01-02 21:24:22
...
响应式变化存在的问题:值传递是无法实现【响应式变化】为此对应props的值传参给data,必须重新包裹封装成一个对象【实现引用传参】才能解决响应式的问题
Vue2的解决办法【要自己封装对象,且结合watch】比较复杂
<template>
<view class="content">
<Test :value="value" :value-obj="valueObj"/>
<button @click="changeValue">改变value</button>
<button @click="changeValueObj">改变valueObj</button>
</view>
</template>
<script>
import Test from "../test.vue";
export default {
components: {
Test,
},
data() {
return {
value: "",
valueObj: {
number: 1,
},
};
},
methods: {
changeValue() {
this.value += "!";
},
changeValueObj() {
this.valueObj.number += 1;
},
},
};
</script>
<template>
<view>
<view>测试props的值传参给dada如何响应式变化:{{ testValueWatchObj.value }}</view>
<view>测试props的对象传参给dada如何响应式变化:{{ testObj.number }}</view>
</view>
</template>
<script>
export default {
name: "test",
data() {
return {
testValueWatchObj: {
/**
* 封装【props属性】的响应式对象【props此属性变化->此对象跟着变化】
* 1、把props中的value值参数赋值给data属性后封装成一个对象【变成引用传参即可响应性变化】
* 2、这里的响应式变化是【通过watch监听】props.value的改变,会影响当前对象的value的改变!
* 3、但是当前对象的value的改变,不会改变props.value的值!
*/
"value": this.value,
},
testObj: this.valueObj,
};
},
updated() {
console.log("testObj====", this.testObj);
this.testObj.aa = "我是新添加的值";
console.log("===valueObj===", this.valueObj);
},
watch: {
value(newValue) {
/**
* 监听value的值的变化,响应式改变this.watchPropsValueObj对象
*/
this.testValueWatchObj.value = newValue;
},
},
props: {
value: {
/*
直接值传参【props赋值给data数据的值传递,不会响应式变化】
*/
type: String,
default: "",
},
valueObj: {
/*
直接对象传参【props赋值给data数据的引用传参,双向响应式变化】
*/
type: Object,
},
},
};
</script>
Vue3 的解决办法【使用toRef函数,非常简单】
<template>
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld :value="value" :value-obj="valueObj"/>
<button @click="changeValue">改变value</button>
<button @click="changeValueObj">改变valueObj</button>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
import { reactive, toRefs } from "vue";
export default {
name: "App",
components: {
HelloWorld,
},
setup() {
let _data = reactive({
value: "#",
valueObj: {
number: 1,
},
});
function changeValue() {
this.value += "!";
}
function changeValueObj() {
this.valueObj.number += 1;
}
return {
...toRefs(_data),
changeValue,
changeValueObj,
};
},
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
<template>
<div class="hello">
<div>测试props的值传参给dada如何响应式变化:{{ testValue }}</div>
<div>测试props的对象传参给dada如何响应式变化:{{ testValueObj.number }}</div>
</div>
</template>
<script>
import { reactive, toRefs, toRef } from "vue";
export default {
name: "HelloWorld",
props: {
value: {
type: String,
default: "",
},
valueObj: {
type: Object,
},
},
setup(props, context) {
console.log(props.value);
let _data = reactive({
// 由于props的value属性是一个值类型,为此这里必须转换成toRef类型变成引用类型即可响应式变化!
testValue: toRef(props, "value"),
testValueObj: props.valueObj,
},
);
return {
...toRefs(_data),
};
},
}
;
</script>