Vue中使用props 创建计算属性,当props发生变化时 计算属性没有发生变化?
//homeTag2.js//使用es module进行import
import { createApp, ref, computed, reactive } from "vue"
const HomeTag = {
props:['id','title'],
setup(props,context) {
//将Props中的属性 保存为私有属性
const homeTagId= ref(props.id)
//组件自身属性
let homeTagName = ref("homeTagName")
//组件使用props创建的计算属性
const normalizedId= computed(()=>{
console.log(props.id*1000)
return Math.floor(Math.random() * 10*props.id) + 1
})
return {
homeTagName,
homeTagId,
normalizedId
}
},
template: `<div> propsId:{{id}},{{title}},homeTagId:{{homeTagId}},normalizedId:{{normalizedId}}</div> `
};
//使用es module 进行你export
export default HomeTag
//index.html<!DOCTYPE html>
<html lang="en">
<body>
<div id="app">
<p>{{name}}</p>
<home-tag v-bind="post"></home-tag>
<button @click="btnClick"> click</button>
</div>
</body>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="importmap">
{"imports":{
"vue":"https://unpkg.com/vue@3/dist/vue.esm-browser.js"
}}
</script>
<script type="module" src="./homeTag2.js">
</script>
<script type="module">
import HomeTag from "./homeTag2.js"
const { createApp, ref, reactive } = Vue
console.log("createApp", createApp)
//应用实例
var appVueInstance = createApp({
setup() {
let name = ref("abc")
let aritcle = { id: 1, title: "My Journey with vue" };
const post = ref(aritcle)
console.log("post",post)
console.log("post.value",post.value)
console.log("article",aritcle)
function btnClick() {
// aritcle.id=3;
post.value.id=Math.random()
console.log("post.value",post.value)
}
return {
name,
post,
btnClick
}
}
})
//注册组件
appVueInstance.component("home-tag", HomeTag)
appVueInstance.mount("#app")
</script>
</html>
index.html 中通过点击按钮每次 随机更新 post的id属性值。 而post对象被 v-bind 到 子组件home-tag的 props中的id和title属性中。
home-tag子组件中存在计算属性normalizedId 依赖于props的id属性。
因此 理论上每次 点击 post的id的更新会导致normalizedId 的值一起变化。
问题: 实际运行 normalizedId 的值没有变化。
回答:
问题基本已经可以锁定在两种模块加载方式混用上了。
题主这里是 ESM + 普通 JS 模块混用的,所以出现了这种奇怪的现象。两种改法可以解决此问题。
第一种见原题评论区,把 index.html
改造成完全的 ESM 形式。
第二种是把 index.html
和 homeTag2.js
都改造成完全的普通 JS 形式:
<!-- index.html --><script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="./homeTag2.js"></script>
<script>
const { createApp, ref, reactive } = Vue;
const HomeTag = window.HomeTag;
// 略
</script>
const { ref, computed, reactive } = Vue;const HomeTag = {
// 略
};
window.HomeTag = HomeTag;
只要像原题中 index.html
里用的是全局变量 Vue、homeTag2.js
用的是模块 vue 这样的混用,就会出现 computed 不触发的问题。
具体原因未知,可能跟依赖收集的作用域有关,混用的时候两者不在同一个作用域下。这个具体咋回事儿得看下源码了,感兴趣的话题主可以自己尝试跟踪一下,我已经给缩小范围了。
回答:
没有复现你的问题——Playground
回答:
看了一下项目
你用watch:
import { watch, computed } from 'vue';props: ['id'],
setup(props) {
const normalizedId = ref(0);
watch(
() => props.id,
(newId, oldId) => {
normalizedId.value = Math.floor(Math.random() * 10 * newId) + 1;
},
{ immediate: true }
);
// ...
}
或者不用v-bind解构对象:
在父组件里:
<home-tag :post="post"></home-tag>
在子组件里:
props: ['post'],setup(props) {
const normalizedId = computed(() => {
return Math.floor(Math.random() * 10 * props.post.id) + 1;
});
// ...
}:
以上是 Vue中使用props 创建计算属性,当props发生变化时 计算属性没有发生变化? 的全部内容, 来源链接: utcz.com/p/934859.html