The use of Vue computed attribute computed; methods VS computed attribute; listener watch; configuration options for listener watch

1_computed computed properties use

1.1_The processing method of complex data

In the template, some data in data can be displayed directly through interpolation syntax, such as the following code

<body>

  <div id="app">
    <!-- 插值语法表达式直接进行拼接 -->
    <!-- 1.拼接名字 -->
    <h2>{
   
   { firstName + " " + lastName }}</h2>
    <h2>{
   
   { firstName + " " + lastName }}</h2>
    <h2>{
   
   { firstName + " " + lastName }}</h2>

    <!-- 2.显示分数等级 -->
    <h2>{
   
   { score >= 60 ? '及格': '不及格' }}</h2>

    <!-- 3.反转单词显示文本 -->
    <h2>{
   
   { message.split(" ").reverse().join(" ") }}</h2>
  </div>
  
  <script src="../lib/vue.js"></script>
  <script>
    // 1.创建app
    const app = Vue.createApp({
      
      
      // data: option api
      data() {
      
      
        return {
      
      
          // 1.姓名
          firstName: "kobe",
          lastName: "bryant",

          // 2.分数: 及格/不及格
          score: 80,

          // 3.一串文本: 对文本中的单词进行反转显示
          message: "my name is hhh"
        }
      },
    })

    // 2.挂载app
    app.mount("#app")
  </script>
</body>

In some cases, it is necessary to perform some conversion on the data before displaying, or combine multiple data for display;

  • For example, it is necessary to perform operations on multiple data data, use a ternary operator to determine the result, and display the data after some transformation;
  • It is very convenient to use expressions in templates, but they are designed for simple operations;
  • Putting too much logic in the template will make the template heavy and difficult to maintain;
  • And if it is used in multiple places, there will be a lot of repeated code;

A way to pull the logic out?

  • One way is to extract the logic into a method and put it in the options of methods; however, this approach has an intuitive drawback, that is, all the data usage process will become a method call;
<body>

  <div id="app">
    <!-- 插值语法表达式直接进行拼接 -->
    <!-- 1.拼接名字 -->
    <h2>{
   
   { getFullname() }}</h2>
    <h2>{
   
   { getFullname() }}</h2>
    <h2>{
   
   { getFullname() }}</h2>
    <!-- 2.显示分数等级 -->
    <h2>{
   
   { getScoreLevel() }}</h2>
    <!-- 3.反转单词显示文本 -->
    <h2>{
   
   { reverseMessage() }}</h2>
  </div>
  
  <script src="../lib/vue.js"></script>
  <script>
    // 1.创建app
    const app = Vue.createApp({
      
      
      // data: option api
      data() {
      
      
        return {
      
      
          // 1.姓名
          firstName: "kobe",
          lastName: "bryant",

          // 2.分数: 及格/不及格
          score: 80,

          // 3.一串文本: 对文本中的单词进行反转显示
          message: "my name is hhh"
        }
      },
      methods: {
      
      
        getFullname() {
      
      
          return this.firstName + " " + this.lastName
        },
        getScoreLevel() {
      
      
          return this.score >= 60 ? "及格": "不及格"
        },
        reverseMessage() {
      
      
          return this.message.split(" ").reverse().join(" ")
        }
      }
    })
    // 2.挂载app
    app.mount("#app")
  </script>
</body>
  • Another way is to use the computed property computed;

1.2_ Calculated attribute computed

How to understand?

  • The official did not give a direct conceptual explanation;
  • Instead, you should use computed properties for any complex logic that includes reactive data;
  • Computed properties will be mixed into the component instance: the this context of all getters and setters is automatically bound to the component instance;

Computed property usage:

  • option: computed
  • 类型:{ [key: string]: Function | { get: Function, set: Function } }

According to the code of 1.1, use the computed attribute

<body>

  <div id="app">
    <!-- 1.拼接名字 -->
    <h2>{
   
   { fullname }}</h2>
    <h2>{
   
   { fullname }}</h2>
    <h2>{
   
   { fullname }}</h2>

    <!-- 2.显示分数等级 -->
    <h2>{
   
   { scoreLevel }}</h2>

    <!-- 3.反转单词显示文本 -->
    <h2>{
   
   { reverseMessage }}</h2>
  </div>
  
  <script src="../lib/vue.js"></script>
  <script>
    // 1.创建app
    const app = Vue.createApp({
      
      
      // data: option api
      data() {
      
      
        return {
      
      
          // 1.姓名
          firstName: "kobe",
          lastName: "bryant",

          // 2.分数: 及格/不及格
          score: 80,

          // 3.一串文本: 对文本中的单词进行反转显示
          message: "my name is hhh"
        }
      },
      computed: {
      
      
        // 1.计算属性默认对应的是一个函数
        fullname() {
      
      
          return this.firstName + " " + this.lastName
        },

        scoreLevel() {
      
      
          return this.score >= 60 ? "及格": "不及格"
        },

        reverseMessage() {
      
      
          return this.message.split(" ").reverse().join(" ")
        }
      }
    })

    // 2.挂载app
    app.mount("#app")
  </script>
</body>

1.3_ Computed properties vs methods

Although the implementation codes of computed properties and methods seem to have little difference, computed properties are cached.

Computed properties are cached based on their dependencies;

  • When the data does not change, the calculated attribute does not need to be recalculated; but the method is called once, and it is calculated once. In contrast, it consumes performance.
  • However, if the dependent data changes, the calculated property will still be recalculated when used;

