1.0.0-Alpha.2 • Published 4 years ago

v3-mini v1.0.0-Alpha.2

Weekly downloads
2
License
ISC
Repository
-
Last release
4 years ago

参考 Vue3.x ,尝试使用 composition-api 开发小程序

下载

npm install v3-mini --save

仓库地址

小程序npm使用

注意

  1. 参考 @vue/reactivity 开发小程序版 composition api ,使用 Proxy 而不用 Object.defineProperty 是因为解决属性添加删除上的问题,但小程序对的 Proxy 的适应性并不好
  2. 采用 westore 的 json diff 进行数据对比,减少了 setData 的内容

解决什么

  1. 使用 composition-api 开发,实现全局状态管理
  2. 添加了 reactive, ref, computed, watchEffect 方法
  3. 兼容原生小程序的写法,在原写法上新增写法
  4. 新的写法,data, methods 皆可在 setup 方法中一起定义返回
  5. 钩子函数也可直接在 setup 方法中直接定义

TODO

  1. 自定义组件的生命周期应该是按小程序原写法来还是与 Page 页面统一?
  2. setup的方法更新属于直接覆盖,是否需要对某些保护属性进行保护?
  3. setup返回的ref/reactive对象监听,采用异步setData的方式,数据改变后只执行一次setData,减少了setData方法的执行率
  4. 当页面中存在自定义组件时,是先执行自定义组件的setup后执行页面的setup

缺点

  1. Deps 依赖不同于 Vue3.x 存储于变量中,该版本存储于闭包中,通过js的机制不再引用时进行垃圾回收,使用不当容易造成内容泄露
  2. 采用 Proxy 才能实现 reactive 的数据监听(为了完成 属性添加删除上的问题),但小程序对 Proxy 的适应性并非很好
  3. setup返回的对象和方法,是在onLoad期间绑定在组件实例上的,依次不太适用于大量静态内容, 建议提前定义好data
  4. Provide / Inject 功能基础,有待提升

之后版本更新内容

  1. 内存回收机制完善(Deps、event)
  2. 自定义组件的 特殊的生命周期 暂未实现

setup

setup 函数是一个新的组件选项。作为在组件内使用 Composition API 的入口点。

  • 调用时机 在onLoad/attached时候被执行

  • 参数 该函数接收 props 作为其第一个参数, context 第二个参数

VPage({
    ... ,
    setup(props, context) {
        context.event.on('load', () => {});
        context.event.emit('load');
        context.setData({
            age: ref(16)
        })
    }
})
  1. props reactive对象,代理小程序原始 onLoad 的参数 options,可通过 toRefs 函数对其进行分解
  2. context作为上下文对象, 暴露了一些api
  3. event是事件通知模块, 包含常用的emit, on, once, off, context注册的事件, 在页面/组件被销毁时也会主动off
  4. setData是封装后的setData, 支持对reactive/ref对象的解析, 其他用法和原生一致
  5. this指向当前页面/组件实例

包装对象ref

ref

ref接受参数并将其包装在具有value属性的对象中,然后将其用于访问或更改反应变量的值

参数 1. val {Any} 任意值,赋值于ref.value

返回值 {Object} 返回代理后的ref对象

import { ref } from 'v3-mini'

const count = ref(0)
console.log(count.value) // 0

count.value = 1

console.log(count.value) // 1

在视图层中读取 当该值被setup返回, 将进入data值, 可在模板中被读取到, 会自动解套,无需在模板中额外书写.value

<view>{{ count }}</view>
<view bindtap="updateCount">+</view>
import { VPage, ref } from 'v3-mini'
VPage({
    setup(props, context) {
        const count = ref(0)
        return {
            count,
            updateCount() {
                count.value += 1
            }
        }
    }
})

拆解包装对象

toRefs

对 reactive 对象进行拆解,得到多个 ref 对象

参数 1. reactive {Reactive} reactive 对象

返回值 {Object} ref 对象集

import { VPage, reactive, toRefs } from 'v3-mini'
VPage({
    setup(props, context) {
        const person = reactive({ name: 'Jack', age: 25 })
        const { name, age } = toRefs(person)
        return {
            name, age,
            updatePerson() {
                name.value = 'Rose'
                person.age = 18
            }
        }
    }
})

