computed
1. vue2写法
computed: {
rulerName: {
get(): string {
return this.name
},
set(value: string) {
this.$emit("update:name", value)
}
}
}
2. vue3写法
接受一个 getter 函数,并根据 getter 的返回值返回一个不可变的响应式 ref 对象。
const count = ref<number>(1)
const plusOne = computed(():number => count.value + 1)
console.log(plusOne.value) // 2
plusOne.value++ // 错误
或者,接受一个具有 get 和 set 函数的对象,用来创建可写的 ref 对象。
const count = ref<number>(1)
const plusOne = computed({
get: ():number => count.value + 1,
set: val:number => {
count.value = val - 1
}
})
plusOne.value = 1
console.log(count.value) // 0
3.使用场景一(处理style)
<script lang="tsx">
import type { CSSProperties, PropType } from "vue";
import { defineComponent, computed, unref } from "vue";
import { Tooltip } from "ant-design-vue";
import { InfoCircleOutlined } from "@ant-design/icons-vue";
import { getPopupContainer } from "/@/utils";
import { isString, isArray } from "/@/utils/is";
import { get } from "/@/utils/helper/tsxHelper";
import { propTypes } from "/@/utils/propTypes";
import { useDesign } from "/@/hooks/web/useDesign";
export default defineComponent({
name: "BasicHelp",
components: { Tooltip },
props: {
// max-width
maxWidth: propTypes.string.def("600px"),
// Whether to display the serial number
showIndex: propTypes.bool,
// color
color: propTypes.string.def("#ffffff"),
fontSize: propTypes.string.def("14px"),
placement: propTypes.string.def("right"),
absolute: propTypes.bool,
// Text list
text: {
type: [Array, String] as PropType<string[] | string>,
},
// 定位
position: {
type: [Object] as PropType<any>,
default: () => ({
position: "absolute",
left: 0,
bottom: 0,
}),
},
},
setup(props, { slots }) {
const { prefixCls } = useDesign("basic-help");
const getOverlayStyle = computed(
(): CSSProperties => {
return {
maxWidth: props.maxWidth,
};
}
);
const getWrapStyle = computed(
(): CSSProperties => {
return {
color: props.color,
fontSize: props.fontSize,
};
}
);
const getMainStyleRef = computed(() => {
return props.absolute ? props.position : {};
});
const renderTitle = () => {
const list = props.text;
if (isString(list)) {
return <p>{list}</p>;
}
if (isArray(list)) {
return list.map((item, index) => {
return (
<p key={item}>
<>
{props.showIndex ? `${index + 1}. ` : ""}
{item}
</>
</p>
);
});
}
return null;
};
return () => {
return (
<Tooltip/>
);
};
},
});
</script>
4.使用场景二(处理props)
<template>
<span :class="getClass"><Icon icon="ion:chevron-forward" :style="$attrs.iconStyle"></Icon></span></template>
<script lang="ts">
import { defineComponent, computed } from "vue";
import { useDesign } from "/@/hooks/web/useDesign";
import { propTypes } from "/@/utils/propTypes";
import { Icon } from "/@/components/Icon";
export default defineComponent({
name: "BasicArrow",
components: { Icon },
props: {
expand: propTypes.bool,
top: propTypes.bool,
bottom: propTypes.bool,
inset: propTypes.bool,
},
setup(props) {
const { prefixCls } = useDesign("basic-arrow");
const getClass = computed(() => {
const { expand, top, bottom, inset } = props;
return [
prefixCls,
{
[`${prefixCls}--active`]: expand,
top,
inset,
bottom,
},
];
});
return {
getClass,
};
},
});
</script>
5.使用场景三(组件v-model)
<template>
<div class="create-rule">
<div class="top">
<a-form-item label="名称">
<a-input
v-model:value="rulerName"
allowClear
class="mr-4"
:style="{ width: isAdd ? 'calc(100% - 150px)' : 'calc(100% - 220px)'}"
/>
<a-checkbox v-model:checked="isSuit"></a-checkbox>
<a-button v-if="!isAdd" type="primary" @click="reset"></a-button>
</a-form-item>
</div>
<slot name="prerequisites"></slot>
<slot name="condition-meet"></slot>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
props: {
name: { type: String, default: '' },
checked: { type: Boolean, default: true },
isAdd: { type: Boolean, default: true }
},
emits: ["update:checked", "update:name", 'reset'],
computed: {
rulerName: {
get(): string {
return this.name
},
set(value: string) {
this.$emit("update:name", value)
}
},
isSuit: {
get(): boolean {
return this.checked
},
set(value: boolean) {
this.$emit("update:checked", value)
}
}
},
methods: {
reset() {
this.$emit('reset')
}
}
})
</script>