Therefore, it is recommended to use the calculated property computed first


1.4_ Setters and getters of computed properties (understand)

In most cases, a computed property only needs a getter method, so the computed property is directly written as a function.

<body>

  <div id="app">
    <h2>{
   
   { fullname }}</h2>

    <button @click="setFullname">设置fullname</button>
  </div>
  
  <script src="../lib/vue.js"></script>
  <script>
    // 1.创建app
    const app = Vue.createApp({
      
      
      // data: option api
      data() {
      
      
        return {
      
      
          firstname: "coder",
          lastname: "hhh"
        }
      },
      computed: {
      
      
        // 语法糖的写法
        // fullname() {
      
      
        //   return this.firstname + " " + this.lastname
        // },
        
        // 完整的写法:
        fullname: {
      
      
          get: function() {
      
      
            return this.firstname + " " + this.lastname
          },
          set: function(value) {
      
      
            const names = value.split(" ")
            this.firstname = names[0]
            this.lastname = names[1]
          }
        }
      },
      methods: {
      
      
        setFullname() {
      
      
          this.fullname = "kobe bryant"
        }
      }
    })

    // 2.挂载app
    app.mount("#app")
  </script>
</body>

2_ listener watch

2.1_Knowledge

listener?

  • During development, the data is defined in the object returned by data, and this data is bound to the template through interpolation syntax, etc.;
  • When the data changes, the template will be automatically updated to display the latest data;
  • But in some cases, you want to monitor the change of a certain data in the code logic, then you need the listener watch to complete;

The usage of the listener is as follows:

  • option: watch
  • 类型:{ [key: string]: string | Function | Object | Array}

case:

  • For example, now you want the user to enter a question in the input;
  • Whenever the user enters the latest content, the latest content is obtained, and the question is used to query the answer from the server;
  • Then, it is necessary to obtain the latest data changes in real time;
<body>

  <div id="app">
    <h2>{
   
   {message}}</h2>
    <button @click="changeMessage">修改message</button>
  </div>
  
  <script src="../lib/vue.js"></script>
  <script>
    // Proxy -> Reflect
    // 1.创建app
    const app = Vue.createApp({
      
      
      // data: option api
      data() {
      
      
        return {
      
      
          message: "Hello Vue",
          info: {
      
       name: "hhh", age: 18 }
        }
      },
      methods: {
      
      
        changeMessage() {
      
      
          this.message = "你好啊, 李银河!"
          this.info = {
      
       name: "kobe" }
        }
      },
      watch: {
      
      
        // 1.默认有两个参数: newValue/oldValue
        message(newValue, oldValue) {
      
      
          console.log("message数据发生了变化:", newValue, oldValue)
        },
        info(newValue, oldValue) {
      
      
          // 2.如果是对象类型, 那么拿到的是代理对象 Proxy
          console.log("info数据发生了变化:", newValue, oldValue)
                  // Proxy(Object) {name: 'kobe'} 
                  // Proxy(Object) {name: 'hhh', age: 18}
          console.log(newValue.name, oldValue.name) //kobe hhh

          // 3.获取原生对象
          console.log({
      
       ...newValue })  //{name: 'kobe'}
          console.log(Vue.toRaw(newValue))  //{name: 'kobe'}
        }
      }
    })

    // 2.挂载app
    app.mount("#app")
  </script>
</body>

2.2_Configuration options for listener watch

one example:

  • When the button is clicked, the value of info.name will be modified;
  • At this time, use watch to listen to info, can you listen to it? The answer is no.

Because by default, watch is only listening to infocitation change, will not respond to changes in internal properties:

  • At this time, you can use an option deep for deeper listening;
  • Note that the listening property in the watch can also be an Object;

The immediate attribute will be executed immediately at the beginning:

  • Use the immediate option at this time;
  • At this time, regardless of whether there is any change in the subsequent data, the listening function will be executed once;
<body>

  <div id="app">
    <h2>{
   
   { info.name }}</h2>
    <button @click="changeInfo">修改info</button>
  </div>
  
  <script src="../lib/vue.js"></script>
  <script>
    // 1.创建app
    const app = Vue.createApp({
      
      
      // data: option api
      data() {
      
      
        return {
      
      
          info: {
      
       name: "hhh", age: 18 }
        }
      },
      methods: {
      
      
        changeInfo() {
      
      
          // 1.创建一个新对象, 赋值给info
          // this.info = { name: "kobe" }

          // 2.直接修改原对象某一个属性
          this.info.name = "kobe"
        }
      },
      watch: {
      
      
        // 默认watch监听不会进行深度监听
        // info(newValue, oldValue) {
      
      
        //   console.log("侦听到info改变:", newValue, oldValue)
        // }

        // 修改代码,进行深度监听
        info: {
      
      
          handler(newValue, oldValue) {
      
      
            console.log("侦听到info改变:", newValue, oldValue)
            console.log(newValue === oldValue)
          },
          // 监听器选项:
          // info进行深度监听
          deep: true,
          // 第一次渲染直接执行一次监听器
          immediate: true
        },
        "info.name": function(newValue, oldValue) {
      
      
          console.log("name发生改变:", newValue, oldValue)
        }
      }
    })

    // 2.挂载app
    app.mount("#app")
  </script>
</body>







































































Guess you like

Origin blog.csdn.net/qq_54075517/article/details/132148610