Оглавление
4. Сравнение свойств и методов
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.
Вывод теста:
- Атрибут FullName рассчитывается с использованием метода Computed, а его значение равно FirstName+lastName. Вычислительные свойства имеют
缓存功能
, когда firstName и LastName не меняются, FullName не будет пересчитываться, например, если мы изменим значение age, значение FullName пересчитывать не нужно.- Методы не имеют функции кэширования.Например, если мы изменим значение age, метод fullName2() будет выполнен снова.
- Когда функцию можно реализовать тремя вышеуказанными методами, очевидно, более целесообразно использовать вычисляемый код, поскольку код прост и имеет функции кэширования.
- Область действия вычисляемого атрибута находится внутри экземпляра 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>