Vue 相关知识梳理系列文章将在本号持续发布,一起查漏补缺学个痛快!若您有遇到其它相关问题,非常欢迎在评论中留言讨论,达到帮助更多人的目的。若感本文对您有所帮助请点个赞吧!
从1989年 Tim 发明了超文本标记语言 HTML 开始,前端的发展就此开始了。从开始的静态网页,再到 ASP、JSP 和 PHP 等创建动态 HTML 方式的诞生,之后是 JavaScript的加入,JavaScript 操作 HTML,JQuery 的诞生。从 MVC 模式演变到 MVVM框架模式等等,前端在悄无声息间茁壮成长。
2013年,在 Google 工作的尤雨溪,受到 Angular 的启发,开发出了一款轻量框架,最初命名为 Seed。2013年12月,更名为 Vue,图标颜色是代表勃勃生机的绿色,版本号是 0.6.0。2014.01.24,Vue 正式对外发布,版本号是 0.8.0。
2015.10.26,vue-router、vuex、vue-cli 相继发布,标志着 Vue 从一个视图层库发展为一个渐进式框架。2016.10.01,Vue 2.0 发布,它吸收了 React 的虚拟 Dom 方案,还支持服务端渲染。2019.12.05,在万众期待中,尤雨溪公布了 Vue 3 源代码,目前 Vue 3 处于 Alpha 版本。
本系列旨在梳理 Vue 2.0 相关知识,接下来让我们一起Vue的旅途吧!
组件化的使用
创建组件构造器 vue.extend()
调用 vue.extend() 创建的是一个组件构造器。通常在创建组件构造器时,传入 template 代表我们自定义组件的模板。该模板就是在使用到组件的地方,要显示的HTML代码。
注册组件 vue.component()
调用 vue.component() 是将刚才的组件构造器注册为一个组件,并且给它起一个组件的标签名称。( 所以需要传递两个参数:注册组件的标签名和组件构造器。)
使用组件(全局组件)
<body>
<div id="app">
//3.使用组件
<my-cpn></my-cpn>
</div>
<script src="../js/vue.js"></script>
<script>
//1.创造组件构造器对象
const cpnC = Vue.extend({
template: //模板
<div>
<h2>title</h2>
<p>哈哈哈哈哈哈</p>
<p>嘎嘎嘎嘎嘎</p>
</div>
});
//2.注册组件:此组件为全局组件(组件标签名,组件构造器
Vue.component('my-cpn',cpnC)
let app = new Vue({
el: '#app'
})
</script>
</body>
局部组件
局部组件(只能在当前vue实例中使用)。
全局组件(可以再多个vue的实例下使用)。
<body>
<div id="app">
//3.使用组件
<my-cpn></my-cpn>
</div>
<script src="../js/vue.js"></script>
<script>
//1.创造组件构造器对象
const cpnC = Vue.extend({
template: //模板
<div>
<h2>title</h2>
<p>哈哈哈哈哈哈</p>
<p>嘎嘎嘎嘎嘎</p>
</div>
});
//2.注册组件--此组件为局部组件
let app = new Vue({
el: '#app',
components:{
<!--cpn使用组件时的标签名-->
cpn:cpnC
}
})
</script>
</body>
组件语法糖注册
省去了调用 Vue.extend() 的步骤,而是可以直接使用一个对象来代替。
<!--注册全局组件语法糖-->
Vue.component('my-cpn',{ <!--my-cpn组件标签名-->
template: //模板
<div>
<h2>lalalala</h2>
<p>哈哈哈哈哈哈</p>
<p>嘎嘎嘎嘎嘎</p>
</div>
})
<!--注册局部组件语法糖-->
components: {
'my-cpn':{ <!--my-cpn组件标签名-->
template: //模板
<div>
<h2>lalalala</h2>
<p>哈哈哈哈哈哈</p>
<p>嘎嘎嘎嘎嘎</p>
</div>
}
}
组件模板的分离写法
将 HTML 分离出来写,然后挂载到对应的组件上,使结构清晰。
使用<script>标签
使用<template>标签
<body>
<!--方法1:使用<script>标签-->
<div id="app">
<my-cpn></my-cpn>
</div>
<script type='text/x-temolate' id="myCpn">
<div>
<h2>lalala</h2>
<p>哈哈哈哈哈哈</p>
</div>
</script>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
components: {
'myCpn': {
template: '#myCpn'
}
}
})
</script>
</body>
<<body>
<!--方法2:使用<template>标签-->
<div id="app">
<my-cpn></my-cpn>
</div>
<template id='myCpn'>
<div>
<h2>lalala</h2>
<p>哈哈哈哈哈哈</p>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
components: {
'myCpn': {
template: '#myCpn'
}
}
})
</script>
</body>
父组件和子组件
<body>
<div id="app">
<parent-cpn></parent-cpn>
</div>
<script src="../js/vue.js"></script>
<script>
//1.创建一个子组件构造器
const childComponent = Vue.extend({
template:
<div>child子组件内容</div>
})
//1.创建一个父组件构造器
const parentComponent = Vue.extend({
template:
<div>
parent父组件内容
<child-cpn></child-cpn>
</div>
,
component:{
'child-cpn': childComponent
}
})
let app = new Vue({
el: '#app',
components: {
'parent-cpn': parentComponent
}
})
</script>
</body>
父级向子级传递 props
在组件中,使用选项 props 来声明需要从父级接收到的数据。
props 的值有两种方式:
字符串数组,数组中的字符串就是传递时的名称。
对象,对象可以设置传递时的类型,也可以设置默认值等。
props 选项是使用一个数组。除了数组之外,也可以使用对象,当需要对props进行类型等验证时,就需要对象写法。验证都支持的数据类型String、Number、Boolean、Array、Object、Date、Function、Symbol。
<<body>
<div id="app">
<cpn :cmovies="movies" :messages="message"></cpn> //传数据
</div>
<template id="cpn">
<div>
<ul>
<li>v-for="item in cmovies"{{item}}</li>
</ul>
<h2>{{messages}}</h2>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
//父传子:props
const cpn = {
template: '#cpn',
props: ['cmovies' ,'messages'],//被传数据
data() { //data必须return
return {}
},
}
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
movies: ['1','2','3']
},
components: { ///局部组件
cpn //增强写法
}
})
</script>
</body>
子级向父级传递 events
当子组件需要向父组件传递数据时,就要用到自定义事件。
自定义事件的流程:
在子组件中,通过$emit()来触发事件。
在父组件中,通过v-on来监听子组件事件。
<<body>
<!--父组件模板-->
<div id="app">
//2.监听子组件事件
<cpn @item-click="cpnClick"></cpn>
</div>
<!--子组件模板-->
<template id="cpn">
<div>
<button v-for="item in categories"
@click="btnClick">{{item.name}}
</button>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
//子组件
const cpn = {
template: '#cpn',
data() {
return {
categories: [ //分类
{id:'a', name: '热门推荐'},
{id:'b', name: '手机数码'}
]
}
},
methods: {
btnClick(item){
//1.自定义事件 触发事件(自定义事件名字,参数)
this.$emit('item-click',item)
}
}
}
//2.父组件
const app =new Vue({
el: '#app',
data: {
message: '你好'
},
components: {
cpn
},
methods: {
cpnClick(item){
console.log('cpnClick',item);
}
}
})
</script>
</body>
父子组件的访问方式
父组件访问子组件:使用 $children 或 $refs
子组件访问父组件:使用 $parent
this.$children 是一个数组类型,它包含所有子组件对象。
$refs 针对一个子组件。
$refs 和 ref 指令通常是一起使用的。
首先,我们通过ref给某一个子组件绑定一个特定的 ID 。
其次,通过 this.$refs.ID 就可以访问到该组件了。
$refs 父传子
<body>
<!--父组件模板-->
<div id="app">
<cpn></cpn>
<button @click='btnClick'>按钮</button>
</div>
<template id="cpn">
<div>子组件</div>
</template>
<script src="../js/vue.js"></script>
<script>
const app =new Vue({
el: '#app',
data: {
message: '你好',
},
methods: {
btnClick(){
console.log(this.$children);
//可直接调用子组件方法
this.$children[0].showPassage()
}
},
components: {
cpn: {
template: '#cpn',
data(){
return {
name: '子组件name',
}
}
}
},
methods: {
showMessage(){
console.log('showMessage');
}
}
})
</script>
</body>
$parent 子传父
子组件不能引用父组件或Vue实例的数据,用父组件将数据传递给子组件。
<body>
<!--父组件模板-->
<div id="app">
<cpn ref="aaa"></cpn>
<button @click='btnClick'>按钮</button>
</div>
<template id="cpn">
<div>子组件</div>
</template>
<script src="../js/vue.js"></script>
<script>
const app =new Vue({
el: '#app',
data: {
message: '你好',
},
methods: {
btnClick(){
//$ref 对象类型,默认是一个空的对象
console.log(this.$refs.aaa.name);
}
},
components: {
cpn: {
template: '#cpn',
data(){
return {
name: '子组件name',
}
}
}
},
methods: {
showMessage(){
console.log('showMessage');
}
}
})
</script>
</body>
Vue 相关知识梳理系列文章将在本号持续发布,一起查漏补缺学个痛快!若您有遇到其它相关问题,非常欢迎在评论中留言讨论,达到帮助更多人的目的。若感本文对您有所帮助请点个赞吧!
葛媛
HFun 前端攻城狮