1. 程式人生 > 其它 >vue改class_Vue-進階構造屬性

vue改class_Vue-進階構造屬性

技術標籤:vue改class

自定義指令

第一種寫法:宣告一個全域性指令

//宣告一個全域性指令v-x,在任何元件都可以使用
//第一個引數是名字,第二個引數是選項
Vue.directive('x',directiveOptions)

舉例:

//注意,這個後面沒有s
Vue.directive('x',{
  inserted:function(el){
    //點選元素之後,列印x
    el.addEventListener('click',()=>{
      console.log('x')
    })
  }
})

第二種寫法:宣告一個區域性指令,只能在一個元件中使用。

例項一:

Child.vue:

<script>
    export default{
        //注意,這個後面有s
        directives:{
            x:{
                inserted(el){
                    el.addEventListener('click',()=>{
                       console.log('x')
                }
            }
        }
    }
</script>

例項二:自定義一個v-on2的自定義指令

main.js

new Vue({
  directives:{
    on2:{
      inserted(el,info){
        //第一個引數是元素的事件,第二個引數是事件對應的方法(使用者傳遞的值)
        el.addEventListener(info.arg,info.value)
      },
      //解除繫結,避免垃圾過多,監聽之後,把它幹掉
      unbind(el,info){
        el.removeEventListener(info.arg,info.value)
      }
    }
  },
  template:`
  <!--hi是函式-->
    <button  v-on2:click="hi">點我</button>
  `,
  methods:{
    hi(){
      console.log("hi")
    }
  }
}).$mount('#app')

directiveOptions有哪些屬性:加粗字型為常用屬性

  1. bind(el,info,vnode,oldVnode),類似於created,繫結到元素上
  2. inserted,插入到頁面
  3. update
  4. componentUpdated
  5. unbind——相當於destroyed,銷燬掉

Vue的例項、元件用於:資料繫結、事件監聽、DOM更新

Vue的指令主要目的是原生的DOM操作

direcytives的作用是減少DOM操作的重複,也可以說專門用於DOM操作

獲取當前容器:this.$el

如果不用自定義指令,要用created等鉤子函式。如:

created(){
    this.$el.querySelector('#h1').addListener('click',()=>{
        console.log('x')
       })
}

如果某個DOM操作比較複雜或者經常使用,就可以封裝成指令。

mixins——混入(複製)

mixins的作用是減少data、methods、鉤子等構造選項(options)的重複

需求

在每個元件上新增name和time,在出現(created)和毀滅(destroyed)時,打出提示,並且報出存活時間?

App.vue:

<template>
  <div id="app">
    <Child1 v-if="child1Visible"/>
    <button @click="child1Visible=false">x</button>

    <Child2 v-if="child2Visible"/>
    <button @click="child2Visible=false">x</button>

    <Child3 v-if="child3Visible"/>
    <button @click="child3Visible=false">x</button>

    <Child4 v-if="child4Visible"/>
    <button @click="child4Visible=false">x</button>

    <Child5 v-if="child5Visible"/>
    <button @click="child5Visible=false">x</button>
  </div>
</template>

<script>
import Child1 from "./components/Child1.vue"
import Child2 from "./components/Child2.vue"
import Child3 from "./components/Child3.vue"
import Child4 from "./components/Child4.vue"
import Child5 from "./components/Child5.vue"
export default {
  name:"App",
  data() {
    return {
      child1Visible:true,
      child2Visible:true,
      child3Visible:true,
      child4Visible:true,
      child5Visible:true
    }
  },
  components:{
    Child1,
    Child2,
    Child3,
    Child4,
    Child5
  }
}
</script>

dieOrlife.js:記錄生存、死亡

const log={
    data(){
        return{
            name:undefined,
            time:undefined
        }
    },
    created(){
        if(!this.name){
            throw new Error('need name')
        }
        this.time=new Date()
        console.log(`${this.name}出生了`)
    },
    beforeDestroy(){
        const now=new Date()
        console.log(`${this.name}死亡了`)
        console.log(`共生存了:${now-this.time}`)
    }
}

export default log

Child1.vue:

<template>
    <div>
        Child1
    </div>
</template>

<script>
import log from "../mixins/dieOrlife.js"
export default {
    data() {
        return {
            name:"Child1"
        }
    },
    mixins:[log]
}
</script>

Child2.vue:

<template>
    <div>
        Child2
    </div>
</template>

<script>
import log from "../mixins/dieOrlife.js"
export default {
    data() {
        return {
            name:"Child2"
        }
    },
    mixins:[log]
}
</script>

Child3.vue:

<template>
    <div>
        Child3
    </div>
</template>

<script>
import log from "../mixins/dieOrlife.js"
export default {
    data() {
        return {
            name:"Child3"
        }
    },
    mixins:[log]
}
</script>

Child4.vue:

<template>
    <div>
        Child4
    </div>
</template>

<script>
import log from "../mixins/dieOrlife.js"
export default {
    data() {
        return {
            name:"Child4"
        }
    },
    mixins:[log]
}
</script>

Child5.vue:

<template>
    <div>
        Child5
    </div>
</template>

<script>
import log from "../mixins/dieOrlife.js"
export default {
    data() {
        return {
            name:"Child5"
        }
    },
    mixins:[log]
}
</script>

extends——繼承、擴充套件

mixins的另一種更抽象寫法,不好用。

provide、inject:提供、注入

用於大範圍的資料(data)、方法(methods)的共用,祖先提供東西,後代注入東西

注意,不能只傳themeName,不傳changeName。因為themeName的值是被複制給provide的

App.vue:

<template>
  <div :class="`app theme-${themeName}`">
    <Child1/>
    <button>x</button>
    <Child2/>
    <button>x</button>
    <Child3/>
    <button>x</button>
    <Child4/>
    <button>x</button>
    <Child5/>
    <button>x</button>
  </div>
</template>

<script>
import Child1 from "./components/Child1.vue";
import Child2 from "./components/Child2.vue";
import Child3 from "./components/Child3.vue";
import Child4 from "./components/Child4.vue";
import Child5 from "./components/Child5.vue";
export default {
  name: "App",
  //提供共用的方法
  provide(){
    return{
      themeName:this.themeName,
      changeTheme:this.changeTheme
    }
  }
  ,
  data() {
    return {
      themeName: "blue", // 'red'
    };
  },
  components: {
    Child1,
    Child2,
    Child3,
    Child4,
    Child5
  },
  methods:{
    //改主題色的函式方法
    changeTheme(){
      if(this.themeName==='blue'){
        this.themeName='red'
      }else{
        this.themeName='blue'
      }
    }
  }
};
</script>

<style>
.app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
.app.theme-blue button {
  background: blue;
  color: white;
}
.app.theme-blue {
  color: darkblue;
}

.app.theme-red button {
  background: red;
  color: white;
}
.app.theme-red {
  color: darkred;
}
</style>

changeThemeButton.vue:

<template>
    <div>
        <button @click="z">當前主題色:{{themeName}}</button>
    </div>
</template>

<script>
export default {
    //引用共用方法
    inject:['themeName','changeTheme'],
    methods:{
        z(){
            this.changeTheme()
        }
    }
}
</script>

codeSandBox的報錯:

8acabcc26ac29576ee80bbfaaeac2f5e.png

解決方法

把程式碼中的 import Vue from 'vue/dist/vue' 全部改為 import Vue from 'vue/dist/vue.common' 就可以了。