vue组件
组件是可复用的 Vue 实例,且带有一个名字。你可以将组件进行任意次数的复用
因为组件是可复用的 Vue 实例,所以它们与 new Vue
接收相同的选项,
例如 data
、computed
、watch
、methods
以及生命周期钩子等。仅有的例外是像 el
这样根实例特有的选项。
每个组件都会各自独立维护它的 数据。因为你每用一次组件,就会有一个它的新实例被创建。
注意点:
1、data
必须是一个函数 目的是每个实例可以维护一份被返回对象的独立的拷贝,如果 Vue 没有这条规则,一个组件内部会影响其他该组件的复用.
全局组件
Vue.component('course', {
template: `<a>ww5</a>`
//返单引号
})
//引用
<course></course>
局部组件:
components: {
course: {
template: `<div>pp</div>`
}
},
//局部组件优先级高于全局
注意 局部组件的优先级高于全局组件
组件之间的传值问题 如下
1、首先组件之间传值依靠v-bind指令绑定标签属性来实现
将属性值绑定vue实例的data属性上实现数据的交互
2、在子组件中通过配置props属性来获取来自于标签属性的数据
3、props属性 设置之后数据将显示在页面上 不设置显示在该组件根标签的行间样式上
通过 Prop 向子组件传递数据:
Prop 是你可以在组件上注册的一些自定义特性。当一个值传递给一个 prop 特性的时候,它就变成了那个组件实例的一个属性一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。
html引用、模板 vue实例代码如下:
<course :list="courseList" :ceshi="ceshi" :post="posts"></course>
props: ['list', 'ceshi', 'post'],
//尽量将属性分开传值 不然还要遍历index才可以找所要的数据
template: `<div>
<ul v-for="item in post" :key="item.name">
<li>{{item.name}}</li>
</ul>
</div>`
new Vue({
el: '#blog-post-demo',
data: {
posts: [
{ id: 1, title: 'My journey with Vue' },
{ id: 2, title: 'Blogging with Vue' },
{ id: 3, title: 'Why Vue is so fun' }
]
}
})
<div class="" id="app">
<course :list="[courseList,dog]"></course>
</div>
<script>
const course = {
props: {
list: {
type: Array,
default:{],
//请求不到数据时显示
require:true,
//规定是否必须有来自父组件的传值 没有报错
validator(value) {
return true;
//默认显示所有值
return value.length < 5;
//传递少于5条数据
}
},
},
data() {
return {
}
},
template: `<div class="wrapper">
<div class="img-box">
<img src="{{list[0][0].poster}}" alt="">
<span>已购:0人</span>
<span>已看:0人</span>
</div>
<div class="content">
<span>Web前端开发之JavaScript(Js)精英课堂【渡一教育】</span>
<span>免费</span>
<span>购买</span>
<span>价格</span>
</div>
</div>`
}
new Vue({
el: '#app',
components: {
course,
},
data: {
dog: {
aaa: 222,
fff: 555
},
courseList: [{
name: 'Web前端开发之JavaScript(Js)精英课堂【渡一教育】',
free: true,
playback: false,
price: 0,
buyNumber: 0,
enrollment: 4942,
poster: 'https://10.url.cn/qqcourse_logo_ng/ajNVdqHZLLBsSud06XlZnJACsTWd7OSA5phIFPRTNibFBeuT8jRjy00Jb5ticSEKYUnpUYdBCicH2U/356'
}]
}
})
组件传值之单项数据流
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
对于单项数据流的处理
1、对于这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。在这种情况下,最好定义一个本地的 data 属性并将这个 prop 用作其初始值:
解析:对于vue实力内部传来的原始值 不在组件内部本地化就是用报警告 但是不会触发vue实力内部的watch侦听器
props: ['initialCounter'],
data: function () {
return {
counter: this.initialCounter
}
}
2、这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性:
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}
3、注意在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变这个对象或数组本身将会影响到父组件的状态。同时触发vue实力内部的侦听器
引用值本地使用需要进行克隆
number:this.list.concat([]),
//对于数组的处理利用该方法不改变原数组 且返回新的数组 完成克隆而非引用
4、对于对象的处理
props验证 传了值接受了
注意那些 prop 会在一个组件实例创建之前进行验证,所以实例的属性 (如 data
、computed
等) 在 default
或 validator
函数中是不可用的。
Vue.component('my-component', {
props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
})
非props特性 传了值没接收汇报错
一个非 prop 特性是指传向一个组件,但是该组件并没有相应 prop 定义的特性。
显式定义的 prop 适用于向一个子组件传入信息,然而组件库的作者并不总能预见组件会被用于怎样的场景。这也是为什么组件可以接受任意的特性,而这些特性会被添加到这个组件的根元素上。
替换/合并已有的特性
在这种情况下,我们定义了两个不同的 class
的值:
form-control
,这是在组件的模板内设置好的date-picker-theme-dark
,这是从组件的父级传入的
对于绝大多数特性来说,从外部提供给组件的值会替换掉组件内部设置好的值。所以如果传入 type="text"
就会替换掉 type="date"
并把它破坏!庆幸的是,class
和 style
特性会稍微智能一些,即两边的值会被合并起来,从而得到最终的值:form-control date-picker-theme-dark
。
<input type="date" class="form-control">
<bootstrap-date-input
data-date-picker="activated"
class="date-picker-theme-dark"
></bootstrap-date-input>