npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@gowiny/vue-class

v1.1.5

Published

Vue 3 用类的形式编写组件,面向对象(OOP)编程,并提供了常用的装饰器,可以自定义装饰器

Downloads

82

Readme

goinwy-vue-class

说明

此项目是Vue3 的 TypeScript Class 支持项目,支持普通vue 3 项目和 uniapp + vue3 项目

用类的形式编写组件,面向对象(OOP)编程,并提供了常用的装饰器,还可以自定义装饰器

不依赖 vue-class-component项目 觉得它的实现方式,跟正常的Class 的用法不一致,所以直接重写了。

vue-class-component 的用法,如果子类也写有生命周期的hook,那实际是所有父类的hook 和 子类的 hook 都会执行一次。

此项目,子类重写父类方法后,如果不显式调用super.xxx 的话,是不会执行父类的hook 的。这跟正常的类的继承、重写保持一致

详细使用方法,可以查看演示项目

演示项目地址:https://gitee.com/gowiny/uni-example

安装教程

安装:

npm install @gowiny/vue-class

初始化

  • main.ts
import vueClass from '@gowiny/vue-class'
import { createSSRApp } from "vue";
import App from "./App.vue";

export function createApp() {
  const app = createSSRApp(App);

  //如果是 Vue Router 项目,则添加 Vue Router 独有的生命周期钩子

  app.use(vueClass,{
    hooks:['beforeRouteEnter','beforeRouteUpdate','beforeRouteLeave']
  })

  //如果是uniapp 项目,则添加uniapp独有的生命周期钩子
  /*
  app.use(vueClass,{
    hooks:['onInit','onLoad','onShow','onReady','onHide','onUnload','onResize','onPullDownRefresh','onReachBottom','onTabItemTap','onShareAppMessage','onPageScroll','onNavigationBarButtonTap',
  'onBackPress','onNavigationBarSearchInputChanged','onNavigationBarSearchInputConfirmed','onNavigationBarSearchInputClicked','onShareTimeline','onAddToFavorites']
  })
  */


  return {
    app,
  };
}

使用方法一:

单独使用 <script lang="ts"> 的情况

<template>
  <view class="container">
	<view>title:{{title}}></view>
	<view>name:{{name}}></view>
	<MyProfile></MyProfile>
	<view><button @click="test1">test1</button>
	<view><button @click="test2">test2</button>
  </view>
</template>
<script  lang="ts">
import { Action,Provide, getOptionsByClass, State,Vue } from '@gowiny/vue-class'
import MyProfile from '@/component/test/my-profile.vue'

@Options({
  components:{
    MyProfile
  }
})
class TestPage extends MyPage{
  title:string='用户信息'
  @State("user.userInfo")
  readonly userInfo!:any
  @Action("user/logout")
  logout!:()=>any

  @Provide("testInject")
  testInject11111(){
    uni.showModal({
      content:'我是 TestPage 提供的 testInject 方法'
    })
  }

  @Provide("provideValue")
  provideValue133333:string="TestPage provideValue"

  test1(){
  	console.log('test1')
  }

  test2(){
	  console.log('test2')
  }
}
export default TestPage
</script>

使用方法二:

<script lang="ts"><script setup lang="ts"> 两个标签共用的情况

<template>
  <view class="container">
	<view>title:{{title}}></view>
	<view>name:{{name}}></view>
	<MyProfile></MyProfile>
	<view><button @click="test1">test1</button>
	<view><button @click="test2">test2</button>
  </view>
</template>
<script setup lang="ts">
import MyProfile from '@/component/test/my-profile.vue'
import { ref } from 'vue'
const title = ref('用户信息')
function test1(){
  console.log('test1')
}
</script>

<script  lang="ts">
import { Action,Provide, getOptionsByClass, State,Vue } from '@gowiny/vue-class'
class TestPage extends MyPage{
  @State("user.userInfo")
  readonly userInfo!:any
  @Action("user/logout")
  logout!:()=>any

  @Provide("testInject")
  testInject11111(){
    uni.showModal({
      content:'我是 TestPage 提供的 testInject 方法'
    })
  }

  @Provide("provideValue")
  provideValue133333:string="TestPage provideValue"

  test2(){
	  console.log('test2')
  }
}
/*
这里展示的是<script lang="ts"> 和 <script setup lang="ts"> 两个标签共用的情况。
最后导出的时候,需要使用 getOptionsByClass 函数转换
*/
export default getOptionsByClass(TestPage)
</script>

可自定义装饰器

提供灵活的自定义装饰器的方法:createDecorator

具体使用方法,请参考源码中已有的装饰器的定义方式

createDecorator方法里的参数:ctx : OptionsContext 可以通过设置 ctx.dataFactoryctx.beforeHandlectx.afterHandle 来修改默认实现

支持的装饰器

@Options
@Prop
@State
@Action
@Mutation
@Getter
@Provide
@Inject
@Watch

@Prop

export default class App extends Vue {
	@Prop
	declare readonly title:string
}

等同于

export default defineComponent( {
  name: 'App',
  props:['title']
})

export default class App extends Vue {
	@Prop({
		default:'hello gowiny!'
	})
	declare readonly title:string
}

等同于

export default defineComponent( {
  name: 'App',
  props:{
	  title:{
		default:'hello gowiny!'
	}
  }
})

@State

export default class App extends Vue {
	@State
	declare readonly appName:string
}

等同于

export default defineComponent( {
  name: 'App',
  computed:{
  	appName(){
		this.$store.state.appName
  	}
  }
})

export default class App extends Vue {
	@State("app.version")
	declare readonly appVersion:string
}

等同于

export default defineComponent( {
  name: 'App',
  computed:{
  	appVersion(){
		this.$store.state.app.version
  	}
  }
})

@Action

export default class App extends Vue {
	@Action
	saveScreenSize!:(screenSize:any)=>Promise<any>
}

等同于

export default defineComponent( {
  name: 'App',
  methods:{
  	saveScreenSize(screenSize:any):Promise<any>{
		return this.$store.dispatch("saveScreenSize",screenSize)
  	}
  }
})

export default class App extends Vue {
	@Action("app/saveScreenSize")
	saveScreenSize!:(screenSize:any)=>Promise<any>
}

等同于

export default defineComponent( {
  name: 'App',
  methods:{
  	saveScreenSize(screenSize:any):Promise<any>{
		return this.$store.dispatch("app/saveScreenSize",screenSize)
  	}
  }
})

@Inject

export default class App extends Vue {
	@Inject
	getScreenSize!:()=>any
}

等同于

export default defineComponent( {
  name: 'App',
  inject: ['getScreenSize']
})

export default class App extends Vue {
	@Inject
	getScreenSize(){
		return {width:800,height:600}
	}
}

等同于

export default defineComponent( {
  name: 'App',
  inject: {'getScreenSize':{
	  default:function(){
		  return {width:800,height:600}
	  }
  }}
})

export default class App extends Vue {
	@Inject("screenWidth")
	width:number
}

等同于

export default defineComponent( {
  name: 'App',
  inject:{
  	width:{
		from:'screenWidth'
	}
  }
})

export default class App extends Vue {
	@Inject({from:'screenWidth',default:800})
	width!:number
}

等同于

export default defineComponent( {
	name: 'App',
	inject: {
		width:{
			from:'screenWidth',
			default:800
		}
	}
})

#其他装饰器的用法都类似,不再一一举例