組件化:
全局組件:
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文件。
其結構如下圖:
插件結構圖.png
插件的配置文件:
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
}
}
}