//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 的值没有变化。
看了一下项目
你用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; }); // ...}:
没有复现你的问题——Playground
问题基本已经可以锁定在两种模块加载方式混用上了。
题主这里是 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 不触发的问题。
具体原因未知,可能跟依赖收集的作用域有关,混用的时候两者不在同一个作用域下。这个具体咋回事儿得看下源码了,感兴趣的话题主可以自己尝试跟踪一下,我已经给缩小范围了。
计算属性 在模板中绑定表达式是非常便利的,但是它们实际上只用于简单的操作。在模板中放入太多的逻辑会让模板过重且难以维护。例如: <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来进行处理。 二、计算属性的用法 在一个计算属性里