props
子组件内接收来自父组件传递过来的数据集合
两种写法:
1、 props : ['todos','item']
2、
props:{ 'todos' : String , 'item': Array } //或者 props :{ 'todos':{ type: Number, //数据类型 default: 0, //默认值 required: true, validator: function (value) { //自定义校验 return value >= 0 } }
非 Prop 的特性
一个非 prop 特性是指传向一个组件,但是该组件并没有相应 prop 定义的特性。
因为显式定义的 prop 适用于向一个子组件传入信息,然而组件库的作者并不总能预见组件会被用于怎样的场景。这也是为什么组件可以接受任意的特性,而这些特性会被添加到这个组件的根元素上。
对于绝大多数特性来说,从外部提供给组件的值会替换掉组件内部设置好的值。所以如果传入 type="text"
就会替换掉 type="date"
并把它破坏!庆幸的是,class
和 style
特性会稍微智能一些,即两边的值会被合并起来,从而得到最终的值:form-control date-picker-theme-dark
。
//父组件
<vModel v-model="textValue" class="username-input" placeholder="Enter your username" :a='1'></vModel>
//子组件
<template>
<!-- v-model实现 -->
<input
type="text"
v-bind='$attrs'
:value="value"
@input="input"
>
<!-- <input
:value="value"
@change="change"
> -->
</template>
<script>
export default {
inheritAttrs: false, //当在子组件中加入inheritAttrs:false时class等属性就不会自动加到根元素上了。
name: "HelloWorld",
// model: {
// //一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框
// //等类型的输入控件可能会将 value 特性用于不同的目的。model 选项可以用来避免这样的冲突:
// prop: "value",
// event: "change"
// },
props: ["value"],
data() {
return {};
},
methods: {
input(e) {
this.$emit("input", e.target.value);
console.log(e.target.value);
}
// change(e) {
// this.$emit("change", e.target.value);
// console.log(e.target.value);
// }
},
mounted() {
console.log(this.$attrs); // {placeholder: "Enter your username", a: 1} 不包含class
}
};
</script>
$attrs存储非prop特性,inheritAttrs控制vue对非prop特性默认行为
solt 插槽
子组件
<template> <ul> <li v-for="(item, index) in todos" :key="index"> <slot :todo='item'> 这是默认组件的todo{{item}} </slot> </li> </ul> </template> <script> export default { props: { todos: Array }, data () { return {} }, mounted() { console.log(this.todos); }, } </script> <style lang="scss" scoped> </style>
父组件
<template> <div class="home"> <img alt="Vue logo" src="@/assets/logo.png"> <TodoList :todos = 'listArray'> <span slot-scope="{todo}">这是不一样的todo{{todo}}</span> </TodoList> <TodoList :todos = 'listArray'></TodoList> <TodoList :todos = 'listArray'> {{name}} </TodoList> </div> </template> <script> // @ is an alias to /src import HelloWorld from '@/components/HelloWorld.vue' import TodoList from '@/components/list.vue' export default { data () { return { name:'这是作用域测试', listArray: [ { id: 1, value: 'this is ad1' }, { id: 2, value: 'this is ad2' } ] } }, components: { HelloWorld, TodoList } } </script>
结果:
<template>
<!-- v-model实现 -->
<input
type="text"
v-bind='$attrs'
:value="value"
@input="input"
>
<!-- <input
:value="value"
@change="change"
> -->
</template>
<script>
export default {
inheritAttrs: false,
name: "HelloWorld",
// model: {
// //一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框
// //等类型的输入控件可能会将 value 特性用于不同的目的。model 选项可以用来避免这样的冲突:
// prop: "value",
// event: "change"
// },
props: ["value"],
data() {
return {};
},
methods: {
input(e) {
this.$emit("input", e.target.value);
console.log(e.target.value);
}
// change(e) {
// this.$emit("change", e.target.value);
// console.log(e.target.value);
// }
},
mounted() {
console.log(this.$attrs);
}
};
</script>