当前位置: 首页 > 知识库问答 >
问题:

javascript - Vue中使用props 创建计算属性,当props发生变化时 计算属性没有发生变化?

广宏远
2023-08-31
//homeTag2.js//使用es module进行importimport { 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 进行你exportexport 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 的值没有变化。

共有3个答案

弘志勇
2023-08-31

看了一下项目
你用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;  });  // ...}:
龙玺
2023-08-31

没有复现你的问题——Playground

姬魁
2023-08-31

问题基本已经可以锁定在两种模块加载方式混用上了。

题主这里是 ESM + 普通 JS 模块混用的,所以出现了这种奇怪的现象。两种改法可以解决此问题。

第一种见原题评论区,把 index.html 改造成完全的 ESM 形式。

第二种是把 index.htmlhomeTag2.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 不触发的问题。

具体原因未知,可能跟依赖收集的作用域有关,混用的时候两者不在同一个作用域下。这个具体咋回事儿得看下源码了,感兴趣的话题主可以自己尝试跟踪一下,我已经给缩小范围了。

 类似资料:
  • 计算属性 在模板中绑定表达式是非常便利的,但是它们实际上只用于简单的操作。在模板中放入太多的逻辑会让模板过重且难以维护。例如: <div id="example"> {{ message.split('').reverse().join('') }} </div> 在这种情况下,模板不再简单和清晰。在实现反向显示 message 之前,你应该确认它。这个问题在你不止一次反向显示 messag

  • 1. 前言 本节介绍计算属性的使用方法。包括什么是计算属性,计算属性的特点,还有计算属性和方法在实际使用中的区别。其中重点掌握计算属性和方法的区别,了解它之后,才能在日常工作中灵活使用计算属性和方法。 2. 慕课解释 计算属性就是当其依赖属性的值发生变化时,这个属性的值会自动更新,与之相关的DOM部分也会同步自动更新。— 官方定义 计算属性实际上是一个方法,它可以完成各种复杂的逻辑,包括运算、函数

  • 本文向大家介绍Vue计算属性的使用,包括了Vue计算属性的使用的使用技巧和注意事项,需要的朋友参考一下 我们都知道在Vue构造函数的参数对象中有一个【data】属性,该属性值是一个对象,该对象是对数据的代理,是一个键值对并且时刻与页面表现是一致的,但是这里面只能是简单的键值对,不能拥有业务逻辑,并且由于【data】中的属性属于同一个生命周期,所以如果我们需要某一个属性是依赖于另外一个属性时,在【d

  • 大多数组件在创建时可以使用各种参数来进行定制。用于定制的这些参数就称为 props 属性。 以基础组件 Image 为例,在创建图片的时候传入一个 source 的属性来指定显示图片的 url,使用 style 属性来控制尺寸。 import React, { Component } from 'react'; import { AppRegistry, Image } from 'react-n

  • 我有一个Vuex实例,其中包含两个变量: 我有我的主Vue实例,其中日期属性是从继承的: 我最初称之为不带任何额外参数,但是一旦和的值更改,我想调用上面的之类的函数。但是,当我更改和的值时,没有任何变化。 可能值得注意的是,当我使用Vue插件在Chrome中进行检查,并单击根组件时,视图中会突然显示更改?很奇怪

  • 本文向大家介绍vue计算属性及使用详解,包括了vue计算属性及使用详解的使用技巧和注意事项,需要的朋友参考一下 一、什么是计算属性 模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。例如: 这里的表达式包含3个操作,并不是很清晰,所以遇到复杂逻辑时应该使用Vue特带的计算属性computed来进行处理。  二、计算属性的用法 在一个计算属性里