Vue(ref和$refs属性介绍与使用)

news2024/11/15 17:20:27

一、 Vue(ref和$refs属性介绍与使用)

在Vue中一般很少会用到直接操作DOM,但不可避免有时候需要用到,这时我们可以通过ref和$refs这两个来实现,本文我们就来详细的介绍下这个内容

除了自定义属性外,Vue实例还暴露一些有用的实例属性和方法,他们都有前缀$,以便和用户定义的属性和方法分开
常用的属性有:

常用的属性有:
	1:vm.$el   	//获取vue实例关联的Dom元素
	2: vm.$data 	//获取vue实例的data选项
	3:vm.$options	//获取vue实例的自定义属性
	4:vm.$refs		//获取vue实例中所有含有ref属性的dom元素,如果有多个,只返回最后一个。
	5: vm.$ref 		// ref 被用来给元素或子组件注册引用信息, 引用信息将会注册在父组件的 $refs 对象上,如果是在普通的DOM元素上使用,引用指向的就是 DOM 元素,如果是在子组件上,引用就指向组件的实例
		 ref加载普通元素上,this.$refs.  获取到的就是dom元素
		 ref记载在子组件上,this.$refs.  获取到的就是组件实例,可使用组件的所有方法。

ref有三种用法:

   ①ref加在普通的元素上,用this.ref.name获取到的是dom元素;

   ②ref加在子组件上,用this.ref.name获取到的是组件实例,可以使用组件的所有方法;

   ③如何利用v-for和ref获取一组数据或者dom节点。

   当v-for用于元素或者组件的时候,引用信息将是包含dom节点或组件实例的数组;

   关于ref注册时间的重要说明:因为ref本身是作为渲染结果被创建的,在初始渲染的时候,你不能访问它们--它们还不存在!$refs也不是响应式的,因此你不应该试图用它在模板中做数据绑定。

ref

ref 被用来给元素或子组件注册引用信息, 引用信息将会注册在父组件的 $refs 对象上,如果是在普通的DOM元素上使用,引用指向的就是 DOM 元素,如果是在子组件上,引用就指向组件的实例。

ref作用

用来给元素或者子组件注册引用信息。引用信息将会注册给父组件的$refs对象上。
1、如果给普通的dom元素使用,引用指向的是dom元素。
2、如果是给子组件使用,引用指向的是子组件的实例。

注意:
1、$refs只有在组件渲染完成后才填充,在初始渲染的时候不能访问它们,并且它是非响应式的,因此不能用它在模板中做数据绑定。
2、微信小程序中给dom元素使用ref无效。得到的是 空对象.

$refs

$refs 是一个对象,持有已注册过 ref 的所有的子组件。

具体演示

1.基础代码

先来准备案例基础代码,如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
    <div id="app">
        
    </div>

    <script>
        var vm = new Vue({
            el: "#app",
            data: {},
            methods: {}
        })
    </script>
</body>
</html>

2.普通DOM

2.1 普通方式

我们先通过 getElementById 方法来获取
  在这里插入图片描述

2.2 ref使用

接下来我们通过 ref 属性来试试。
  在这里插入图片描述

然后查看 vm 实例对象
  在这里插入图片描述

通过上面的演示我们发现 在vm实例上有一个 $refs属性,而且该属性就有我们通过ref注册的DOM对象,于是我们可以这样获取DOM对象
在这里插入图片描述
在这里插入图片描述

3.组件

ref 也可以作用在组件中,我们来看下效果

3.1 添加组件

先来添加一个自定义的组件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2 ref 使用

在 子组件中使用 ref属性,会将子组件添加到父组件的$refs对象中,如下
在这里插入图片描述
查看vm对象
在这里插入图片描述
通过 vm 实例查看 发现 $refs中绑定的有 我们的login组件,而且还看到了对应的 组件中的 msg属性和 show方法,那这样我们可以调用了,如下
在这里插入图片描述

