vue2、vue3傻傻分不清楚

前端工作也做了几年了,好多东西还是分不清楚。特别是对于最基础的书写格式还是有点模糊不清,今天特地整理一下,以供日后查阅。

vue2

//最纯洁简单的一种创建组件的方式,使用基础 Vue 构造器,创建一个“子类”。
<script>
import Vue from 'vue';
import HelloWorld from '@/components/HelloWorld.vue'; // @ is an alias to /src

export default Vue.extend({
  name: 'HomeView',
  components: {
    HelloWorld,
  },
  data(){
    return {
      name:'张三',
    }
  },
  computed:{
    newName(){
      return this.name+'哈哈'
    }
  },
  watch: {
    //……
  },
  methods:{
    eventClick(){
      this.name = '李磊'
    },
    //……
  }
});
</script>

其中,由于
在这里插入图片描述
所以我们也可以直接省略掉Vue.extend,直接使用export default({……})声明模块。

vue+ts

vue2.x 对 TS 的支持并不友好,所以 vue2.x 跟 TS的整合,通常需要基于vue-class-component(官方推荐的)来用基于 class(类) 的组件书写方式。
这种编写方式可以让.vue 文件的 js 域结构更扁平,并使 vue 组件可以使用继承、混入等高级特性。

使用vue-class-component带来了很多便利:

methods 钩子都可以直接写作 class 的方法

  • computed 属性可以直接通过 get 来获得
  • 初始化 data 可以声明为class 的属性
  • 其他的都可以放到 Component 装饰器里
//注意!:多了lang="ts",用来声明使用了ts语法
<script lang="ts">
import Vue from 'vue'
import Component from 'vue-class-component'
 
 // 4.其他的都可以放到 Component 装饰器里
@Component({
  template: '<button @click="onClick">Click!</button>',
  components: {
    Component 
  },
  props: {
    propMessage: String
  },
  ……
})
// 1.methods 钩子都可以直接写作 class 的方法
export default class App extends Vue { //注意!:extends Vue是用来声明类的类型,遵从ts语法

  // 2.初始化 data 可以声明为class 的属性 
  msg = 123
  
  // 3.computed 属性可以直接通过 get 来获得
  get computedMsg () {
    return 'computed ' + this.msg
  }
 
  // method
  greet () {
    alert('greeting: ' + this.msg)
  }
}
</script>

vue-property-decorator

是基于vue-class-component扩展的一个非官方库, 主要功能就和名字一样,为vue的属性提供装饰器写法,让代码更加美观、直白。推荐使用,这个文档比较推荐可以直接链接过去学习。

vue-class

顺便说一下vuex-class是vuex和vue-class-component的绑定助手,包装了vuex, 简化了代码。在我的项目中也经常被使用到。举个例子

//cate.ts,一个模块
import {Commit,ActionContext} from 'vuex';
//ts类型定义
interface State {
    clueId: number;
    refreshTime: number
};
const state: State = {
    clueId: 0,
    refreshTime: new Date().getTime()
};
const mutations = {
    UPDATE(state: State,clueId: number) {
        state.clueId = clueId;
        state.refreshTime = new Date().getTime()
     }
};
const actions = {
    update(context: ActionContext<State, any> , clueId: number) {
        context.commit('UPDATE' , clueId);
    }
};

const getters = {
    refreshTime() {
        return state.refreshTime
    }
}
export default {
    namespaced: true,
    state,
    mutations,
    actions,
    getters
};
//index.ts
import Vue from 'vue'
import Vuex from 'vuex'

import Cate from './modules/Cate'

const modulesFiles = require.context("./modules", true, /\.ts$/);
//注意!:通过reduce方法循环,将每个js中export default出的对象放在modules中并return,最后将modules丢到Vuex.Strore中。
const modules = modulesFiles.keys().reduce((modules: any, modulePath) => {
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, "$1");
  const value = modulesFiles(modulePath);
  modules[moduleName] = value.default;
  return modules;
}, {});

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    Cate,
    ……
  },
  strict: process.env.NODE_ENV !== 'production'
})
//装饰器:@State @Getter @Action @Mutation
import Vue from 'vue'
import Component from 'vue-class-component'
import {
  State,
  Getter,
  Action,
  Mutation,
  namespace
} from 'vuex-class'

const someModule = namespace('path/to/module')

@Component
export class MyComponent extends Vue {
  @State('foo') stateFoo
  @State(state => state.bar) stateBar
  @Getter('foo') getterFoo
  @Action('foo') actionFoo
  @Mutation('foo') mutationFoo
  @someModule.Getter('foo') moduleGetterFoo

  // 如果省略参数, 直接使用每一个 state/getter/action/mutation 类型的属性名称
  @State foo
  @Getter bar
  @Action baz
  @Mutation qux

  created () {
    this.stateFoo // -> store.state.foo
    this.stateBar // -> store.state.bar
    this.getterFoo // -> store.getters.foo
    this.actionFoo({ value: true }) // -> store.dispatch('foo', { value: true })
    this.mutationFoo({ value: true }) // -> store.commit('foo', { value: true })
    this.moduleGetterFoo // -> store.getters['path/to/module/foo']
  }
}

vue3

  • 选项式api:保持vue的传统写法

使用选项式 API,我们可以用包含多个选项的对象来描述组件的逻辑,例如 data、methods 和
mounted。选项所定义的属性都会暴露在函数内部的 this 上,它会指向当前的组件实例。

  • 组合式api

通过组合式 API,我们可以使用导入的 API 函数来描述组件逻辑。在单文件组件中,组合式 API 通常会与 <script setup>搭配使用。这个 setup attribute 是一个标识,告诉 Vue 需要在编译时进行一些处理,让我们可以更简洁地使用组合式 API。比如,<script setup> 中的导入和顶层变量/函数都能够在模板中直接使用。

setup

//setup语法糖
<script setup>
import { ref, onMounted } from 'vue'

// 响应式状态
const count = ref(0)

// 用来修改状态、触发更新的函数
function increment() {
  count.value++
}

// 生命周期钩子
onMounted(() => {
  console.log(`The initial count is ${count.value}.`)
})
</script>

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>

setup 函数是一个新引入的组件选项,它在 Vue3 组件实例创建之前执行,主要用于封装组件所需的逻辑,主要作用如下:

  1. 接收并处理组件的 propscontext(包含 attrsslotsemit)等数据。
  2. 允许在组件内部声明响应式数据、计算属性、侦听器等。
  3. 提供一个干净、独立的环境,使得组件内部的代码更容易维护和复用。
  4. 避免在组件生命周期钩子函数(如 beforeCreatecreated 等)中编写复杂逻辑,从而提高代码的可读性和可维护性。
  5. 提供了一种在 Vue3 组件中使用 refreactive 等新特性方法的途径。

我们已经充分了解有哪些东西需要在setup中去生命,我们就可以对以上的代码进行进步的优化,这是我在项目中常会用到的一种写法。

//注意!:没有setup
<script>
//一部分代码可以抽离开来
import { ref, onMounted ,defineComponent} from 'vue'
export default defineComponent({
  name: "ManageBaseInfo",
  components: { MgFileView , MgComplexView},
});
</script>

<script setup>
const count = ref(0)
……
</script>

好,以上就是全部啦!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值