vue组件
组件使用的细节点
is的使用
<div id="app">
<table>
<tbody>
<tr is="row"></tr>
<row></row>
<row></row>
</tbody>
</table>
</div>
<script>
Vue.component("row", {
template: "<tr><td>this is a row</td></tr>"
})
var app = new Vue({
el: "#app",
})
通过浏览器查看网页源码,使用了is=row的标签进行了正常的输出,
两外两个标签渲染的位置有误(不同浏览器可能不同)
子组件数据
在子组件中,data是一个函数,必须返回一个对象
Vue.component("row", {
data: function() {
return {
content: "this is a row"
}
},
template: "<tr><td>{{content}}</td></tr>"
})
ref引用
通过使用ref来进行两个数字的相加
<body>
<div id="app">
<counter ref="one" @change="handleChange"></counter>
<counter ref="two" @change="handleChange"></counter>
<div>{{total}}</div>
</div>
<script>
Vue.component("counter", {
data: function() {
return {
content: 0
}
},
template: "<div @click='handleClick'>{{content}}</div>",
methods: {
handleClick: function () {
this.content++;
this.$emit("change")
}
}
})
var app = new Vue({
el: "#app",
data: {
total: 0
},
methods: {
handleChange: function () {
this.total = this.$refs.one.content + this.$refs.two.content
}
}
})
</script>
</body>
父子组件传值
父传子
子组件中不能直接修改父组件中传递过来的数据(单项数据流)
<div id="app">
<counter :content="0"></counter>
<counter :content="0"></counter>
<div>{{total}}</div>
</div>
<script>
var counter = {
props: ['content'],
data: function() {
return {
num: this.content
}
},
template: "<div @click='handleClick'>{{num}}</div>",
methods: {
handleClick: function () {
this.num ++;
}
}
}
子传父
通过事件触发的形式来进行传值
<div id="app">
<counter :content="0" @inc="handleChange"></counter>
<counter :content="0" @inc="handleChange"></counter>
<div>{{total}}</div>
</div>
<script>
var counter = {
props: ['content'],
data: function() {
return {
num: this.content
}
},
template: "<div @click='handleClick'>{{num}}</div>",
methods: {
handleClick: function () {
this.num +=2;
this.$emit("inc", 2)
}
}
}
var app = new Vue({
el: "#app",
data: {
total: 0
},
methods: {
handleChange: function (step) {
this.total += step
}
},
components: {
"counter": counter
}
})
</script>
prop验证
Vue.component('my-component', {
props: {
// 基础的类型检查 (`null` 匹配任何类型)
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
}
}
}
})
插槽
<body>
<div id="app">
<row>
<!--<div slot="header"></div>-->
<div slot="footer">fotter</div>
</row>
</div>
<script>
Vue.component("row", {
template: `<div>
<slot name="header">
<div>
default
</div>
</slot>
<div>content</div>
<slot name="footer"></slot>
</div>`
})
var app = new Vue({
el: "#app",
})
</script>
</body>
取消header的注释,div中的default就会消失
作用域插槽
<body>
<div id="app">
<child>
<template slot-scope="props">
<div>{{props.item}}</div>
</template>
</child>
</div>
<script>
Vue.component("child", {
data: function() {
return {
list: [1, 2, 3, 4, 5]
}
},
template: `<div>
<ul>
<slot v-for="item in list"
:item="item">
</slot>
</ul>
</div>`
})
var app = new Vue({
el: "#app",
})
</script>
</body>
动态组件
<div id="app">
<component :is="type"></component>
<!--<child-one v-if="type === 'child-one'"></child-one>-->
<!--<child-two v-if="type === 'child-two'"></child-two>-->
<button @click="handleClick">change</button>
</div>
<script>
Vue.component("child-one", {
template: "<div>child one</div>"
})
Vue.component("child-two", {
template: "<div>child two</div>"
})
var app = new Vue({
el: "#app",
data: {
"show": true,
type: "child-one"
},
methods: {
handleClick: function () {
this.type = (this.type === 'child-one' ? 'child-two':'child-one')
}
}
})
</script>
被注释的内容效果和<component :is="type"></component>效果是一样的
Vue.component("child-one", {
template: "<div v-once>child one</div>"
})
Vue.component("child-two", {
template: "<div v-once>child two</div>"
})
当使用了v-once后,组件中的内容会被渲染成静态文本