Vue — вычисляемые свойства и слушатели

Оглавление

1. Расчетные свойства

1. Основное использование

2. Сложное использование

3. геттер и сеттер

4. Сравнение свойств и методов

Во-вторых, слушатель

1. Использование часов


1. Расчетные свойства

1. Основное использование

​ Теперь есть переменные фамилия и имя, чтобы получить полное имя.

   <div id="app">

        <h2>您的firstname:{
   
   {firstName}}</h2>
        <h2>您的lastname:{
   
   {lastName}}</h2>
        
        <h2>您的fullname是从计算属性中得到:{
   
   {fullName}}</h2>

        <h2>您的fullname是从方法中得到:{
   
   {getFullName()}}</h2>

    </div>
    <script>
        Vue.config.productionTip = false;  //阻止 vue 在启动时生成生产提示。
        const vm = new Vue({
            el: '#app',
            data(){
                return{
                    firstName:'zhang',
                    lastName:'san'
                }
            },
            methods: {
                getFullName(){
                    return this.firstName + this.lastName
                }
            },
            computed:{//计算属性 一定要有一个返回值 在页面中渲染时是不需要加小括号的
                fullName(){
                    return this.firstName + this.lastName
                }
            }
        })
    </script>

  Сращивание с использованием синтаксиса Mastache<h2>{ {firstName}}{ {lastName}}</h2>

  Как использовать методы<h2>{ {getFullName()}}</h2>

  Используя вычисленное свойство, вычисленное<h2>{ {fullName}}</h2>

В этом примере вычисляемый атрибут выглядит так же, как метод, за исключением того, что для вызовов метода необходимо использовать (), а для вычисляемых атрибутов — нет. Имя метода обычно представляет собой глагол, а имя вычисляемого атрибута — существительное. , но это всего лишь базовое использование. 

2. Сложное использование

   Теперь существует массив данных book, который содержит множество объектов book, структура данных следующая:

book:[ 
          {id:110,name:"JavaScript от входа до входа",price:119}, 
          {id:111,name:"Java от входа до закрытия",price:80}, 
          {id:112,name: "Искусство кодирования",цена:99}, 
          {id:113,name:"Энциклопедия кода",цена:150}, 
        ]

    ​ Требуется посчитать общую стоимость всех книг totalPrice.

<div id="app">
			<h2>您的总价:{
   
   {totalPrice}}</h2>
		</div>
		<script>
			const vm = new Vue({
				el: '#app',
				data() {
					return {
						books: [{
								id: 110,
								name: "JavaScript从入门到入土",
								price: 119
							},
							{
								id: 111,
								name: "Java从入门到放弃",
								price: 80
							},
							{
								id: 112,
								name: "编码艺术",
								price: 99
							},
							{
								id: 113,
								name: "代码大全",
								price: 150
							},
						]
					}
				},
				computed: {
					/* totalPrice() {
						let total = 0
						for (let i = 0; i < this.books.length; i++) {
                              total += this.books[i].price
						}
						return total
					} */
					
					/* totalPrice() {
						let total = 0
						for (let index in this.books) {
							total += this.books[index].price
						}
						return total
					} */
					
					/* totalPrice() {
						let total = 0;
						for(let item of this.books){
							total += item.price
						}
						return total
					} */
					
					/* totalPrice() {
						let total = 0;
						this.books.forEach(item=>{
							total += item.price
						})
						return total
					} */
					
					/* map */
					/* totalPrice() {
						let total = 0;
						this.books.map(item=>{
							total += item.price
						})
						return total
					} */
					
					/* filter */
					/* totalPrice() {
						let total = 0;
						this.books.filter(item=>{
							total += item.price
						})
						return total
					} */
					
					/* reduce */
					/* totalPrice() {
						return this.books.reduce((total,item)=>{
							 return total + item.price 
						},0)
					} */
					
					/* totalPrice() {
						return this.books.reduce((total,item)=>total + item.price,0)
					} */
					
					/* some */
					totalPrice() {
						let total = 0;
						this.books.some(item=>{
							total += item.price
						})
						return total
					}
					
				}
			})
		</script>

​ Получите накопленную цену каждого книжного объекта. Когда цена одной из книг изменится, общая цена изменится соответственно.

3. геттер и сеттер

В вычисляемом свойстве на самом деле есть два метода: setter и getter.

Но у вычисляемых свойств обычно нет метода set, у свойств только для чтения есть только метод get, но в приведенном выше примере newValue — это новое значение, вы также можете использовать метод set для установки значения, но, как правило, нет.

       <div id="app">
			<input type="text" v-model="firstName"/><br>
			<input type="text" v-model="lastName"/><br>
			<input type="text" v-model="fullName"/>
			<!-- v-model实现数据的双向绑定 -->
			<!-- 2.双向绑定(v-model):数据不仅能从data流向页面,还可以从页面流向data。
						备注:
								1.双向绑定一般都应用在表单类元素上(如:input、select等)
								2.v-model:value 可以简写为 v-model,因为v-model默认收集的就 
                                   是value值。 -->
		</div>
		<script>
			const vm = new Vue({
				el: '#app',
				data() {
					return {
						firstName: 'zhang',
						lastName: 'san'
					}
				},
				computed: { //计算属性 一定要有一个返回值 在页面中渲染时是不需要加小括号的
					/* fullName(){
						return this.firstName + this.lastName
					} */

					 fullName: {
						get: function() {
							return this.firstName +','+ this.lastName
						},
						set:function(val){
							var list = val.split(',')
							console.log(list);
							this.firstName = list[0]
							this.lastName = list[1]
						}
					} 
				}
			})
		</script>

 

 Таким образом, мы можем изменить значение свойства, связанное с вычисляемым свойством, одновременно изменяя значение вычисляемого свойства.

