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. 복잡한 사용

   이제 많은 책 개체를 포함하는 배열 데이터 책이 있으며 데이터 구조는 다음과 같습니다.

books:[ 
          {id:110,name:"입력부터 종료까지의 JavaScript",price:119}, 
          {id:111,name:"입력부터 포기까지의 Java",price:80}, 
          {id:112,name: "코딩의 예술",가격:99}, 
          {id:113,이름:"코드 백과사전",가격: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동일한 속성의 경우 메소드가 4번 호출되는 반면 계산된 속성은 한 번만 호출되므로 계산된 속성의 성능이 메소드보다 확실히 좋습니다. 그리고 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 속성은 계산을 사용하여 계산되며 값은 firstName+lastName입니다. 계산 속성에는 缓存功能firstName과 lastName이 변경되지 않으면 fullName이 다시 계산되지 않습니다. 예를 들어 age 값을 변경하면 fullName 값을 다시 계산할 필요가 없습니다.
  2. 메소드에는 캐싱 기능이 없으며, 예를 들어 age 값을 변경하면 fullName2() 메소드가 다시 실행됩니다.
  3. 위의 세 가지 방법으로 함수를 실현할 수 있는 경우 계산을 사용하는 것이 더 적절하고 코드가 간단하며 캐싱 기능이 있습니다.
  4. 계산된 속성의 범위는 Vue 인스턴스 내에 있으며, Vue 인스턴스의 외부 객체를 수정하면 렌더링이 다시 계산되지 않지만, Vue 인스턴스 외부의 객체가 먼저 수정된 다음 Vue 계산 속성의 객체가 수정되면, 외부 개체의 값도 다시 렌더링됩니다.

계산된 속성: 계산됨

     Vue 인스턴스의 fullName에서 계산 속성 범위로 관리되는 firstName 및 lastName은 일반적으로 여러 변수를 수신합니다. 1111

청취자: 시청하세요

     데이터 변경 사항을 모니터링합니다. 일반적으로 변수나 배열만 모니터링합니다.

사용되는 장면

      watch( 异步场景), 계산( 数据联动) 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>

 핸들러 메소드는 일반 리스너에 의해 트리거되는 이벤트와 동일하며, 결과를 보면 컴포넌트가 초기화될 때 리스너에 핸들러 메소드가 없으므로 fullName에 값이 없음을 알 수 있습니다.

위 코드를 수정할 때 Immediate: true를 추가하고, Immediate: true를 추가하면 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">
          <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>

입력창에 데이터를 입력하면 fullName의 값이 변경되지 않은 것을 확인할 수 있는데, 이는 Vue가 person.firstname 변경 등 객체의 내부 속성값 변경을 감지할 수 없기 때문입니다.

그래서 이때 vue의 딥 모니터링(deep)을 사용해야 합니다.

이때 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