首页 > 其他分享 >Vuejs装饰器风格开发教程(计算属性、事件派发、侦听器)

Vuejs装饰器风格开发教程(计算属性、事件派发、侦听器)

时间:2023-08-17 12:01:40浏览次数:46  
标签:教程 Vue Vuejs Component 侦听器 vue oldValue import newValue

计算属性

计算属性的设计背景:在 Vuejs 开发时我们可以在模板中通过编写表达式的方式做一系列的逻辑处理,但这就偏离的模板的概念,还会使得模板的内容变得臃肿且难以维护,所以引入了计算属性的来对不该出现在模板中的复杂逻辑处理进行重构,使用计算属性重构后的依然保持了状态的响应式。

在类组件中,通过使用类属性的访问器方法(gettersetter)来描述计算属性的读写操作。在下面的代码中就是一个应用计算属性的典型场景。

基础示例

在计算属性的 getter 中应该仅做计算而不包含任何其他的副作用,应该严厉禁止在 getter 中做异步请求或改变 DOMgetter 的触发会使得数据的变化,数据的变化会驱动 DOM 的变化,这是一个正向的流程,强行对 DOM 进行修改会导致数据与 DOM 不同步,也会造成性能问题(getter 会频繁触发)。

<script lang="ts">
  import { Component, Vue } from 'vue-facing-decorator';

  @Component
  export default class App extends Vue {
    
    firstName = '';
    lastName = '';

    // 计算属性(标记为 get 访问器):对 firstname 和 lastname 进行合并
    get fullName() {
      return this.firstName + '/' + this.lastName;
    }
    
  }
</script>

<template>
  <div>
    <p>firstName:<input v-model="firstName" /></p>
    <p>lastName:<input v-model="lastName" /></p>
    <p>fullName:{{ fullName }}</p>
  </div>
</template>

可写的计算属性

下面的代码是改造后的支持可写的计算属性的场景,在 fullName 发生变化后会重写对 firstNamelastName 进行赋值。

<script lang="ts">
  import { Component, Vue } from 'vue-facing-decorator';

  @Component
  export default class App extends Vue {
    
    firstName = '';
    lastName = '';
    
    get fullName() {
      return this.firstName + '/' + this.lastName;
    }
    
    set fullName(newValue) {
      [this.firstName, this.lastName] = newValue.split('/');
    }
  }
</script>

<template>
  <div>
    <p>firstName:<input v-model="firstName" /></p>
    <p>lastName:<input v-model="lastName" /></p>
    <p>fullName:<input v-model="fullName" /></p>
  </div>
</template>

原生访问器

在类组件中如果要使用原生的 gettersetter 时需要用 vfd 提供得 @Vanilla装饰器。

事件派发

$emitVuejs 组件开发中是使用频率较高一个 API,往往会使用 $emit 将子组件运行后的结果通知到父组件去执行后续的一些操作。在类组件中同样需要一个新的装饰器支持:@Emit

基础示例

在下面这个 Form 组件中,我们仅让它来负责数据的收集,在触发登陆按钮后会通过事件派发将 username 和 password 数据发送至它的父组件。

<script lang="ts">
  import { Component, Emit, Vue } from 'vue-facing-decorator';

  @Component({
    name: 'Form',
  })
  export default class From extends Vue {
    username = 'admin';
    password = '123456';

    @Emit('login')
    login() {
      return {
        username: this.username,
        password: this.password,
      }
    }
  }
</script>

<template>
  <p>username: <input v-model="username"></p>
  <p>password: <input v-model="password"></p>
  <p><button @click="login">登陆</button></p>
</template>
<script lang="ts">
  import Form from './components/Form.vue';
  import { Component, Vue } from 'vue-facing-decorator';

  @Component({
    components: {
      Form,
    },
  })
  export default class App extends Vue {
    toLogin(value: any) {
      console.log(`以获取登陆数据,${value.username}/${value.password},可以执行登录请求~`);
    }
  }
</script>

<template>
  <div>
    <Form @login="toLogin"></Form>
  </div>
</template>

^注: @Emit 的参数即事件派发的名称,如果装饰器所描述的方法名称和派发事件的名称一致,则可以省略装饰器内的参数。

异步事件

