前端工作也做了几年了,好多东西还是分不清楚。特别是对于最基础的书写格式还是有点模糊不清,今天特地整理一下,以供日后查阅。
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 组件实例创建之前执行,主要用于封装组件所需的逻辑,主要作用如下:
- 接收并处理组件的
props
,context
(包含attrs
、slots
、emit
)等数据。 - 允许在组件内部声明响应式数据、计算属性、侦听器等。
- 提供一个干净、独立的环境,使得组件内部的代码更容易维护和复用。
- 避免在组件生命周期钩子函数(如
beforeCreate
、created
等)中编写复杂逻辑,从而提高代码的可读性和可维护性。 - 提供了一种在 Vue3 组件中使用
ref
和reactive
等新特性方法的途径。
我们已经充分了解有哪些东西需要在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>
好,以上就是全部啦!