3.5 完整代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
    <div id="app">
        <input type="button" value="获取h3的值" @click="getElement()">
        <h3 id="myh3" ref="myh3" >我是一个h3</h3>
        <hr>
        <login ref='mylogin'></login>
    </div>

    <script>

        var login = {
            template: "<h3>我是login子组件</h3>",
            data(){
                return {
                    msg: "ok"
                }
            },
            methods:{
                show(){
                    console.log("show方法执行了...")
                }
            }
        }

        var vm = new Vue({
            el: "#app",
            data: {},
            methods: {
                getElement(){
                    // 通过 getElementById 方式获取 DOM 对象
                    // console.log(document.getElementById("myh3").innerHTML)
                    // console.log(this.$refs.myh3.innerHTML)

                    console.log(this.$refs.mylogin.msg)
                    this.$refs.mylogin.show()
                }
            },
            components:{
                login
            }
        })
    </script>
</body>
</html>

二. vue中父子组件通过ref传值「dialog组件」

一个基于vue的项目,有可能会很多的组件,组件之间难免需要进行数据的传递,比如: 父组件 传数据 给子组件;子组件传数据给父组件等,需要用到组件之间的通信处理方式。
项目中经常用到element中的dialog组件,现记录父子组件通过ref传值。

操作流程:

1.父组件中点击按钮吊起子组件模态框dialog进行内容设置,并给子组件传递id

this.$nextTick(() => {   //此函数执行时所有的DOM挂载和渲染都已完成
      this.$refs.dialogRef.init(this.fatherId);    //获取子组件中init方法并将父组件id传递给子组件
 });

2.在子组件中需接收父组件传来的内容id并查询内容详情

init (val) {
      this.activityId = val   //接收父组件传递的id值
}

3.在子组件dialog中可以编辑内容,然后将数据通过$emit传递给父组件

this.$emit("setActivityBtn", this.SetForm);   //setActivityBtn为父组件接收的方法,将参数传给父组件

4.父组件接收数据后提交到服务器

setActivityBtn(data) { //获取子组件传来的值
     let params = data
 },

以下为父子组件全部代码

子组件Dialog