将上面的案例进行改造,Form 组件中的 login 方法负责请求服务器进行实际的登陆处理,将登陆的结果进行派发,在其父组件接收登录的结果。

<script lang="ts">
  import { Component, Emit, Vue } from 'vue-facing-decorator';

  @Component({
    name: 'Form',
  })
  export default class From extends Vue {
    username = 'admin';
    password = '123456';

    @Emit('login')
    login() {
      return new Promise((resolve) => {
        setTimeout(() => {
            resolve('登陆成功~')
        }, 1000)
      })
    }
  }
</script>

<template>
  <p>username: <input v-model="username"></p>
  <p>password: <input v-model="password"></p>
  <p><button @click="login">登陆</button></p>
</template>
<script lang="ts">
  import Form from './components/Form.vue';
  import { Component, Vue } from 'vue-facing-decorator';

  @Component({
    components: {
      Form,
    },
  })
  export default class App extends Vue {
    toLogin(value: any) {
      console.log(`登陆结果:${value}`);
    }
  }
</script>

<template>
  <div>
    <Form @login="toLogin"></Form>
  </div>
</template>

侦听器

在类组件中提供装饰器 @Watch 对需要侦听的类属性进行描述,@Watch 的参数 1 是被侦听的属性名,参数 2 是一个可选的选项列表,分别是deepflushimmediate

<script lang="ts">
  import { Component, Watch, Vue } from 'vue-facing-decorator';

  @Component
  export default class App extends Vue {
    userName = 'admin';
    passWord = '123456';

    @Watch('userName')
    userNameWatcher(newValue: string, oldValue: string) {
      console.table([
        { '': 'userName', newValue: newValue, oldValue: oldValue },
      ]);
    }

    @Watch('passWord')
    passWordWatcher(newValue: string, oldValue: string) {
      console.table([
        { '': 'passWord', newValue: newValue, oldValue: oldValue },
      ]);
    }
  }
</script>

<template>
  <div>
    <p>UserName:<input v-model="userName" /></p>
    <p>PassWord:<input v-model="passWord" /></p>
  </div>
</template>

深度监听

在面对普通的类属性时可以不指定任何的可选选项,但是对于对象类型的类属性来说,就必须用到 deep 选项了,作用同 vue option api。

<script lang="ts">
  import { Component, Watch, Vue } from 'vue-facing-decorator';

  @Component
  export default class App extends Vue {
    login = {
      userName: 'admin',
      passWord: '123456',
    };

    @Watch('login', {
      deep: true,
    })
    userNameWatcher(newValue: any, oldValue: any) {
      console.log(newValue, oldValue);
    }
  }
</script>

<template>
  <div>
    <p>UserName:<input v-model="login.userName" /></p>
    <p>PassWord:<input v-model="login.passWord" /></p>
  </div>
</template>

回调触发时机

当响应式的状态发生改变后,除了会触发侦听器以外还会触发 Vuejs 组件更新,也就是会触发 beforeUpdateupdated 生命周期。默认情况下执行的先后顺序是:Watcher => beforeUpdate => updated,但是如果需要再 Watcher 中对更新前的 DOM 进行访问和操作时,就需要指定 flush 选项值为 post,这时的执行先后顺序就变更为:beforeUpdate => Watcher => updated

<script lang="ts">
  import { Component, Watch, Vue } from 'vue-facing-decorator';

  @Component
  export default class App extends Vue {
    
    userName = 'admin';

    @Watch('userName', {
      flush: 'post'
    })
    userNameWatcher(newValue: any, oldValue: any) {
      console.log(newValue, oldValue);
    }

    beforeUpdate() {
      console.log('beforeUpdate')
    }
    
    updated() {
      console.log('updated')
    }
  }
</script>

<template>
  <div>
    <p>UserName:<input id="username" v-model="userName" /></p>
  </div>
</template>

立即执行的侦听器

侦听器默认情况下仅在响应状态发生变化时才会触发回调,但某些场景下会需要在侦听器被创建后就立即执行一次,比如说根据默认的响应状态要做一遍数据的筛选等等。

@Watch('userName', {
  immediate: true,
})
userNameWatcher(newValue: any, oldValue: any) {
  console.log(newValue, oldValue);
}

