06丨Vue组件的核心概念(1):属性
05.Vue组件的核心概念(1):属性
代码地址:
不同的组件就是Options的不同,
三大核心概念
尽可能的罗列了平时可能会用到的属性的写法。
第一种属性的写法,平时开发的时候不推荐这么做,对系统后期的维护是不利的。
推荐使用的方式:通过对象的形式把属性,给一个类型声明、自定义校验,还有一些默认值。
这是自定义的校验,type通过自定义校验,达到一个枚举类型的的校验。
list是一个数组,默认是一个空的数组
isVisible默认是false ,如果你不写默认值的,vue也会帮你处理的
onChange这里是一个函数:不建议你起名叫做onChange,因为我们后续在讲到Jsx的时候,onChange会和里面的功能点会有一些冲突。
<template> <div> name: {{ name }} <br /> type: {{ type }} <br /> list: {{ list }} <br /> isVisible: {{ isVisible }} <br /> <button @click="handleClick">change type</button> </div> </template> <script> export default { name: "PropsDemo", // inheritAttrs: false, // props: ['name', 'type', 'list', 'isVisible'], props: { name: String, type: { validator: function(value) { // 这个值必须匹配下列字符串中的一个 return ["success", "warning", "danger"].includes(value); } }, list: { type: Array, // 对象或数组默认值必须从一个工厂函数获取 default: () => [] }, isVisible: { type: Boolean, default: false }, onChange: { type: Function, default: () => {} } }, methods: { handleClick() { // 不要这么做、不要这么做、不要这么做 // this.type = "warning"; // 可以,还可以更好 this.onChange(this.type === "success" ? "warning" : "success"); } } }; </script>
使用这个组件
把要传递的属性罗列在这里
<template> <div> <a-tabs> <a-tab-pane key="props" tab="属性"> <Props name="Hello Vue!" :type="type" :is-visible="false" :on-change="handlePropChange" title="属性Demo" class="test1" :class="['test2']" :style="{ marginTop: '20px' }" style="margin-top: 10px" /> </a-tab-pane> <a-tab-pane key="event" tab="事件"> <Event :name="name" @change="handleEventChange" /> </a-tab-pane> <a-tab-pane key="slot" tab="插槽"> <h2>2.6 新语法</h2> <SlotDemo> <p>default slot</p> <template v-slot:title> <p>title slot1</p> <p>title slot2</p> </template> <template v-slot:item="props"> <p>item slot-scope {{ props }}</p> </template> </SlotDemo> <br /> <h2>老语法</h2> <SlotDemo> <p>default slot</p> <p slot="title">title slot1</p> <p slot="title">title slot2</p> <p slot="item" slot-scope="props">item slot-scope {{ props }}</p> </SlotDemo> </a-tab-pane> <a-tab-pane key="bigProps" tab="大属性"> <BigProps :name="bigPropsName" :on-change="handleBigPropChange" :slot-default="getDefault()" :slot-title="getTitle()" :slot-scope-item="getItem" /> </a-tab-pane> </a-tabs> </div> </template> <script> import Props from "./Props"; import Event from "./Event"; import Slot from "./Slot"; import BigProps from "./BigProps"; export default { components: { Props, Event, SlotDemo: Slot, BigProps }, data: () => { return { name: "", type: "success", bigPropsName: "Hello world!" }; }, methods: { handlePropChange(val) { this.type = val; }, handleEventChange(val) { this.name = val; }, handleBigPropChange(val) { this.bigPropsName = val; }, getDefault() { return [this.$createElement("p", "default slot")]; }, getTitle() { return [ this.$createElement("p", "title slot1"), this.$createElement("p", "title slot2") ]; }, getItem(props) { return [ this.$createElement("p", `item slot-scope ${JSON.stringify(props)}`) ]; } } }; </script>
没有什么特别的展示效果。只是把我们父组件传递的值罗列在这里
这里我们看到div上面挂载了一个title,这就是原生属性,默认自动挂载到我们的根元素
如果你并不想要这个自动挂载的功能
我们把它设置为false 就可以了inheritAttrs:false
这样title就不见了
按钮的事件,不要去这么做
如果放开这段代码就会报错。
因为我们的属性是一个单行数据流的,不能够在子组件内修改父组件传递过来的值
可以使用回调的方式,也就是onChange,但是这不是最好的方式,后续会讲到
属性就讲到这里,
课后习题
基础篇会集中的解答。
完结