<script>
export default {
  name: '',
  data () {
    return {
      id: '',  //用来查询详情的id
      dialogFormVisible: false, //模态框
      SetForm: {   }, //模态框数据 
    }
  },
  methods: { 
     // 初始化方法
    init (val) {
      this.activityId = val   //接收父组件传递的值
      this.dialogFormVisible = true;
      this.getActivityInfo()
    },
    //获取内容详情
    getActivityInfo () {
   
    },
    //模态框确定按钮
    setActivityBtn () {
      this.$emit("setActivityBtn", this.SetForm);   //将参数传给父组件
      this.dialogFormVisible = false;
    },
}
</script>

父组件

<script>
import Dialog from '../components/Dialog'
export default {
  name: '',
  data () {
    return {
      fatherId:'',  //详情id
      dialogShow: false,  //模态框
    }
  },
components: { // 组件的引用
    Dialog
  },
  methods: { 
     //吊起模态框
    activitySet() {
      this.dialogShow= true;
      this.$nextTick(() => {   //此函数执行时所有的DOM挂载和渲染都已完成
        this.$refs.dialogRef.init(this.fatherId);     //获取子组件中init方法并将父组件id传递给子组件
      });
    },
    //确定按钮
    setActivityBtn(data) { //获取子组件传来的值
      let params = data
      XXXXXXXX(params).then(res => {
        if (res.data.code == 0) {
          this.dialogFormVisible = false
        }
      })
    },
}
</script>

吊起模态框

<script>
import Dialog from '../components/Dialog'
export default {
  name: '',
  data () {
    return {
      fatherId:'',  //详情id
      dialogShow: false,  //模态框
    }
  },
components: { // 组件的引用
    Dialog
  },
  methods: { 
     //吊起模态框
    activitySet() {
      this.dialogShow= true;
      this.$nextTick(() => {   //此函数执行时所有的DOM挂载和渲染都已完成
        this.$refs.dialogRef.init(this.fatherId);     //获取子组件中init方法并将父组件id传递给子组件
      });
    },
    //确定按钮
    setActivityBtn(data) { //获取子组件传来的值
      let params = data
      XXXXXXXX(params).then(res => {
        if (res.data.code == 0) {
          this.dialogFormVisible = false
        }
      })
    },
}
</script>

三.拓展

方式一、父子组件通过ref传值,然后在子组件中data函数直接return获得

父组件中:可以通过ref向子组件传值

this.$refs.dialogRef.name1=this.fatherName1  
this.$refs.dialogRef.name2=this.fatherName2

子组件中:可以通过数组的形式向父组件传递多个参数

this.$emit("setActivityBtn", [this.SetForm,this.dialogFormVisible]);

方式二.v-bind绑定,子组件中props接受,return中定义要改变传给父组件的属性:

父组件

<script>
     this.fatherName= this.detailData.name;
     this.fatherSalePrice= this.detailData.salePrice;
</script>

子组件

<script>
  export default {
       props: {
            sonName: {
                type:String,
                default:''
            },
            sonSalePrice: {
                type:Number,
                default:0
            },
        },
        data:function () {
            return {
                cartName:this.sonName,
                cartSalePrice:this.sonSalePrice
            }
        },
        methods: {
            addCart() {
                this.$emit('confirmAddCart',[this.cartName,this.cartSalePrice]);
            }
        }
  }
</script>

注:vue的思想是数据驱动视图,所以尽量少的用直接操作dom,当然一些需要获取元素宽高等场景时也会用到$refs
事件驱动

四 vue的思想是数据驱动视图

在前端来说数据驱动式框架,必然离不开事件驱动,事件驱动一定程度上弥补了数据驱动的不足,在dom操作的时代通常都是这样操作:
通过特定的选择器查找到需要操作的节点 -> 给节点添加相应的事件监听
响应用户操作,效果是这样:
用户执行某事件(点击,输入,后退等等) -> 调用 JavaScript 来修改节点
这种模式对业务来说是没有什么问题,但是从开发成本和效率来说会比较力不从心,在业务系统越来越庞大的时候,就显得复杂了。另一方面,找节点和修改节点这件事,效率本身就很低,因此出现了数据驱动模式。

数据驱动

读取模板,同时获得数据,并建立 VM( view-model ) 的抽象层 -> 在页面进行填充
要注意的是,MVVM 对应了三个层,M - Model,可以简单的理解为数据层;V - View,可以理解为视图,或者网页界面;VM - ViewModel,一个抽象层,简单来说可以认为是 V 层中抽象出的数据对象,并且可以与V 和 M 双向互动(一般实现是基于双向绑定,双向绑定的处理方式在不同框架中不尽相同)。
用户执行某个操作 -> 反馈到 VM 处理(可以导致 Model 变动) -> VM 层改变,通过绑定关系直接更新页面对应位置的数据

Vue 模式

Vue 通过{{}}绑定文本节点,data里动态数据与Props静态数据进行一个映射关系,当data中的属性或者props中的属性有变动,以上两者里的每个数据都是行为操作需要的数据或者模板 view 需要渲染的数据,一旦其中一个属性发生变化,则所有关联的行为操作和数据渲染的模板上的数据同一时间进行同步变化,这种基于数据驱动的模式更简便于大型应用开发。只要合理的组织数据和代码,就不会显得后续皮软。

何为动态数据 data,何为静态数据 props

  • 相同点

两者选项里都可以存放各种类型的数据,当行为操作改变时,所有行为操作所用到和模板所渲染的数据同时都会发生同步变化。

  • 不同点

Data 被称之为动态数据的原因,在各自实例中,在任何情况下,我们都可以随意改变它的数据类型和数据结构,不会被任何环境所影响。

Props 被称之为静态数据的原因,在各自实例中,一旦在初始化被定义好类型时,基于 Vue 是单向数据流,在数据传递时始终不能改变它的数据类型。

更为关键地是,对数据单向流的理解,props的数据都是通过父组件或者更高层级的组件数据或者字面量的方式进行传递的,不允许直接操作改变各自实例中的props数据,而是需要通过别的手段,改变传递源中的数据。

  • data 选项

当一个实例创建的时候,Vue会将其响应系统的数据放在data选项中,当这些属性的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。初始定行的行为代码也都会随着响应系统进行一个映射。

而 data 选项中的数据在实例中可以任意改变,不受任何影响,前提必须数据要跟逻辑相辅相成。

  • 初始化映射
<template>
   <div>
      <p v-if='boolean'>true</p>
      <p v-for='value in obj'>{{value}}</p>
      <p v-for='item in list'>{{item}}</p>
      <p>{{StringMsg}}</p>
      <p>{{NumberMsg}}</p>
   </div>
</template>
<script>
   export default {
     data () {
       return  {
          obj : {a:'1',b:'2',c:'3'},
          list:['a','b','c'],
          boolean : true,
          StringMsg : 'hello vue',
          NumberMsg : 2.4,
       }
     }
   }
</script>

运行代码时,在data选项里定义了五种数据类型,通过指令和{{}}进行渲染,证实了data选项里可以定义任何数据类型。

  • 视图与数据映射
<template>
   <div>
      <p>{{StringMsg}}</p>
      <p>{{NumberMsg}}</p>
      <button @click='changeData'>改变数据</button>
   </div>
</template>
<script>
   export default {
     data () {
       return  {
          StringMsg : 'hello vue',
          NumberMsg : 2.4
       }
     },
     methods: {
       changeData () {
         this.StringMsg = 2.4;
         this. NumberMsg = 'hello vue'
       }
     }
   }
</script>

每个.vue 的文件则就是一个实例,在 data 中定义了两种数据:

String 类型
Number 类型
同时还定义了一个 changeData 事件。

在运行代码时候,data选项已经进入了Vue的响应系统里,model层(数据层)与view层(视图层)进行了对应的映射,任何数据类型都可以定义。

当用户发生点击操作的时候,同时可以把 StringMsg, NumberMsg 的数据对调,充分说明了,无论值和类形都可以进行随意转换。

  • 行为与数据的映射
<template>
   <div>
      <p>{{StringMsg}}</p>
      <p>{{NumberMsg}}</p>
      <button @click='changeData'>改变数据</button>
      <button @click='findData'>查看数据</button>
   </div>
</template>
<script>
   export default {
     data () {
       return  {
          StringMsg : 'hello vue',
          NumberMsg : 2.4
       }
     },
     methods: {
       changeData () {
         this.StringMsg = 2.4;
         this.NumberMsg = 'hello vue'
       },
       findData () {
         console.log(`StringMsg: ${this.StringMsg}`)
         console.log(`NumberMsg: ${this.NumberMsg}`)
       }
     }
   }
</script>

改变数据以后,通过点击 findData 事件来进行验证,虽然在初始化定义好了行为数据的检测代码,但是当数据在执行 findData 之前先执行 changeData,一旦改变 data 选项里的数据时,findData 里对应的数据同时也会进行相应的映射。

this.StringMsg //=> 2.4

this.NumberMsg //=>‘hello vue’

五 、总结:

  1. data 选项里的数据是灵活的
  2. 可以定义任何数据类型
  3. 也可以改变成任何数据类型
  4. 当数据变化时,视图和行为绑定的数据都会同步改变

props

  1. 使用props传递数据作用域是孤立的,它是父组件通过模板传递而来,想接收到父组件传来的数据,需要通过props选项来进行接收。
  2. 子组件需要显示的声明接收父组件传递来的数据的数量,类型,初始值。
  3. 简单的接收可以通过数组的形式来进行接收。

父组件

<template>
   <div>
      <demo :msg='msgData' :math = 'mathData' ></demo>
   </div>
</template>
<script>
import Demo from './Demo.vue'
   export default {
     data () {
       return  {
          msgData:'从父组件接收来的数据',
          mathData : 2
       }
     },
     components : {
       Demo
     }
   }
</script>

子组件

<template>
  <div>
     <p>{{msg}}</p>
     <p>{{math}}</p>
  </div>
</template>

<script>
export default {
  name: 'demo',
  props: [ 'msg' , 'math'],
}
</script>

在子组件中需要通过显示定义好需要从父组件中接收那些数据。

同样的在父组件中在子组件模板中过v-bind来传递子组件中需要显示接收的数据。

语法: :== v-bind(是封装的语法糖) :msg = msgData

msg 第一个参数必须要与子组件的 props 同名
msgData 则是父组件中需要向子组传递的数据
props 可以显示定义一个或一个以上的数据,对于接收的数据,可以是各种数据类型,同样也可以传递一个函数。

父组件

<template>
   <div>
      <demo :fn = 'myFunction'  ></demo>
   </div>
</template>
<script>
import Demo from './Demo.vue'
   export default {
     components : {
       Demo
     },
     methods: {
       myFunction () {
           console.log('vue')
       }
     }
   }
</script>

六 、为什么会出现MVVM?

1. 首先解释:MVVM是什么?干什么用的?

1:MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式。

2:其核心是提供对View  ViewModel 的双向数据绑定,这使得ViewModel 的状态改变可以自动传递给 View,即所谓的数据双向绑定。

3:以Vue.js 为例。Vue是一个提供了 MVVM 风格的双向数据绑定的 Javascript 库,专注于View 层。

4:它的核心是 MVVM 中的 VM,也就是 ViewModel。 ViewModel负责连接 View  Model,保证视图和数据的一致性,这种轻量级的架构让前端开发
更加高效、便捷。

在这里插入图片描述

  • Model - 模型、数据
  • View - 视图、模板(视图和模型是分离的)
  • ViewModel - 连接 ModelView
    在这里插入图片描述

本文来源:码农网
本文链接:https://www.codercto.com/a/33262.html

2.为什么会出现MVVM? 框架的发展? MVC----MVP----MVVM

1:最初是MVC:MVC是一种架构模式,M表示Model,V表示视图View,C表示控制器Controller
		    就是 模型—视图—控制器,也就是说一个标准的Web 应用程式是由这三部分组成的
		    
2:在HTML5 还未火起来的那些年,MVC 作为Web 应用的最佳实践是OK .

3:这是因为 Web 应用的View 层相对来说比较简单,前端所需要的数据在后端基本上都可以处理好

4:View 层主要是做一下展示,那时候提倡的是 Controller 来处理复杂的业务逻辑,所以View 层相对来说比较轻量,就是所谓的瘦客户端思想。

在这里插入图片描述

1 开发者在代码中大量调用相同的 DOM API,处理繁琐 ,操作冗余,使得代码难以维护。

2、大量的DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。

3  Model 频繁发生变化,开发者需要主动更新到View ;当用户的操作导致 Model 发生变化,开发者同样需要将变化的数据同步到Model 中,这样
的工作不仅繁琐,而且很难维护复杂多变的数据状态。

MVVM的出现完美的解决了上面的几个问题:

1:MVVM  Model、View、ViewModel 三部分构成,Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负
责将数据模型转化成UI 展现出来,ViewModel 是一个同步View  Model的对象。

2:在MVVM架构下,View  Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model  ViewModel 之间的交互是双向的, 因此View 
据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
3:ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View  Model 之间的同步工作完全是自动的,无需人为干涉,因此开发
者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。

3. Vue.js与MVVM的关系?

Vue.js 可以说是MVVM 架构的最佳实践,VUE并没有完全遵循MVVM,专注于 MVVM 中的 ViewModel,不仅做到了数据双向绑定,而且也是一款相对比较轻量级的JS 库,API 简洁,很容易上手。

Vue.js 是采用 Object.defineProperty  getter  setter,并结合观察者模式来实现数据绑定的。
当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

在这里插入图片描述
在这里插入图片描述

3.1 关于 ViewModel

MVVM ViewModel
在这里插入图片描述

v-model用于表单数据的双向绑定

v-model用于表单数据的双向绑定,其实它就是一个语法糖,这个背后就做了两个操作:

    1. v-bind绑定一个value属性
    1. v-on指令给当前元素绑定input事件

自定义组件使用v-model,应该有以下操作:

  • 接收一个value prop
  • 触发input事件,并传入新值

在原生表单元素中:

<input v-model="inputValue">

相当于

<input v-bind:value="inputValue" v-on:input="inputValue = $event.target.value">

在自定义组件中

<my-component v-model="inputValue"></my-component>

相当于

<my-component v-bind:value="inputValue" v-on:input="inputValue = argument[0]"></my-component>

这个时候,inputValue接受的值就是input事件的回调函数的第一个参数,所以在自定义组件中,要实现数据绑定,还需要$emit去触发input的事件。

this.$emit('input', value)

3.2 MVVM 框架的三大要素

  • 响应式: vue 如何监听到 data 的每个属性变化?
  • 模板引擎: vue 的模板如何被解析,指令如何处理?
  • 渲染: vue 的模板如何被渲染成 html ?以及渲染过程

3.3 vue 中如何实现响应式

3.3.1 什么是响应式

修改 data 属性之后,vue 立刻监听到
data 属性被代理到 vm 上

在这里插入图片描述

3.3.1 .2 Object.defineProperty

在这里插入图片描述

3.3.1 .3 模拟实现

在这里插入图片描述

在这里插入图片描述

4. vue 中如何解析模板

4.1 模板是什么
  • 本质:字符串
  • 有逻辑,如 v-if v-for 等
  • 与 html 格式很像,但有很大区别
  • 最终还要转换为 html 来显示

模板最终必须转换成 JS 代码,因为

  • 有逻辑( v-if v-for ),必须用 JS 才能实现
  • 转换为 html 渲染页面,必须用 JS 才能实现
  • 因此,模板最重要转换成一个 JS 函数( render 函数)

在这里插入图片描述

4.2 render 函数
  • 模板中所有信息都包含在了 render 函数中
  • this 即 vm
  • price 即 this.price 即 vm.price ,即 data 中的 price
  • _c 即 this._c 即 vm._c

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

4.3 render 函数与 vdom
  • vm._c 其实就相当于 snabbdom 中的 h 函数
  • render 函数执行之后,返回的是 vnode

在这里插入图片描述
在这里插入图片描述

  • updateComponent 中实现了 vdompatch
  • 页面首次渲染执行 updateComponent
  • data 中每次修改属性,执行 updateComponent

五、vue 的整个实现流程

  • 第一步:解析模板成 render 函数
  • 第二步:响应式开始监听
  • 第三步:首次渲染,显示页面,且绑定依赖
  • 第四步: data 属性变化,触发 rerender

在这里插入图片描述

5.1 第一步:解析模板成 render 函数

在这里插入图片描述

在这里插入图片描述

  • 模板中的所有信息都被 render 函数包含
  • 模板中用到的 data 中的属性,都变成了 JS 变量
  • 模板中的 v-model v-for v-on 都变成了 JS 逻辑
  • render 函数返回 vnode
5.2 第二步:响应式开始监听
  • Object.defineProperty
  • 将 data 的属性代理到 vm 上

在这里插入图片描述

5.3 第三步:首次渲染,显示页面,且绑定依赖
  • 初次渲染,执行 updateComponent ,执行 vm._render()
  • 执行 render 函数,会访问到 vm.list vm.title
  • 会被响应式的 get 方法监听到
  • 执行 updateComponent ,会走到 vdompatch 方法
  • patchvnode 渲染成 DOM ,初次渲染完成

在这里插入图片描述
在这里插入图片描述

为何要监听 get ,直接监听 set 不行吗?

  • data 中有很多属性,有些被用到,有些可能不被用到
  • 被用到的会走到 get ,不被用到的不会走到 get
  • 未走到 get 中的属性, set 的时候我们也无需关心
  • 避免不必要的重复渲染

在这里插入图片描述

https://www.codercto.com/a/33262.html
前端面试之MVVM浅析

本文来源:码农网
本文链接:https://www.codercto.com/a/33262.html

超详细VUE专栏

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/129512.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Educational Codeforces Round 140 (Rated for Div. 2)

A. Cut the Triangle 题目链接&#xff1a;Problem - A - Codeforces 样例输入&#xff1a; 44 7 6 8 3 54 5 4 7 6 85 8 1 8 2 53 6 6 6 6 3 样例输出&#xff1a; YES YES YES NO题意&#xff1a;在二维平面上给定一个非退化三角形的三个顶点&#xff0c;问我们能不能用…

NVIDA CUDA和cuDNN安装教程

文章目录一. 查看自己的GPU版本是否支持cuda二 .安装CUDA三. 安装cuDNN一. 查看自己的GPU版本是否支持cuda 打开显卡的控制面板&#xff0c;查看显卡是否支持cuda 二 .安装CUDA 去官网查看cuda版本与所需系统固件的对应关系 从官网下载所需的CUDA Toolkit Archive,这里下载…

04-Css+Nginx

前端入门——CSS 1 CSS入门 1.1 初识CSS 1.1.1 概述 在学习了基本HTML标签和样式后&#xff0c;接下来学习前端开发的第二门技术。 我们发现&#xff0c;虽然标签的属性可以调整一些样式&#xff0c;但是效果不够理想&#xff0c;而我们更愿意把样式编写在<style> 标…

CSS 实现七彩圆环loading动画

前言 &#x1f44f;CSS 实现七彩圆环loading动画&#xff0c;速速来Get吧~ &#x1f947;文末分享源代码。记得点赞关注收藏&#xff01; 1.实现效果 2.实现步骤 定义父容器宽度为–w&#xff0c;每个圆环之间的gap间距为–gap&#xff0c;圆环的border边框宽为–border&am…

7个从Windows计算机上恢复Word文档的方法

你是否有受到Windows上损坏或丢失的Word文件的困扰&#xff1f;好吧&#xff0c;你并不孤单&#xff01; 文件损坏是 Word 文档的常见问题。此外&#xff0c;人们不小心删除了文件或忘记保存最新版本。 由于Word文件通常包含您在个人或职业生涯中所需的重要数据&#xff0c;因…

JavaWeb:Maven创建Web项目

1.1 Web项目结构 Web项目的结构分为&#xff1a;开发中的项目和开发完可以部署的Web项目&#xff0c;这两种项目的结构是不一样的&#xff0c;我们一个个来介绍下&#xff1a; Maven Web项目结构&#xff1a;开发中的项目 开发完成部署的Web项目 开发项目通过执行Maven打包…

python为你画虎迎新年,结束旧年迎新景

前言 2022年是农历壬寅虎年&#xff0c;虎作为十二生肖是家喻户晓的 据学者考证&#xff0c;其应当起源于楚文化中对虎的图腾崇拜&#xff0c;象征力量与威严。 虎者&#xff0c;百兽之王&#xff0c;是威猛的象征&#xff0c;为镇宅辟邪之灵物。 虎在民间习俗中被尊崇为瑞兽…

高斯分布下的线性判别函数简介

协方差矩阵的性质 实对称矩阵&#xff08;第iii元素和第jjj元素的耦合与第jjj元素和第iii元素的耦合相等&#xff09;Eigenvalues & eigenvecters (本征值, 本征向量) ΣϕiλiϕiΦ[ϕ1ϕ2⋯ϕd]Λdiag⁡[λ1,λ2,⋯,λd]\Sigma \phi_i\lambda_i \phi_i \quad \Phi\left[…

oracle安装完成后,只能在本地链接

Oracle搭建好了之后&#xff0c;发现只能在服务器本机链接oracle&#xff0c;其他客户端无法链接&#xff0c;这是因为监听地址是本地localhost&#xff0c;重建监听即可 lsnrctl status 查看监听的名称 lsnrctl stop 停止监听&#xff0c;并关闭数据库 sqlplus / as sysdba…

基于人工神经网络的空压机负荷预测(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

爱站权重怎么查询?怎么做爱站号权重高一些?

这一篇又是网站权重查询和提高权重的分享&#xff0c;爱站权重怎样查询&#xff1f;怎么提高爱站权重&#xff1f; 大家一起来看看嘿。 爱站权重怎样查询&#xff1f; 第一步&#xff1a;打开iis7站长之家seo批量检测&#xff0c;在左上方的框框里面输入需要的域名/网站地址…

数据结构-二叉树详解

目录 一.二叉树 1.概念及结构 2.特殊的二叉树 3.性质与解题 4.存储结构 二.顺序结构与堆 1.堆的概念及结构 2.堆的创建 3.堆的插入 4.堆的删除 5.堆的具体实现 6.堆的应用&#xff1a;堆排序和OPK问题 三.链式二叉树 1.前序/中序/后序遍历 2.层序遍历 3.结点个数…

effective C++读书笔记2

目录 了解C默认编写并调用的函数 若不想使用编译器自动生成的函数&#xff0c;就要明确拒绝 为多态基类声明virtual析构函数 不要让异常逃离析构函数 绝不在构造和析构过程中调用virtual函数 在operator处理自我赋值 复制对象时不要忘记其每一个成分 这是effective C第二章…

Java高效率复习-SpringMVC[SpringMVC]

SpringMVC的简介 表述层前端页面Servlet 入门案例-创建SpringMVC 创建Maven工程 创建Maven工程后&#xff0c;pom文件的打工方式是war包&#xff0c;表示web应用打包方式。 正确的web.xml文件创建路径 src\main\webapp\WEB-INF\web.xml添加依赖 spring-web:5.3.1是SpringM…

java 多线程编程

Java 给多线程编程提供了内置的支持。 一条线程指的是进程中一个单一顺序的控制流&#xff0c;一个进程中可以并发多个线程&#xff0c;每条线程并行执行不同的任务。 多线程是多任务的一种特别的形式&#xff0c;但多线程使用了更小的资源开销。 这里定义和线程相关的另一个…

用户手册编写的终极指南

用户手册对于寻求了解产品和流程的用户来说是非常重要的。有时&#xff0c;它们甚至是一个公司向客户销售其产品的法律要求。 客户往往会在联系你的客户支持团队之前查阅你的用户手册&#xff0c;所以你的手册有可能为你节省支持成本。 在你的用户手册上投入大量时间和精力是…

PHP---表单传值

目录 一、表单传值的概念 二、表单传值的方式 &#xff08;1&#xff09;GET和POST的区别 &#xff08;2&#xff09;GET方式 &#xff08;3&#xff09;POST方式 三、接受表单数据 四、处理复选框的注意点 (1)单选框的数据处理 &#xff08;2&#xff09;复选框的数据…

机器学习100天(二十一):021 分类模型评价指标-ROC曲线和AUC

机器学习100天!今天讲的是:分类模型评价指标-ROC曲线和AUC 《机器学习100天》完整目录:目录 首先基于混淆矩阵,介绍两个新的概念:真正例率(TPR)和假正例率(FPR)。真正例率是预测为正且实际为正的样本的占所有正例样本的比例。TPR 越大,预测的正类中实际正类越多。计…

跳板攻击原理及如何追踪定位攻击者主机(下)

跳板攻击溯源中&#xff0c;我们需要先确定本地网络中是否存在攻击者的跳板。具体可参考&#xff08;跳板攻击原理及如何追踪定位攻击者主机&#xff08;上&#xff09;&#xff09; 那么在本地网络中发现跳板后&#xff0c;又要如何追踪定位攻击者主机&#xff1f; 这种情况…

【苹果相册推】增加家庭对方下载 zookeeper-3.4.12.tar.gz #编削配置装备摆设 vim conf/zoo.cfg

推荐内容IMESSGAE相关 作者推荐内容iMessage苹果推软件 *** 点击即可查看作者要求内容信息作者推荐内容1.家庭推内容 *** 点击即可查看作者要求内容信息作者推荐内容2.相册推 *** 点击即可查看作者要求内容信息作者推荐内容3.日历推 *** 点击即可查看作者要求内容信息作者推荐…