joken-前端工程师

  :: 首页 :: 博问 :: 闪存 :: 新随笔 :: :: :: 管理 ::

总论

  • tsx setup里面定义了return dom 元素,则options api的 render函数不生效
  • options 的render函数生效前提是setup里面不能return dom
  • options 的render里面不能使用this,只能使用ctx,且setup得返回数据,ctx才能访问到相应数据
  • tsx一般最好用defineComponent包裹,这样响应式才能生效
  • tsx dom语法 使用{} 渲染变量, 使用onClick等直接触发事件,.value 访问ref数据
  • tsx 放在setup return 则需要返回的是一个函数,函数里面放tsx

代码测试

  • 父组件
<template>
    <div class="component-name">
        <child :render="render" :params1="abc" />
    </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted, nextTick } from 'vue';
import child from './components/child';
import { ElInput } from 'element-plus';
const abc = ref('sdlfkjsdfj');
const render = (h) => {
    const text = ref('');
    return h('input', {
        type: 'text',
        modelValue: text.value, // 使用modelValue 而不是value传递输入框的值
        onInput: (e) => {
            text.value = e.target.value; // 更新 text.value
        }
    });
};

setTimeout(() => {
    abc.value = '中文';
}, 3000);
</script>

<style lang="scss" scoped></style>

  • 子组件使用方式1
import { defineComponent, PropType, h, computed } from 'vue';
export default defineComponent({
    name: 'PageF',
    props: {
        render: Function as PropType<(...args: any) => any>,
        params1: String as PropType<string>
    },
    setup(props) {
        const { render } = props;

        const param1 = computed(() => props.params1);

        console.log(param1.value, 'param1');

        return () => {
            return render && render(h);
        };
    }
});
  • 子组件使用方式2
import { defineComponent, PropType, h, computed } from 'vue';
export default defineComponent({
    name: 'PageF',
    props: {
        render: Function as PropType<(...args: any) => any>,
        params1: String as PropType<string>
    },
    setup(props) {
        const { render } = props;

        const param0 = computed(() => props.params1); //这样可以监听到props.params1 外面数据的变化
        const param1 = ref(props.params1); //这样是内部单独建立一份ref,props外部改变,不影响该数据

        console.log(param1, 'param1');

        //不能监听到
        watch(param1, () => {
            console.log(param1.value, 'param1_change');
        });

        //可以监听到
        watch(param0, () => {
            console.log(param0.value, 'param0_change');
        });

        return () => {
            return render && render(h);
        };
    }
});

  • 使用方式3
import { defineComponent, PropType, h, computed } from 'vue';
export default defineComponent({
    name: 'PageF',
    props: {
        render: Function as PropType<(...args: any) => any>,
        params1: String as PropType<string>
    },
    setup(props) {
        const { render } = props;

        const param0 = computed(() => props.params1); //这样可以监听到props.params1 外面数据的变化
        const param1 = ref(props.params1); //这样是内部单独建立一份ref,props外部改变,不影响该数据

        console.log(param1, 'param1');

        //不能监听到
        watch(param1, () => {
            console.log(param1.value, 'param1_change');
        });

        //可以监听到
        watch(param0, () => {
            console.log(param0.value, 'param0_change');
        });
        // return (<div>slkfsjfdksd</div>) 这样不能渲染dom,需要返回函数,函数里面再放dom
        return () => <div>sdlfkjsfkjsd</div>;
    }
});
  • 使用方式4
import { defineComponent, PropType, h, computed } from 'vue';
export default defineComponent({
    name: 'PageF',
    props: {
        render: Function as PropType<(...args: any) => any>,
        params1: String as PropType<string>
    },
    setup(props) {
        const { render } = props;

        const param0 = computed(() => props.params1); //这样可以监听到props.params1 外面数据的变化
        const param1 = ref(props.params1); //这样是内部单独建立一份ref,props外部改变,不影响该数据

        console.log(param1, 'param1');

        //不能监听到
        watch(param1, () => {
            console.log(param1.value, 'param1_change');
        });

        //可以监听到
        watch(param0, () => {
            console.log(param0.value, 'param0_change');
        });
        // return (<div>slkfsjfdksd</div>) 这样不能渲染dom,需要返回函数,函数里面再放dom
        // return () => <div>sdlfkjsfkjsd</div>;
    },
    //这个render函数能够运行的前提是 setup里面不返回return dom
    render: (ctx, no, props) => {
        console.log(ctx, 'ctx');
        console.log(no, 'nonsdjflsjdf');
        console.log(props, 'props');
        // return <div>23424342</div>;

        return h('div', {}, 'sdlkfjsldfjsldfjsl');
    }
});
  • 使用方式4
