组件化:
全局组件:
1、创建组件构造器(template 只能有一个根元素)
var Profile = Vue.extend({
template: "<div><p>标题</p><p>内容</p></div>"
})
2、注册已经创建好的组件
// 第一个参数:组件名称
// 第二个参数:组件构造器
Vue.component('my-component',Profile)
3、使用注册好的组件
<my-component></my-component>
创建组件的其他写法简写
// 1、直接将一个对象作为第二个参数,这时内部会自动创建组件构造器
Vue.component('my-component-2',{
template: "<div><p>标题2</p><p>内容2</p></div>"
})
// 2、template 的内容写在 script 中
Vue.component('my-component-3',{
template:"#info"
})
<script id='info' type="text/html">
<div>
<div>标题3</div>
<div>内容3</div>
</div>
</script>
//3、template 的内容写在 template 标签中
Vue.component('my-component-4',{
template:"#info"
})
<template id='info'>
<div>
<div>标题4</div>
<div>内容4</div>
</div>
</template>
局部组件:
// 自定义组件属性key
components: {
"my-component-5": {
template: "#info",
},
},
动态组件
// v-bind:is='' 通过这种方式切换组件可以保存组件的状态
<!-- 失活的组件将会被缓存!-->
<keep-alive>
<component v-bind:is="要展示的组件名称"></component>
</keep-alive>
父子组件
//首先弄两个组件
<template id="fater">
<div>
<p>我是你爹</p>
<son></son>
</div>
</template>
<template id="son">
<div>
<p>我是儿子</p>
</div>
</template>
// 注册组件
Vue.component('father',{
template:'#fater',
// father 组件里面存在子组件 son。
components:{
'son':{
template:'#son',
}
}
})
// 父组件给子组件传数据
// 子组件添加 props 字段,弄个数组,接受的字段全写进去就好啦。
'son':{
template:'#son',
props:['name','age']
}
//使用的地方,用 :name 就可以将参数传递过来
<son :name='name' :age='age'></son>
//父组件的方法传递给子组件
// 1、将父组件的方法 fatherFn,通过约定的事件名 sonclick,传递给子组件
<son :name='name' :age='age' @sonclick='fatherFn'></son>
// 2、子组件添加自己的事件,调用自己方法。
<p @click='sonFn'>点击事件</p>
// 3、子组件在自己的方法中,通过以下方式调用父组件。
sonFn(){
this.$emit('sonclick')
}
//子组件给父组件传递参数
通过调用父组件方法,传递参数。
this.$emit('sonclick','哈哈哈哈')
*** 传递参数的时候不能用驼峰命名,用 - 连接,接受到的就是驼峰命名
*** 传递方法的时候不能用驼峰命名,只能用 - 连接
插槽
默认情况下是不能在组件中添加子元素的。要想添加就需要用到 slot。
匿名插槽
<template id="son">
<div>
<div>头部</div>
<!-- 如果将来不在组件中添加子元素,则显示下面的内容。否则将会替换这一块儿内容 -->
<slot>默认数据</slot>
<div>尾部</div>
</div>
</template>
具名插槽
<template id="son">
<div>
<div>头部</div>
<slot name='body'>默认数据</slot>
<div>尾部</div>
</div>
</template>
<son>
<!-- 通过名字替换对应的 slot-->
<div slot="body">啦啦啦啦啦啦</div>
</son>
<son>
<!-- v-slot指令替换对应的 slot,v-slot指令只能用于 template 标签-->
<template v-slot:body>
<div>hahahahahah</div>
</template>
</son>
作用域插槽
<template id="son">
<div>
<div>头部</div>
<!-- v-bind:sonName="sonName" 将子组件的数据暴露给父组件 -->
<slot v-bind:sonname="sonName">默认数据{{sonName}}</slot>
<div>尾部</div>
</div>
</template>
<son>
<!-- 通过 obj 接收子组件的相关数据 -->
<template slot-scope='obj'>
<div>hahahahahah{{obj.sonname}}</div>
</template>
</son>
<!-- v-slot: default(插槽名称,匿名插槽为default) obj(参数传递) -->
<template v-slot:default='obj'>
<div>hahahahahah{{obj.sonname}}</div>
</template>
数据共享(Vuex)
// 1.创建 Vuex 对象
const store = new Vuex.Store({
// 用于保存共享数据
state:{
msg:'我是共享数据'
}
})
Vue.component('father', {
template: '#fater',
// 2.在父组件添加这个对象,子组件也可以进行使用
store: store,
//...
<template id="fater">
<div>
<!-- 3.通过以下格式使用就OK -->
<p>{{this.$store.state.msg}}</p>
</div>
</template>
修改共享数据
// 创建 Vuex 对象
const store = new Vuex.Store({
// 用于保存共享数据
state:{
msg:'我是共享数据',
count: 0
},
// 修改共享数据要通过这个统一的方法,方便排查错误
mutations:{
mAdd(state){
state.count = state.count + 1
}
}
})
//使用
this.$store.commit('mAdd')
//计算属性
// 创建 Vuex 对象
const store = new Vuex.Store({
// 用于保存共享数据
state:{
msg:'我是共享数据',
},
// 和组件中的计算属性一样的(computed)
getters:{
format(state){
return "格式化数据" + state.msg
}
}
})
//使用
<p>{{this.$store.getters.format}}</p>
Vue Router:
// 基本步骤
// 1、定义组件
const one = {
template: '#one'
}
const two = {
template: '#two'
}
// 2、定义路由规则
const routes=[
{path:'/one', component: one},
{path:'/two', component: two},
]
// 3、创建路由对象
const router = new VueRouter({
routes: routes
})
var app = new Vue({
el: '#app',
// 4、路由对象绑定Vue实例
router:router,
components: {
one: one,
two: two
}
})
<!-- 5、路由匹配的组件渲染的位置 -->
<a href="#/one">第一个页面</a>
<a href="#/two">第二个页面</a>
<router-view></router-view>
// router-link to:指定路由 tag:指定渲染的标签(默认是<a>)
<router-link to='/one' tag='button'>第一个页面</router-link>>
<router-link to='/two'>第二个页面</router-link>
// router-link 激活样式
const router = new VueRouter({
routes: routes,
// 指定激活状态的 router-link 样式
linkActiveClass:'wjj-link-active'
})
//页面重定向
const routes=[
// 重定向根路径重定向到具体页面
{path:'/', redirect: '/one'},
{path:'/one', component: one},
{path:'/two', component: two},
]
//参数传递
//通过连接传递参数
<router-link to='/one?name=zs&age=18' tag='button'>第一个页面</router-link>
//获取参数
this.$route.query
//通过占位符来传递
const routes=[
{path:'/two/:name/:age', component: two},
]
<router-link to='/two/zs/18' tag='button'>第一个页面</router-link>
//获取参数
this.$route.params
//嵌套路由
const routes = [
{
path: '/one',
component: one,
children: [{
path: 'sub1',
component: subOne
}, {
path: 'sub2',
component: subTwo
}]
},
]
//监听路由地址变化
var app = new Vue({
//省略代码
data:{
one:1
},
watch:{
one:function(newValue, oldValue){
},
"$route.path":function(newValue, oldValue){
}
},
//省略代码
})
生命周期:
//Vue 创建期间的生命周期方法
beforeCreate(){
//仅仅代表 Vue 实例刚刚被创建,还没有初始化好 Vue 实例的数据和方法,因此不能访问 Vue 的数据和方法。
},
created(){
//Vue 实例数据和方法已经初始化成功
},
beforeMount(){
//编译好最终模板,但是没有将最终的模板渲染到界面上
},
mounted(){
//完成最终的渲染,可以拿到最终的数据(界面上渲染的数据)
},
//Vue 运行期间的生命周期方法
beforeUpdate(){
//保存的数据发生变化就会调用,数据已经修改但是界面还没有同步
},
update(){
//界面同步更新之后就会调用
},
//Vue 销毁期间的生命周期方法
beforeDestroy(){
//表示组件即将被销毁,最后一个可以获取 Vue 实例数据和方法的生命周期方法。
},
destroyed(){
//当前组件已经被销毁
}
Plugin 开发:
第一步:需要搞一个组件。
第二部:编写插件对应的JS文件。
其结构如下图:
插件的配置文件:
import Vue from 'vue'
import Toast from './Toast.vue'
export default {
// 组件封装成为插件,必须提供一个 install 方法,在 install 中注册对应的组件。
install:function(){
Vue.component(Toast.name, Toast)
}
}
我们为啥要把组件封装成插件呢?因为插件更方便进行扩展。
下面我们对插件进行如下修改。
import Toast from './Toast.vue'
export default {
// 这个方法可以接收两个参数(Vue对象,参数)
install: function (Vue, options) {
//1、根据组件生成构造函数
let Contructor = Vue.extend(Toast)
//2、创建对应的实例对象
let taostInstance = new Contructor()
//3、随便创建一个标签
let oDiv = document.createElement('div')
//4、将标签添加到界面上
document.body.appendChild(oDiv)
//5、将创建好的对象挂载到创建好的元素上
taostInstance.$mount(oDiv)
//处理传入的参数(Toast 对象中已经添加 title, isShow 的属性)
if (options){
if (options.title){
taostInstance.title = options.title
}
}
//添加全局方法
//显示toast
Vue.showToast = function(){
taostInstance.isShow = true
}
//隐藏toast
Vue.hideToast = function(){
taostInstance.isShow = false
}
//添加实例方法
Vue.prototype.$toast = function(isShow){
taostInstance.isShow = isShow
}
}
}