• 技术文章 >web前端 >前端问答

    vue可以修改prop中的值吗

    长期闲置长期闲置2022-06-16 10:29:32原创110

    vue中不可以直接修改prop中的值,若直接修改vue会产生警告,且修改该属性值并不能修改父组件对应的变量;但是可以通过触发子组件事件,父组件监听该事件并执行修改父组件的函数,通过监听子组件事件做到双向数据绑定来实现修改prop中的值。

    本教程操作环境:windows10系统、Vue3版、Dell G3电脑。

    vue可以修改prop中的值吗

    在Vue中,prop是可以接受由父组件传递给子组件的属性,但prop无法进行修改的。

    如果prop被强制修改,会有警告

    所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。

    另外,每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。

    尝试通过下面的方法直接修改属性值

    this.$props.modelValue = true;

    Vue 将提出警告

    Set operation on key “modelValue” failed: target is readonly.

    且修改该属性值并不能修改父组件对应的变量,仅仅适用于基础数据类型。

    注意在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变这个对象或数组本身将会影响到父组件的状态,且 Vue 无法为此向你发出警告。作为一个通用规则,应该避免修改任何 prop,包括对象和数组,因为这种做法无视了单向数据绑定,且可能会导致意料之外的结果。

    Vue3 Props 文档

    正确的修改方法是触发子组件事件,父组件监听该事件并执行修改父组件的函数,以 v-model 为例,v-model 本身就是传递给子组件的 modelValue 属性,然后监听 update:modelValue 事件来做到双向数据绑定,所以我们也可以通过该方法来在代码中修改 modelValue

    this.$emit("update:modelValue", !this.$props.modelValue);

    v-model 将自动监听 update:modelValue 事件并将 modelValue 修改为触发事件时传递的参数值(即 $emit 的第二个参数)。

    需要注意的是,这种通过触发事件-监听事件的数据流模式并不能马上生效,如果使用以下代码

    this.$emit("update:modelValue", !this.$props.modelValue);console.log(this.$props.modelValue);

    会发现输出到控制台的仍然是 modelValue 原先的值,这是因为触发事件-监听事件的模式下属性值的修改需要时间,改用以下代码会发现输出正常:

    this.$emit("update:modelValue", !this.$props.modelValue);setTimeout(()=> {console.log(this.$props.modelValue)}, 1000)

    实践

    由于 Vant 只实现了左边放 label 的输入框,想基于此实现一个 label 在右边的输入框

    Vant3 Field 文档

    这其中遇到的问题除了把 label 右置并根据 label 的内容自适应宽度外,就是 Vant 中的 <van-field /> 与我需要实现的 <right-label-input /> 以及放置 <right-label-input> 的父组件之间的数据流了。

    错误做法

    为了能够与 <van-field /> 一致使用 v-model ,我在 <right-label-input /> 下设置 modelValue 属性,然后将 <van-field>v-model="modelValue"

    <template>
    <van-field :placeholder="placeholder" :name="name" v-model="modelValue" :disabled="disabled"/>
    </template>
    
    <script>
    export default {
        name: "RightLabelInput",
        props: {
            modelValue: "",
        },
    }
    </script>

    无疑,这种做法违背了单向数据流原则,在 VanField 修改时将直接影响 RightLabelInputmodelValue 值,而 modelValueRightLabelInput 的属性,不能直接修改。

    可能正确的做法

    <template>
        <van-field :placeholder="placeholder"
                   :name="name"
                   v-model="input"
    
                   :disabled="disabled"
        />
    </template>
    
    <script>
    export default {
        name: "RightLabelInput",
        props: {
            placeholder: "",
            name: "",
            label: "",
            modelValue: "",
            disabled: {
                type: Boolean,
                default: false
            }
        },
        data() {
            return {
                input: this.modelValue, // 绑定到 data 的变量,防止直接修改 Props
            }
        },
        beforeMount() {
            this.input = this.modelValue
        },
        watch: {
            input(newInput, oldInput) {
                this.$emit("update:modelValue", newInput); // 监听 input 在修改时发起事件,由父组件修改 modelValue 的值
            },
            modelValue(newValue, oldValue) {
                this.input = newValue;
            }
        }
    }
    </script>
    
    <style scoped>
    
    </style>

    关键词:单向数据流

    【相关推荐:《vue.js教程》】

    以上就是vue可以修改prop中的值吗的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:Vue
    上一篇:css3可以做3d的效果吗 下一篇:vue中props可以传递函数吗
    php培训_php实战培训【立即报名】-php中文网第20期

    相关文章推荐

    • 【活动】充值PHP中文网VIP即送云服务器• 浅析Vue中的生命周期和数据共享• 什么是插槽?深入了解Vue中的插槽• 什么是自定义指令?深入了解Vue中的自定义指令• vue项目首次加载缓慢怎么办?两种解决方案• 9个提高开发效率和性能的Vue小技巧
    1/1

    PHP中文网