第七章
1. 第一二节 组件与复用 使用Props传递数据
- practioce_4.1.html
<!--
第7章
第一节 组件与复用
创建组件后要注册,全局注册和局部注册
局部组件需只能在该实例的作用域内使用
table里面只能用 is来加载组件
第二节 使用Props传递数据
传递字符串可以不使用V-bind 其他不行
props 要是驼峰变量
组件return的数据作用域只在组件本身
-->
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="screen" href="style_4.css" />
<script src="Vue.js"></script>
</head>
<body>
<div id="first">
<div>
<table>
<tbody is="my-component-part"></tbody>
</table>
</div>
<div>
<label>父组件的数据:</label>
<input type="text" v-model="parentMessage">
<my-component :message="parentMessage" message-text="来自父组件的数据"></my-component>
</div>
</div>
</body>
<script>
Vue.component("my-component",{
props: ["messageText","message"],
template:"<p>{{messageText}}:{{message}}</p>",
data: function(){
return {
counter: 0
};
}
})
var Child = {
template:"<div>我是局部组件</div>"
}
var first = new Vue({
el:"#first",
components: {
"my-component-part":Child
},
data:{
parentMessage:" It is me !"
}
})
</script>
</html>
2. 第三节 组件通信
- practice_4.2.html
<!--
第7章
第三节 组件通信
input v-model
third-component 实现双向绑定的v-model组件的两个要求
1:接收一个value属性
2:有新的value时触发input事件
非父子组件通信:
bus空Vue forth-component
父子组件最好用props和$emit来通信
this.$parent
this.$children 需要遍历所有组件实例麻烦
自组建索引$refs fifth-component
-->
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="screen" href="style_4.css" />
<script src="Vue.js"></script>
</head>
<body>
<div id="first">
<div>
<p>总数:{{total}}</p>
<first-component @increase="handleGetTotal" @reduce="handleGetTotal"></first-component>
</div>
<div>
<p>总数:{{totals}}</p>
<second-component v-model="totals"></second-component>
</div>
<div>
<p>总数:{{totales}}</p>
<third-component v-model="totales"></third-component>
<button @click="handleRe">-1</button>
</div>
<div>
{{message}}
<forth-component></forth-component>
<br>{{msg}}<br>
</div>
<div>
<button @click="handleRef">通过ref获取子组件实例</button>
<fifth-component ref="comA"></fifth-component>
{{refmsg}}
</div>
</div>
</body>
<script>
Vue.component("first-component",{
template:'\
<button @click="handleIncrease">+1</button>\
<button @click="handleReduce">-1</button>\
',
data: function(){
return {
counter: 0
}
},
methods: {
handleIncrease:function(){
this.counter++;
this.$emit("increase",this.counter);
},
handleReduce:function(){
this.counter--;
this.$emit("reduce",this.counter);
}
}
});
Vue.component("second-component",{
template:'\
<button @click="handleClick">+1</button>\
',
data: function(){
return {
counter: 0
}
},
methods: {
handleClick:function(){
this.counter++;
this.$emit("input",this.counter);
}
}
});
Vue.component("third-component",{
props:['value'],
template:'<input :value="value" @input="updateValue">',
methods: {
updateValue:function(event) {
this.$emit("input",event.target.value);
}
}
});
var bus = new Vue();
Vue.component("forth-component",{
template:'<button @click="handleEvent">传递事件</button>',
methods: {
handleEvent:function(){
bus.$emit("on-message","来自组件forth的内容");
this.$parent.msg = "来自forth的内容,修改了父链"
}
}
});
Vue.component("fifth-component",{
template:'<p>ref=comA的子组件</p>',
data:function(){
return {
message:"fifth子组件的内容"
}
}
})
var first = new Vue({
el:"#first",
data:{
total: 0,
totals: 0,
totales: 0,
msg:"Parent",
message:"",
refmsg:"",
},
mounted:function() {
var _this = this ;
bus.$on("on-message",function(msg){
_this.message = msg;
})
},
methods:{
handleGetTotal:function(total){
this.total = total;
},
handleRe:function(){
this.totales--;
},
handleRef:function(){
var msg = this.$refs.comA.message;
this.refmsg = msg;
console.log(msg);
}
}
})
</script>
</html>
3. 第四节 使用slot分发
- practice_4.3.html
<!--
第7章
第四节 使用slot分发内容
作用域
slot用法
作用域插槽
访问slot $slot
-->
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="screen" href="style_4.css" />
<script src="Vue.js"></script>
</head>
<body>
<div id="first">
<a-component>
<h2 slot="header">标题</h2>
<div>
<p>分发的内容</p>
<p>更多分发的内容</p>
</div>
<div>
<p slot="footer">底部信息</p>
</div>
</a-component>
</div>
<div id="second">
<my-list :books="books">
<template slot="book" slot-scope="props">
<li>
{{props.bookName}}
</li>
</template>
</my-list>
</div>
</body>
<script>
Vue.component("a-component", {
template: '\
<div>\
<slot name="header"></slot>\
<slot>\
<p>如果父组件没有插入内容,我将作为默认出现</p>\
</slot>\
<slot name="footer"></slot>\
</div>',
mounted () {
var header = this.$slots.header;
// console.log(header);
console.log(header[0].elm.innerHTML);
// 访问slot
}
});
Vue.component("my-list", {
props: {
books: {
type: Array,
default: function () {
return [];
}
}
},
template: '\
<ul>\
<slot name="book"\
v-for="book in books"\
:book-name="book.name">\
</slot>\
</ul>'
});
var app = new Vue({
el: '#first',
})
var second = new Vue({
el: '#second',
data: {
books: [
{
name: 'HTML'
},
{
name: 'Css3'
},
{
name: 'javascript'
}
]
}
})
</script>
</html>
4. 第五节 组件高级用法
- practice_4.4.html
<!--
第7章
第五节 组件高级用法
递归
内联模板
动态组件
$nextTick
手动挂载
-->
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="screen" href="style_4.css" />
<script src="Vue.js"></script>
</head>
<body>
<div id="first">
<first-component :count="1"></first-component>
<!-- 动态组件 -->
<div>
<component :is="currentView"></component>
<button @click="handleChangeView('A')">A</button>
<button @click="handleChangeView('B')">B</button>
<button @click="handleChangeView('C')">C</button>
</div>
<second-component></second-component>
</div>
<div id="second">
<div id="div" v-if="showDiv">
$nextTick用法
</div>
<button @click="getText">获取div内容</button>
<div id="mount-div"></div>
</div>
</body>
<script>
Vue.component("first-component", {
name: "first-component",
props: {
count: {
type: Number,
default: 1
}
},
template: '\
<div class="child">\
<first-component\
:count="count + 1"\
v-if="count < 3">\
</first-component>\
<p>递归</p>\
</div>',
});
Vue.component('second-component', function (resolve, reject) {
window.setTimeout(function () {
resolve({
template: '<div>我是异步渲染的</div>'
});
}, 2000)
})
//手动挂载
var MyComponent = Vue.extend({
template: '<div>Hello: {{name}}</div>',
data: function () {
return {
name: 'Rain X'
}
}
});
new MyComponent().$mount('#mount-div');
var first = new Vue({
el: '#first',
components: {
comA: {
template: '<p>组件A</p>'
},
comB: {
template: '<p>组件B</p>'
},
comC: {
template: '<p>组件C</p>'
},
},
data: {
currentView: 'comA'
},
methods: {
handleChangeView: function (component) {
this.currentView = 'com' + component;
}
}
})
var second = new Vue({
el: '#second',
data: {
showDiv: false
},
methods: {
getText: function () {
this.showDiv = true;
this.$nextTick(function () {
var text = document.getElementById('div').innerHTML;
console.log(text);
});
}
}
})
</script>
</html>
- style_4.css
div{
border: 1px solid blue;
}
.title{
font: 18px bold orange;
}