4. Сравнение свойств и методов

       <div id="app">
			<h2>您的fullname是从计算属性中得到:{
   
   {fullName}}</h2>
			<h2>您的fullname是从计算属性中得到:{
   
   {fullName}}</h2>
			<h2>您的fullname是从计算属性中得到:{
   
   {fullName}}</h2>
			<h2>您的fullname是从计算属性中得到:{
   
   {fullName}}</h2>
			
			<h2>您的fullname是从方法中得到:{
   
   {getFullName()}}</h2>
			<h2>您的fullname是从方法中得到:{
   
   {getFullName()}}</h2>
			<h2>您的fullname是从方法中得到:{
   
   {getFullName()}}</h2>
			<h2>您的fullname是从方法中得到:{
   
   {getFullName()}}</h2>
		</div>
		<script>
			const vm = new Vue({
				el:'#app',
				data(){
					return {
						firstName:'zhang',
						lastName:'san'
					}
				},
				methods:{
					getFullName(){
						console.log('这里调用了方法getFullName');
						return this.firstName + this.lastName
					}
				},
				computed:{//计算属性 一定要有一个返回值 在页面中渲染时是不需要加小括号的
					fullName(){
						console.log('这里调用了计算属性fullName');
						return this.firstName + this.lastName
					}
				}
			})
			
			/* 总结:计算属性的性能是优于方法的 因为计算属性是具有缓存特性的 */
		</script>

Видно, что вычисленный атрибут имеет кеш. В this.firstName + " " + this.lastNameслучае одного и того же атрибута методы вызываются четыре раза, а вычисленный атрибут вызывается только один раз. Производительность вычисленных атрибутов явно лучше, чем методов. А в случае изменения firstName вычисляемое свойство вызывается всего один раз, а методы все равно нужно вызывать 4 раза.

Во-вторых, слушатель

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>Vue计算属性/侦听器/方法比较</title>
        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <h1>计算属性:computed</h1>
            {
   
   {fullName}}
            <h1>方法:methods</h1>
            {
   
   {fullName2()}}
            <h1>侦听器:watch</h1>
            {
   
   {watchFullName}}
            <h1>年龄</h1>
            {
   
   {age}}
        </div>
        <script>
            var other = 'This is other';
            var app = new Vue({
                el:"#app",
                data:{
                firstName:"zhang",
                lastName:"san",
                watchFullName:"zhangsan",
                age:18,
                },
                watch: {
                    firstName:function(newFirstName, oldFirstName){
                        console.log("firstName触发了watch,newFirstName="+newFirstName+",oldFirstName="+oldFirstName)
                        this.watchFullName = this.firstName+this.lastName+","+other
                    },
                    lastName:function(newLastName, oldLastName){
                        console.log("lastName触发了watch,newLastName="+newLastName+",oldLastName="+oldLastName)
                        this.watchFullName = this.firstName+this.lastName+","+other
                    }  
                },
                computed: {
                    fullName:function(){
                    console.log("调用了fullName,计算了一次属性")
                    return this.firstName+this.lastName+","+other;
                    }
                },
                methods: {
                    fullName2:function(){
                        console.log("调用了fullName,执行了一次方法")
                        fullName2 = this.firstName+this.lastName+","+other;
                        return fullName2;
                    }
                }
            });
        </script>
    </body>
    </html>

инициализация:

 Изменить имя/фамилию/оба

 Измените возраст, который не рассчитывается в вычисленных

 Изменение объектов за пределами экземпляра Vue

 После изменения объекта вне экземпляра Vue измените объект внутри экземпляра Vue.

Вывод теста:

  1. Атрибут FullName рассчитывается с использованием метода Computed, а его значение равно FirstName+lastName. Вычислительные свойства имеют 缓存功能, когда firstName и LastName не меняются, FullName не будет пересчитываться, например, если мы изменим значение age, значение FullName пересчитывать не нужно.
  2. Методы не имеют функции кэширования.Например, если мы изменим значение age, метод fullName2() будет выполнен снова.
  3. Когда функцию можно реализовать тремя вышеуказанными методами, очевидно, более целесообразно использовать вычисляемый код, поскольку код прост и имеет функции кэширования.
  4. Область действия вычисляемого атрибута находится внутри экземпляра Vue, изменение внешнего объекта экземпляра Vue не приведет к перерасчету рендеринга, но если сначала изменяется объект вне экземпляра Vue, а затем изменяется объект вычисляемого атрибута Vue, значение внешнего объекта также будет перерисовано.