标签:教程,Vue,Vuejs,Component,侦听器,vue,oldValue,import,newValue
From: https://blog.51cto.com/u_11711012/7120590

相关文章

  • python rasa聊天机器人教程三:基于WebSocket的简单网页组件配置
    1.准备环境新建一个目录,并且在命令行中进入该目录初始化一个Rasa项目,使用以下命令:rasainit2.修改Rasa的配置在Rasa项目目录中,找到credentials.yml文件,添加以下内容:socketio:user_message_evt:user_utteredbot_message_evt:bot_utteredsession_persistenc......
  • 无涯教程-Perl - sub函数
    描述此函数定义一个新的子例程。上面显示的参数遵循以下规则-NAME是子例程的名称。可以在有或没有原型规范的情况下预先声明命名的子例程(没有关联的代码块)。匿名子例程必须具有定义。PROTO定义了函数的原型,调用该函数以验证提供的参数时将使用该原型。ATTRS为......
  • 【Nest教程】连接MySQL数据库 -----转
      来自:https://cloud.tencent.com/developer/article/1774827本人测试这文章确实成功了,建议看上面链接的原文            对于一个WebAPI项目,数据库是必不可少的,Nest与数据库无关,允许您轻松地与任何SQL或NoSQL数据库集成。根据您的偏好,您有......
  • 无涯教程-Perl - study函数
    描述此功能需要花费额外的时间来研究EXPR,以改善在EXPR上执行的正则表达式的性能。如果省略EXPR,则使用$_。实际的速度增益可能非常小,具体取决于您希望搜索字符串的次数。您一次只能学习一种表达式或标量。语法以下是此函数的简单语法-studyEXPRstudy返回值此函数不......
  • 无涯教程-Perl - sprintf函数
    描述此函数使用FORMAT基于LIST中的值返回格式化的字符串。本质上与printf相同,但是返回格式化的字符串而不是将其打印。语法以下是此函数的简单语法-sprintfFORMAT,LIST返回值此函数返回SCALAR(格式化的文本字符串)。例以下是显示其基本用法的示例代码-#!/usr/bin/......
  • 一个十分简单的增删改查系统(含MYSQL数据库安装教程)
    一个十分简单的增删改查系统(nodejs+vue)该系统采用前后端分离的方式,实现最基本的增、删、改、查功能。前端使用vue框架搭建,后端使用nodejs,数据库用mysql1.准备工作1.1安装nodejs下载nodejs,官网如下Node.js(nodejs.org)选择长期维护版,下载之后直接下一步下一步就行了......
  • 0基础微信小程序搭建教程之禾匠商城源码搭建教程
    2022年版禾匠商城V4搭建教程(重新更新一份禾匠商城V4独立版搭建教程,因为之前的版本搭建跟现在有点不一样,现在一键安装比之前简单多了,废话不多现在开始!)准备工作:1、服务器一个,要好2核4G,安装系统CentOS7.5和宝塔面板。2、Nginx1.20,插件:PHP72、数据库5.6、Redis6.2.6,其它......
  • mysql 5.6 升级到 5.7 教程
    一、下载mysql5.7包  链接:https://pan.baidu.com/s/1ZBA1P6Yxq1clWS1ZZ9YzMw?pwd=yknx提取码:yknx 将下载文件解压后创建mysql.ini,并放入以下内容[mysqld]event_scheduler=onport=3306basedir=D:\mysql\XXXdatadir=D:\mysql\XXX\datamax_connection......
  • t visual develop STM8 软件配置教程
    打开STVD软件,点击Debuginstrument→targatsetting,Target选择SwimST-Link,将Restarttheapplication…勾选上,TargetPortSelection选择usb://usb,将Showtheselected…勾选上,点击应用然后关闭。第二步点击Tools,选择options,Directories,Toolbars,将前三项、第5678项勾选,,Too......
  • 无涯教程-Perl - socketpair函数
    描述此函数使用PROTOCOL在指定的DOMAIN(指定的TYPE)中创建一对未命名的连接Socket。如果未实现系统socketpair()函数,则将导致致命错误。语法以下是此函数的简单语法-socketpairSOCKET1,SOCKET2,DOMAIN,TYPE,PROTOCOL返回值如果失败,此函数返回0,如果成功,则返回1。......