1.创建组件
- Vue.extend、Vue.component结合创建
<div id="app">
<index-a></index-a>
</div>
<script>
// 方法1
var index = Vue.extend({
template: "<div>我是方法1创建的模板</div>"
})
Vue.component("indexA", index);
var vm = new Vue({
el: "#app",
})
</script>
- Vue.component创建
<div id="app">
<index-b></index-b>
</div>
<script>
// 方法2
Vue.component("indexB", {
template: "<div>我是方法2创建的模板</div>"
})
var vm = new Vue({
el: "#app",
})
</script>
- template创建
<template id="text">
<div>我是方法3创建的模板</div>
</template>
<div id="app">
<index-c></index-c>
</div>
<script>
// 方法3
Vue.component("indexC", {
template: "#text"
})
var vm = new Vue({
el: "#app",
})
</script>
注意
- template只能有一个根节点。
- 组件如果用驼峰命名,例如indexA,使用时用连字符"-",例如index-a。
2.组件中的指令和事件
<div id="app">
<index></index>
</div>
<script>
Vue.component("index", {
template: "<div>{{msg}}<button @click='changeMsg'>点击</button></div>",
data () {
return {
msg: "今天多少号?"
}
},
methods: {
changeMsg () {
this.msg = "今天2月31";
}
}
})
var vm = new Vue({
el: "#app",
})
</script>
注意
- 组件中可以使用vue实例中的大多数选项,但是data必须写成方法。
3.创建父子组件
<div id="app">
<father></father>
</div>
<script>
Vue.component("father", {
template: "<div>我是爸爸<son></son></div>",
components: {
son: {
template: "<div>我是儿子</div>",
}
}
})
var vm = new Vue({
el: "#app",
})
</script>
注意
- 创建:通过components属性创建,子组件是对象。
- 使用:在template中,父组件 包含 子组件,如果是平级,则会报错。
4.父组件传值给子组件
<div id="app">
<father></father>
</div>
<script>
Vue.component("father", {
template: "<div>我是爸爸,儿子名叫{{sonName}}<son :myName='sonName'></son></div>",
data () {
return {
sonName: "benny",
}
},
components: {
son: {
props: ["myName"],
template: "<div>我是儿子,名叫{{myName}}</div>",
}
}
})
var vm = new Vue({
el: "#app",
})
</script>
传值的过程:
父组件传值给子组件
5.子组件传值给父组件
<div id="app">
<father></father>
</div>
<script>
Vue.component("father", {
template: `
<div>我儿子的名字叫做{{sonName}}
<son @tellName='getName'></son>
</div>
`,
data () {
return {
sonName: "....",
}
},
methods: {
getName (data) {
this.sonName = data;
}
},
components: {
son: {
template: `<button @click='emitName'>告诉他我叫{{name}}</button>`,
data () {
return {
name: "舒克",
}
},
methods: {
emitName () {
return this.$emit("tellName", this.name);
}
}
}
}
})
var vm = new Vue({
el: "#app",
})
</script>
传值的过程:
子组件传值给父组件
注意
- 子组件需要用$emit(param1, param2)方法来传值 :param1 -- 事件名称 | param2 -- 需要传递的数据。
- 父组件用getName(param)来接收值,param是默认参数,表示从子组件传递的值。
6.兄弟组件之间传值
<div id="app">
<father></father>
</div>
<script>
// 创建空vue实例,作为事件总线
var eventbus = new Vue();
Vue.component("father", {
template: `<div>
<bro></bro>
<sis></sis>
</div>`,
components: {
bro: {
template: `<div>我妹妹叫{{sisName}}</div>`,
data () {
return {
sisName: "....",
}
},
mounted () {
// eventbus.$on可以监听兄弟节点发射过来的事件
// eventbus.$on有两个参数,参数1--“事件名称”,参数2--“函数(参数即为传递过来的数据)”
eventbus.$on("tellBroMyName", data => {
this.sisName = data;
})
}
},
sis: {
template: `<button @click="emitMyName">我叫{{myName}}</button>`,
data () {
return {
myName: "花泽香菜",
}
},
methods: {
emitMyName () {
// 通过事件总线,发射事件名称和值
eventbus.$emit("tellBroMyName", this.myName);
}
}
}
}
})
var vm = new Vue({
el: "#app",
})
</script>
传值的过程:
兄弟组件之间传值
注意
- bro和sis是兄弟关系,作用域不同,所以要通过eventbus来传值,eventbus相当于“中介”。
6.动态创建组件
<div id="app">
<ul>
<li @click="currentComponent = 'movie'"><a href="#">影评</a></li>
<li @click="currentComponent = 'book'"><a href="#">书评</a></li>
<li @click="currentComponent = 'drama'"><a href="#">剧评</a></li>
</ul>
<!-- 利用component标签创建动态组件,is属性指向谁,就显示哪个组件 -->
<component :is="currentComponent"></component>
</div>
<script>
// 影评组件
Vue.component("movie", {
template: `<div>荒岛余生</div>`,
})
// 书评组件
Vue.component("book", {
template: `<div>百年孤独</div>`,
})
// 剧评组件
Vue.component("drama", {
template: `<div>开心麻花剧场</div>`,
})
var vm = new Vue({
el: "#app",
data: {
currentComponent: "",
},
})
</script>
7.局部过滤器和局部自定义属性
<div id="app">
<fil></fil>
<direc></direc>
</div>
<script>
// 全局自定义指令
Vue.directive("pinkfont", {
inserted (el, binding) {
el.style.color = binding.value
}
})
Vue.component("fil", {
data() {
return {
time: new Date(),
color: "pink",
}
},
template: `
<div>
<p>{{time | formatTime}}</p>
<input type="text" v-pinkfont="color" >
</div>
`,
// 局部过滤器
filters: {
formatTime(ctime) {
let y = ctime.getFullYear();
let m = ctime.getMonth() + 1;
let d = ctime.getDate();
return y + "/" + m + "/" + d;
}
}
})
Vue.component("direc", {
data() {
return {
time: new Date(),
color: "pink",
}
},
template: `
<div>
<p>{{time}}</p>
<input type="text" v-focus v-pinkfont="color" >
</div>
`,
// 局部自定义指令
directives: {
focus: {
inserted (el, binding) {
el.focus();
}
}
}
})
var vm = new Vue({
el: "#app",
})
</script>
注意
- 全局自定义指令和全局过滤器可以在任何组件中使用。
- 局部指定和局部过滤器,只能在当前组件中使用,脱离当前组件则无效。
8.生命周期
$el -- vue实例使用的根DOM元素
$data -- vue实例观察的数据对象
- beforeCreate
实例初始化之后被调用。
实例未完成配置:数据观测(data observer)和event/watch配置。 - created
实例创建完成后立即被调用。
实例已完成配置:
1.数据观测(data observer)
2.属性和方法的运算
3.watch/event事件回调
实例未完成配置:挂载阶段未开始,dom未生成,$el属性不可见。 - beforeMount
模板编译挂载前被调用。
过程:判断el => 判断template属性 => 生成vm.$el,但指令未被解析 - mounted
模板编译挂载之后调用。
过程:vm.$el替换掉el指向的DOM - beforeUpdate
因为数据变更,从而导致虚拟DOM重新渲染,之前调用。 - updated
因为数据变更,从而导致虚拟DOM重新渲染,之后调用。 - beforeDestroy
实例销毁之前调用。
此时,实例完全可以正常使用。 -
destroyed
vue实例指向的所有东西解除绑定,包括watcher、事件、所有子组件。
生命周期图解(部分)
网友评论