Вычисляемое свойство: вычислено

     FirstName и LastName, управляемые рассчитанным диапазоном атрибутов в полном имени экземпляра Vue, обычно прослушивают несколько переменных 1111.

Слушатель: смотреть

     Отслеживайте изменения данных, обычно отслеживайте только переменную или массив.

сцены, которые будут использоваться

      watch( 异步场景), Computed( 数据联动) Watch может напрямую добавлять имя метода в строковой форме после отслеживаемых данных.

<!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>Vue计算属性/侦听器/方法比较</title>
        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <h1>计算属性:computed</h1>
            {
   
   {fullName}}
            <h1>方法:methods</h1>
            {
   
   {fullName2()}}
            <h1>侦听器:watch</h1>
            {
   
   {watchFullName}}
            <h1>年龄</h1>
            {
   
   {age}}
        </div>
        <script>
            var other = 'This is other';
            var app = new Vue({
                el:"#app",
                data:{
                firstName:"zhang",
                lastName:"san",
                watchFullName:"zhangsan",
                age:18,
                },
                watch: {
                    firstName:function(newFirstName, oldFirstName){
                        console.log("firstName触发了watch,newFirstName="+newFirstName+",oldFirstName="+oldFirstName)
                        this.watchFullName = this.firstName+this.lastName+","+other
                    },
                    lastName:function(newLastName, oldLastName){
                        console.log("lastName触发了watch,newLastName="+newLastName+",oldLastName="+oldLastName)
                        this.watchFullName = this.firstName+this.lastName+","+other
                    },
                    watchFullName:"change"

                },
                computed: {
                    fullName:function(){
                    console.log("调用了fullName,计算了一次属性")
                    return this.firstName+this.lastName+","+other;
                    }
                },
                methods: {
                    fullName2:function(){
                        console.log("调用了fullName,执行了一次方法")
                        fullName2 = this.firstName+this.lastName+","+other;
                        return fullName2;
                    },
                    change(){
                        console.log("调用了change,触发了watch")
                        return this.watchFullName='111'
                    }
                }
            });
        </script>
    </body>
    </html>

 Метод обработчика эквивалентен событию, инициированному обычным прослушивателем. Из результатов мы видим, что при инициализации компонента прослушиватель не имеет метода-обработчика, поэтому полное имя не имеет значения.

Изменяя приведенный выше код, добавьте немедленный: true, немедленный: true означает, что после объявления часов функция в обработчике будет выполнена немедленно. Выполните соответствующую логику. Когда компонент инициализируется, прослушиватель немедленно запускает метод обработчика.

<!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>Vue计算属性/侦听器/方法比较</title>
        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
    </head>
    <body>
        <div id="app">
          <div>
            <p>FullName: {
   
   {person.fullname}}</p>
            <p>FirstName: <input type="text" v-model="person.firstname"></p>
          </div>
        </div>
        <script>
            var other = 'This is other';
            var app = new Vue({
              el: '#app',
               data(){
                return {
                    person: {
                        firstname: 'Menghui',
                        lastname: 'Jin',
                        fullname: ''
                    }
                }
              },
             watch: {
              person: {
                  handler(n,o){
                      this.person.fullname = n.firstname + '' + this.person.lastname;
                  },
                   immediate: true,  //刷新加载 立马触发一次handler
                  deep: true  // 可以深度检测到 person 对象的属性值的变化
              }
              }
            })
        </script>
    </body>
    </html>

При вводе данных в поле ввода можно обнаружить, что значение полного имени не изменилось.Это связано с тем, что Vue не может обнаружить изменение значения внутреннего свойства объекта, например изменение person.firstname.

Итак, на данный момент вам нужно использовать глубокий мониторинг vue (глубокий)

В это время добавьте код deep: true

Можно обнаружить, что полное имя меняется каждый раз, когда изменяются данные поля ввода.

Из вышеизложенного можно обнаружить, что новое значение, отслеживаемое обработчиком, совпадает со старым значением. Это вызвано колебаниями и гомологией ямы vue2.0, которые можно исправить с помощью вычисленных

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>

	</head>
	<body>
		<div id="app">
             <p>FullName: {
   
   {person.fullname}}</p>
             <p>FirstName: <input type="text" v-model="person.firstname"></p>
		</div>
		<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
		<script>
			const app = new Vue({
				el: "#app",
				data() {
					return {
						person: {
							firstname: 'Menghui',
							lastname: 'Jin',
							fullname: ''
						}
					}
				},
				methods: {

				},
				computed: {
                   person2(){
					    return JSON.parse(JSON.stringify(this.person));
				   }//解决深度监听新老值同源问题
				},
				watch:{
				   person2:{
					     handler(n,o){
							 console.log(this.person);
							 console.log(n.firstname);
					                 console.log(o.firstname);
							
							 /* this.person.fullname = this.person.firstname + this.person.lastname */
						 },
						/* immediate: true, */
						 deep: true  // 可以深度检测到 person 对象的属性值的变化
				   }
				}
			})
		</script>
	</body>
</html>

рекомендация

отblog.csdn.net/m0_46461853/article/details/126019079