总论
- tsx setup里面定义了return dom 元素,则options api的 render函数不生效
- options 的render函数生效前提是setup里面不能return dom
- options 的render里面可以直接使用this访问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>
</>
);
};
}
});
标签:return,tsx,render,vue3,几种,param1,props,console,log
From: https://www.cnblogs.com/jocongmin/p/18399378