包装对象reactive

reactive

参数 1. val {Object|Array} 创建该对象/数组的代理,监听数据变化

返回值 {Proxy} 返回代理后的reactive对象

将数据包装成一种可观测的类型,当数据产生变更的时候,监听并执行响应操作

import { reactive, watchEffect } from 'v3-mini'

const person = reactive({ name: 'Jack', age: 25 })
watchEffect(() => console.log(person.name)) // Jack
person.name = 'Rose' // Rose

reactive 对象中可使用 ref 对象

计算属性

computed

返回一个 不可手动修改的 ref 对象,收集监听当ref/reactive发送变化时随之更新值

参数 1. setter {Function} 监听变化的回调, 返回任意值

返回值 {Object} 返回计算后的ref对象

import { ref, computed } from 'v3-mini'

const count = ref(1)
const plusOne = computed(() => count.value + 1)

console.log(plusOne.value) // 2
count.value = 5
console.log(plusOne.value) // 6

计算属性总是最少会执行一次,为了第一次赋值

监听ref/reactive值更新

watchEffect 当被监听的ref/reactive对象变化时, 将触发

参数 1. callback 监听变化的回调

返回值 {Function} 返回停止监听的方法

import { ref, watchEffect } from 'v3-mini'

const count = ref(1)
const stop = watchEffect(() => console.log(`count: ${count.value}`)) // count: 1
count.value++ // count: 2
stop()
count.value++ // 无输出

watchEffect 总是最少会执行一次,为了收集依赖 注意:第一次执行 watchEffect 时并没有生成 stop ,在 callback 中使用 stop 会产生错误


生命周期函数

可以直接导入 onXXX 一族的函数来注册生命周期钩子:

import { VPage, onLoad, onHide, onShow } from 'v3-mini'

VPage({
  setup() {
    onLoad(() => {
      console.log('onLoad!')
    })
    onHide(() => {
      console.log('onHide!')
    })
    onShow(() => {
      console.log('onShow!')
    })
  },
}

VPage使用

<view>name: {{name}}</view>
<view>count1: {{count1}}</view>
<view>count2: {{count2}}</view>
<view>allCount.count1: {{allCount.count1}}</view>
<view>allCount.count2: {{allCount.count2}}</view>
<view>allCount.count3: {{allCount.count3}}</view>
<view bindtap="changeName">changeName</view>
<view bindtap="addCount1">addCount1</view>
<view bindtap="addCount3">addCount3</view>
<view bindtap="delCount3">delCount3</view>
<view bindtap="stopWatch">stopWatch</view>
import { VPage, ref, toRefs, reactive, watchEffect, computed, onLoad } from 'v3-mini';

VPage({
    setup(props) {
        let { name } = toRefs(props)
        let count1 = ref(1)
        let count2 = computed(() => count1.value * 2)
        let allCount = reactive({ count1, count2 })

        const stop = watchEffect(() => {
            console.log(`监听allCount.${'count2'}: ${allCount['count2']}`);
        })
        function changeName() {
            name.value = 'Rose'
        }
        function addCount1() {
            count1.value++
        }
        function addCount3() {
            allCount.count3 = (allCount.count3 || 0) + 3
        }
        function delCount3() {
            delete allCount.count3
        }
        function stopWatch() {
            console.log(`停止监听allCount.${'count2'}`);
            stop()
        }

        onLoad(() => {
            console.log('onLoad!')
        })
        return { name, count1, count2, allCount, changeName, addCount1, addCount3, delCount3, stopWatch }
    }
})

VComponent使用

<view>name: {{name}}</view>
<view bindtap="changeName">changeName</view>
<myView name="Jack" />
import { VComponent, toRefs, attached } from 'v3-mini';

VComponent({
    properties:{
        name: String
    },
    setup(props) {
        let { name } = toRefs(props)

        function changeName() {
            name.value = 'Rose'
        }

        attached(() => {
            console.log('attached!')
        })
        return { name, changeName }
    }
})
1.0.0-Alpha.2

4 years ago

1.0.0-Alpha.1

4 years ago

1.0.0-Alpha.0

4 years ago

0.0.5

4 years ago

0.0.4

4 years ago

0.0.3

4 years ago

0.0.2

4 years ago

0.0.1

4 years ago