前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >4.vue 的双向绑定的原理是什么?_vue双向绑定底层原理

4.vue 的双向绑定的原理是什么?_vue双向绑定底层原理

作者头像
全栈程序员站长
发布2022-11-02 17:18:45
1.4K0
发布2022-11-02 17:18:45
举报
文章被收录于专栏:全栈程序员必看

🍅 作者简介:哪吒,CSDN2021博客之星亚军🏆、新星计划导师✌、博客专家💪 🍅 哪吒多年工作总结:Java学习路线总结,搬砖工逆袭Java架构师 🍅 关注公众号【哪吒编程】,回复1024,获取Java学习路线思维导图、大厂面试真题、加入万粉计划交流群、一起学习进步

目录

一、前端代码初体验

1、代码实例

2、浏览器显示

二、根据异常改进

1、监听事件,反向赋值

2、代码实例

3、浏览器显示

三、联动修改num1的值

1、代码实例

2、浏览器显示

四、watch

五、通过$refs完成父访问子


需求分析: 通过输入框,双向绑定文本框显示。

一、前端代码初体验

1、代码实例

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <cpn :number1="num1"
       :number2="num2"/>
</div>

<template id="cpn">
  <div>
    <h2>{
  
  {number1}}</h2>
    <input type="text" v-model="number1">
    <h2>{
  
  {number2}}</h2>
    <input type="text" v-model="number2">
  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      num1: 1,
      num2: 0
    },
    components: {
      cpn: {
        template: '#cpn',
        props: {
          number1: Number,
          number2: Number
        },
      }
    }
  })
</script>

</body>
</html>

2、浏览器显示

错误信息

Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop’s value. Prop being mutated: “number1”

谷歌翻译 –>

避免直接改变 prop,因为每当父组件重新渲染时,值都会被覆盖。 相反,根据道具的值使用数据或计算属性。 道具被变异:“number1”

这时候要完成双向绑定怎么办呢?

红色异常显示,希望在data中定义一个其它属性。

输入框绑定方法:

二、根据异常改进

1、监听事件,反向赋值

2、代码实例

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <cpn :number1="num1"
       :number2="num2"/>
</div>

<template id="cpn">
  <div>
    <h2>{
  
  {number1}}</h2>
    <h2>{
  
  {dnumber1}}</h2>
    <input type="text" v-model="dnumber1">
    <h2>{
  
  {number2}}</h2>
    <h2>{
  
  {dnumber2}}</h2>
    <input type="text" v-model="dnumber2">
  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      num1: 1,
      num2: 0
    },
    components: {
      cpn: {
        template: '#cpn',
        props: {
          number1: Number,
          number2: Number
        },
        data(){
            return{
                dnumber1:this.number1,
                dnumber2:this.number2
            }
        }
      }
    }
  })
</script>

</body>
</html>

3、浏览器显示

三、联动修改num1的值

1、代码实例

但是,我想通过反向传到父组件中,也就是改变number1的值,也就是改变data中的num1,怎么整?

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <cpn :number1="num1"
       :number2="num2"
       @num1change="num1change"
       @num2change="num2change"/>
</div>

<template id="cpn">
  <div>
    <h2>props:{
  
  {number1}}</h2>
    <h2>data:{
  
  {dnumber1}}</h2>
    <!--<input type="text" v-model="dnumber1">-->
    <input type="text" :value="dnumber1" @input="num1Input">
    <h2>props:{
  
  {number2}}</h2>
    <h2>data:{
  
  {dnumber2}}</h2>
    <!--<input type="text" v-model="dnumber2">-->
    <input type="text" :value="dnumber2" @input="num2Input">
  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      num1: 1,
      num2: 0
    },
    methods: {
      num1change(value) {
        this.num1 = parseFloat(value)
      },
      num2change(value) {
        this.num2 = parseFloat(value)
      }
    },
    components: {
      cpn: {
        template: '#cpn',
        props: {
          number1: Number,
          number2: Number
        },
        data() {
          return {
            dnumber1: this.number1,
            dnumber2: this.number2
          }
        },
        methods: {
          num1Input(event) {
            // 1.将input中的value赋值到dnumber中
            this.dnumber1 = event.target.value;

            // 2.为了让父组件可以修改值, 发出一个事件
            this.$emit('num1change', this.dnumber1)

            // 3.同时修饰dnumber2的值
            this.dnumber2 = this.dnumber1 * 100;
            this.$emit('num2change', this.dnumber2);
          },
          num2Input(event) {
            this.dnumber2 = event.target.value;
            this.$emit('num2change', this.dnumber2)

            // 同时修饰dnumber2的值
            this.dnumber1 = this.dnumber2 / 100;
            this.$emit('num1change', this.dnumber1);
          }
        }
      }
    }
  })