import { defineComponent, PropType, h, computed } from 'vue';
export default {
    name: 'PageF',
    props: {
        render: Function as PropType<(...args: any) => any>,
        params1: String as PropType<string>
    },
    setup(props) {
        const { render } = props;

        const param0 = computed(() => props.params1); //这样可以监听到props.params1 外面数据的变化
        const param1 = ref(props.params1); //这样是内部单独建立一份ref,props外部改变,不影响该数据

        console.log(param1, 'param1');

        //不能监听到
        watch(param1, () => {
            console.log(param1.value, 'param1_change');
        });

        //可以监听到
        watch(param0, () => {
            console.log(param0.value, 'param0_change');
        });
        // return (<div>slkfsjfdksd</div>) 这样不能渲染dom,需要返回函数,函数里面再放dom
        // return () => <div>sdlfkjsfkjsd</div>;
    },
    //这个render函数能够运行的前提是 setup里面不返回return dom
    render: (ctx, no, props) => {
        console.log(ctx, 'ctx');
        console.log(no, 'nonsdjflsjdf');
        console.log(props, 'props');
        // return <div>23424342</div>;

        return h('div', {}, 'sdlkfjsldfjsldfjsl');
    }
};
  • 直接函数
import { defineComponent, PropType, h, computed } from 'vue';

// 不建议这样使用,测试发现.value 无法响应式,最好还是defineComponent 里面使用
export default (props) => {
    console.log(props, 'sldjfslfkjsldfjslf');

    const count = ref(232342342);

    function handleClick() {
        console.log('slfjsf');
        count.value = 475945795;
    }

    return (
        <>
            {/* 响应式无效 */}
            <div>{count.value}</div>
            <button onClick={handleClick}>btn</button>
        </>
    );
};

  • 使用方式n
import { defineComponent, PropType, h, computed } from 'vue';
export default defineComponent({
    setup: (props) => {
        console.log(props, 'sldjfslfkjsldfjslf');

        const count = ref(232342342);

        function handleClick() {
            console.log('slfjsf');
            count.value = 475945795;
        }

        return () => {
            return (
                <>
                    <div>{count.value}</div>
                    <button onClick={handleClick}>btn</button>
                </>
            );
        };
    }
});

  • this是否访问的到?
import { defineComponent, PropType, h, computed } from 'vue';
export default defineComponent({
    setup: (props) => {
        console.log(props, 'sldjfslfkjsldfjslf');

        const count = ref(232342342);

        function handleClick() {
            console.log('slfjsf');
            count.value = 475945795;
        }
        // 需要renturn ,render函数 ctx才能有 相应数据
        return {
            handleClick,
            count
        };
    },
    render: (ctx) => {
        console.log(this, 'sklfjslfjs'); //this 直接访问不了

        console.log(ctx, 'ctx_sdlfjsdlfksj');
        return <div>{ctx.count}</div>;
    }
});

  • defineComponent 定义Props ts类型的方式
import { defineComponent, PropType, h, computed } from 'vue';

// defineComponent 定义props类型的一种方式
interface Props {
    render: (...args: any[]) => any;
    params1: string;
}
export default defineComponent<Props>({
    name: 'PageF',
    setup(props) {
        const { render } = props;

        const param0 = computed(() => props.params1); //这样可以监听到props.params1 外面数据的变化
        const param1 = ref(props.params1); //这样是内部单独建立一份ref,props外部改变,不影响该数据

        console.log(param1, 'param1');

        //不能监听到
        watch(param1, () => {
            console.log(param1.value, 'param1_change');
        });

        //可以监听到
        watch(param0, () => {
            console.log(param0.value, 'param0_change');
        });

        return () => {
            return render && render(h);
        };
    }
});

  • 定义props ts类型方式2,必须与否实现
import { defineComponent, PropType, h, computed, ref, watch } from 'vue';

export default defineComponent({
    name: 'PageF',
    props: {
        render: {
            type: Function as PropType<(...args: any[]) => any>,
            required: true // required定义必须
        },
        params1: {
            type: String as PropType<string>,
            default: 'default value', // 设置默认值
            required: true
        }
    },
    setup(props) {
        const { render } = props;

        const param0 = computed(() => props.params1); // 监听 props.params1 的变化
        const param1 = ref(props.params1); // 内部独立的 ref

        console.log(param1, 'param1');

        // 监听 param1 的变化
        watch(param1, () => {
            console.log(param1.value, 'param1_change');
        });

        // 监听 param0 的变化
        watch(param0, () => {
            console.log(param0.value, 'param0_change');
        });

        return () => {
            return render && render(h);
        };
    }
});
posted on 2024-09-05 23:19  joken1310  阅读(102)  评论(0编辑  收藏  举报