【vue】方法、计算属性、数据监听

方法(methods)

<template>
   <div>
       <p>原始数据:{{message}}"</p>
       <p>反转后的数据:"{{reverseMessage()}}"</p>
   </div>
</template>

<script>

export default {
    data(){
        return {
            message:"hello"
        }
    },
    methods:{
        reverseMessage:function(){
            return this.message.split('').reverse().join('')
        }
    }
}
</script>

计算属性 (computed)

<template>
   <div>
       <p>原始数据:{{message}}"</p>
       <p>反转后的数据:"{{reversedMessage}}"</p>
   </div>
</template>

<script>

export default {
    data(){
        return {
            message:"hello"
        }
    },
    computed:{
        reversedMessage:function(){
            return this.message.split('').reverse().join('')
        }
    }
}
</script>

计算属性默认只有getter
本例中,计算属性computed.reversedMessagegetter就是
function(){ return this.message.split('').reverse().join('') }
当然,也可以将该函数直接写成getter,像这样,

    //也可以直接写成getter
    computed:{
        reversedMessage:{
            get(){
                return this.message.split('').reverse().join('')
            }
        }
    }

getter,当然也可以提供setter,如下,

    //当然,也可以提供setter
    computed:{
        reversedMessage:{
            get(){
                return this.message.split('').reverse().join('')
            },
            set(val){
                this.message = val+"hahaha";
            }
        }
    },

呃,对比下,方法 和 计算属性 好像没啥区别,都实现了字符串反转。
别着急下定论,继续往下看。

方法 与 计算属性

<template>
   <div>
       <p>原始数据:{{message}}"</p>
       <p>反转后的数据:"{{reverseMessage()}}"</p>
       <p>反转后的数据:"{{reversedMessage}}"</p>
   </div>
</template>

<script>

export default {
    data(){
        return {
            message:"hello"
        }
    },
    methods:{
        reverseMessage:function(){
            console.log("reversing message in methods at "+ new Date().toLocaleTimeString());
            return this.message.split('').reverse().join('')
        }
    },
    computed:{
        reversedMessage:function(){
            console.log("reversing message in computed at "+ new Date().toLocaleTimeString());
            return this.message.split('').reverse().join('')
        }
    },
    mounted:function(){
        setTimeout(() => {
            this.$forceUpdate();
        },5000);
        // setTimeout(() => {
        //     this.message = "world";
        // },3000)
    }
}
</script>

在这里插入图片描述
5秒后,强制组件重新渲染。
这时,方法中的函数reverseMessage再次执行了,但 计算属性reversedMessagegetter函数没有被再次调用,因为 它被 缓存 了。
是的,计算属性会被缓存,且只有它依赖的数据发生变化时,计算属性才会更新。

数据监听

当一个数据依赖另一个数据时,要实现数据同步, 计算属性 是一个方法。
另一个方法就是 使用watch 监听数据。

<template>
   <div>
       <p>原始数据:{{message}}"</p>
       <p>反转后的数据:"{{reversedMessage}}"</p>
   </div>
</template>

<script>
export default {
    data(){
        return {
            message:"",
            reversedMessage:''
        }
    },
    watch:{
        message:function(newMessage){
            this.reversedMessage = newMessage.split('').reverse().join('')
        }
    },
    mounted:function(){
        setTimeout(() => {
            this.message = "hello";
        },3000)
    }
}
</script>

监听message,当它发生变化时,同步更新reversedMessage

watch在异步中的应用
代码结构

在这里插入图片描述

服务端
  • answers.json
{
    "0":"Yes",
    "1":"Yes",
    "2":"No"
}
  • server.js
const express = require("express");
const fs = require("fs");
const app = express();

app.use(express.static("../dist"));
app.get("/get/:id",(req,res) => {
    fs.readFile('./answers.json','utf-8',(err,data)=>{
        var data = JSON.parse(data);
        const answer = data[req.params.id];
        res.writeHead(200,"ok",{"Content-Type":"text/plain"});
        res.end(answer);
    })
})

app.listen(3000,()=>{
    console.log("listening on *:3000");
})
客户端
  • webpack.config.js
const path = require('path');
const VueLoaderPlugin = require("vue-loader/lib/plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
module.exports = {
    mode:"development",
    devtool:"cheap-source-map",
    entry:{
        "index":"./index.js"
    },
    output:{
        filename:"[name].bundle.js",
        path:path.resolve(__dirname,"dist")
    },
    module:{
        rules:[
            {
                test:/\.vue$/,
                loader:'vue-loader'
            },
            {
                test:/\.css$/,
                loader:[
                    'vue-style-loader',
                    'css-loader'
                ]
            },
            {
                test:/\.js$/,
                loader:'babel-loader'
            }
        ]
    },
    plugins:[
        new VueLoaderPlugin(),
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            template:'./index.html'
        })
    ]
}
  • index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>index</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
  • index.js
import Vue from "vue";
import Helloworld from "./src/helloworld.vue";

const vm = new Vue({
    render:(h) => h(Helloworld),
}).$mount("#root");
  • helloworld.vue
    npm install --save lodash axios
    这里用到了防抖_.debounce(fn,delay),保证输入框输入完毕方发送请求。
<template>
   <div>
       <p><input type="text" v-model="question" /></p>
       <p>{{answer}}</p>
   </div>
</template>

<script>
import _ from "lodash";
import axios from "axios";
export default {
    data(){
        return {
            question:"",
            answer:"I cannot give u an answer util u ask a question!"
        }
    },
    watch:{
        question:function(newQuestion,oldQuestion){
            this.answer = "waiting for u to stop typing...";
            this.debounceGetAnswer();
        }
    },
    created:function(){
        this.debounceGetAnswer = _.debounce(this.getAnswer,500);
    },
    methods:{
        getAnswer:function(){
            const idx = parseInt(Math.random()*2);
            const vm = this;
            axios.get("/get/"+idx).then((response) => {
                vm.answer = response.data;
            }).catch(err => {
                vm.answer = "An error occurred,cannot get answer";
            })
        }
    }
}
</script>

node server.js,启动服务端,
浏览器地址栏输入localhost:3000,效果如下:
在这里插入图片描述

参考文章

侦听器
_.debounce
axios

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值