</script>

</body>
</html>

2、浏览器显示

四、watch

watch关键是监听某一属性的改变,是上面写法的一种变形写法。

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <cpn :number1="num1"
       :number2="num2"
       @num1change="num1change"
       @num2change="num2change"/>
</div>

<template id="cpn">
  <div>
    <h2>props:{
  
  {number1}}</h2>
    <h2>data:{
  
  {dnumber1}}</h2>
    <input type="text" v-model="dnumber1">
    <h2>props:{
  
  {number2}}</h2>
    <h2>data:{
  
  {dnumber2}}</h2>
    <input type="text" v-model="dnumber2">
  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      num1: 1,
      num2: 0
    },
    methods: {
      num1change(value) {
        this.num1 = parseFloat(value)
      },
      num2change(value) {
        this.num2 = parseFloat(value)
      }
    },
    components: {
      cpn: {
        template: '#cpn',
        props: {
          number1: Number,
          number2: Number,
          name: ''
        },
        data() {
          return {
            dnumber1: this.number1,
            dnumber2: this.number2
          }
        },
        watch: {
          dnumber1(newValue) {
            this.dnumber2 = newValue * 100;
            this.$emit('num1change', newValue);
          },
          dnumber2(newValue) {
            this.number1 = newValue / 100;
            this.$emit('num2change', newValue);
          }
        }
      }
    }
  })
</script>

</body>
</html>

五、通过$refs完成父访问子

父子组件通信

在开发中,往往有一些数据需要送上层传递到下层;

比如在一个页面中,我们从服务器请求到很多的数据,其中一部分数据,并非是我们整个页面大组件的,需要在子组件中进行展示,这时,并不会让子组件再次请求一次,而是直接从父组件将数据传递给子组件。

那么如何传递呢?

官方提到:

通过props向子组件传递数据;

通过事件向父组件传递数据;

一般不推荐使用children,children一般用于拿到所有组件的时候使用。

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <cpn></cpn>
  <cpn></cpn>

  <my-cpn></my-cpn>
  <y-cpn></y-cpn>

  <cpn ref="aaa"></cpn>
  <button @click="btnClick">按钮</button>
</div>

<template id="cpn">
  <div>我是子组件</div>
</template>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    },
    methods: {
      btnClick() {
        // 1.$children
        // console.log(this.$children);
        // for (let c of this.$children) {
        //   console.log(c.name);
        //   c.showMessage();
        // }
        // 拿第三个组件的内容,但是下标值不太好用
        // console.log(this.$children[3].name);

        // 2.$refs => 对象类型, 默认是一个空的对象 ref='bbb'
        console.log(this.$refs.aaa.name);
      }
    },
    components: {
      cpn: {
        template: '#cpn',
        data() {
          return {
            name: '我是子组件的name'
          }
        },
        methods: {
          showMessage() {
            console.log('showMessage');
          }
        }
      },
    }
  })
</script>

</body>
</html>

上一篇:Vue基础知识总结 5:vue实现树形结构

下一篇:Vue基础知识总结 7:插槽slot与vue导入导出

关注公众号,备注1024,获取Java学习路线思维导图、加入万粉计划交流群

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/180641.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年10月18日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、前端代码初体验
    • 1、代码实例
      • 2、浏览器显示
      • 二、根据异常改进
        • 1、监听事件,反向赋值
          • 2、代码实例
            • 3、浏览器显示
            • 三、联动修改num1的值
              • 1、代码实例
                • 2、浏览器显示
                • 四、watch
                • 五、通过$refs完成父访问子
                相关产品与服务
                云服务器
                云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档