Vue 腳手架編程

来源:https://www.cnblogs.com/codechen8848/archive/2022/10/30/16842298.html
-Advertisement-
Play Games

1.1 初始化腳手架 1.1.1 說明 Vue 腳手架是 Vue 官方提供的標準化開發工具(開發平臺) 最新的版本是 4.x 文檔 1.1.2 具體步驟 第一步(僅第一次執行):全局安裝 @vue/cli npm install -g @vue/cli 第二步: 切換到要創建項目的目錄 ,然後使用命 ...


1.1 初始化腳手架

1.1.1 說明

  1. Vue 腳手架是 Vue 官方提供的標準化開發工具(開發平臺)
  2. 最新的版本是 4.x
  3. 文檔

1.1.2 具體步驟

  1. 第一步(僅第一次執行):全局安裝 @vue/cli

    npm install -g @vue/cli
    
  2. 第二步: 切換到要創建項目的目錄 ,然後使用命令創建項目

    vue create xxxx
    

    xxxx: 項目名

  3. 第三步:啟動項目

    npm run serve
    
  4. 備註:

    1. 如出現:下載緩慢請配置淘寶鏡像:

      npm config set registry https://registry.npm.taobao.org
      
    2. Vue 腳手架隱藏了所有 webpack 相關的配置,若想查看具體的 webpack配置,請執行:

      vue inspect > output.js
      

1.1.3 模板項目的結構

├──node_modules
├──public
│ ├──favicon.ico:頁簽圖標
│ └──index.html:主頁面
├──src
│ ├──assets:存放靜態資源
│ │ └──logo.png
│ │──component:存放組件
│ │ └──HelloWorld.vue
│ │──App.vue:彙總所有組件
│ │──main.js:入口文件
├──.gitignore:git版本管制忽略的配置
├──babel.config.js:babel的配置文件
├──package.json:應用包配置文件
├──README.md:應用描述文件
├──package-lock.json:包版本控制文件

1.1.4 不同版本的 Vue

  1. vue.jsvue.runtime.xxx.js 的區別:
    1. vue.js 是完整版的 Vue,包含:核心功能 + 模板解析器。
    2. vue.runtime.xxx.js 是運行版的 Vue,只包含:核心功能;沒有模板解析器
  2. 因為 vue.runtime.xxx.js 沒有模板解析器,所以不能使用 template 這個配置項,需要使用 render 函數接收到的 createElement 函數去指定具體內容

1.1.5 vue.config.js 配置文件

  1. 使用 vue inspect > output.js 可以查看到Vue腳手架的預設配置。

  2. 使用 vue.config.js 可以對腳手架進行個性化定製,詳情

1.2 ref

1.2.1 使用說明

  1. 被用來給元素或子組件註冊引用信息(id 的替代者)
  2. 應用在 html 標簽上獲取的是真實 DOM 元素,應用在組件標簽上是組件實例對象(vc
  3. 使用方式:
    1. 打標識:<h1 ref="xxx">.....</h1><School ref="xxx"></School>
    2. 獲取:this.$refs.xxx

1.3 props

1.3.1 使用說明

  1. 功能:讓組件接收外部傳過來的數據

  2. 傳遞數據:<Demo name="xxx"/>

  3. 接收數據:

    1. 第一種方式(只接收):props:['name']

    2. 第二種方式(限制類型):props:{name:String}

    3. 第三種方式(限制類型、限制必要性、指定預設值):

      props:{
      	name:{
      	type:String, //類型
      	required:true, //必要性
      	default:'老王' //預設值
      	}
      }
      

    備註:props 是只讀的,Vue 底層會監測你對 props 的修改,如果進行了修改,就會發出警告,若業務需求確實需要修改,那麼請複製 props 的內容到 data 中一份,然後去修改 data 中的數據。

1.3.2 代碼示例

父組件 App 中使用子組件 Student,並傳參數

<template>
<div id="app">
    <!-- 註意:屬性前面有沒有加 : 的區別,沒加就是表示傳的參數是字元串,加了就是表示具體的類型值 -->
    <!-- <Student studentName="張三" studentSex="男" studentAge="18"/> -->
    <hr />
    <Student studentName="張三" studentSex="男" :studentAge="18"/>
    <hr />
    <Student  studentSex="男" :studentAge="20"/>

    </div>
</template>
<script>
    import Student from "./components/Student.vue";

    export default {
        components: { Student }
    };
</script>

Student 組件接收父組件傳來的參數

<template>
  <div>
    <h2>{{ msg }}</h2>
    <h2>學生姓名: {{ studentName }}</h2>
    <h2>學生性別: {{ studentSex }}</h2>
    <!-- <h2>學生年齡: {{ studentAge + 1 }}</h2> -->
    <h2>學生年齡: {{ age + 1 }}</h2>
    <button @click="addAge">點我年齡 +10 </button>
  </div>
</template>

<script>
export default {
  name: "Student",
  // 接收參數的簡要寫法
  // props: ['studentName', 'studentSex', 'studentAge'],

  // 接受參數 + 指定類型的寫法
  // props: {
  //   studentName: String,
  //   studentSex: String,
  //   // 指令類型為數值類型,當傳入的類型不是數值類型時就會報錯
  //   // Expected Number with value 18, got String with value "18".
  //   studentAge: Number, 
  // },

  // 接收參數 + 指定類型 + 指定是否必傳 + 指定預設值
  props: {
    studentName: {
      // 指定類型是字元串
      type: String,
      // 指定預設值
      default: "李四"
    },
    studentSex: {
      type: String,
      // 指定必傳
      required: true
    },
    studentAge: {
      type: Number
    }
  },
  
  data() {
    return {
      msg: "我是一名學生",
      age: this.studentAge
    };
  },

  methods: {
    addAge() {
      // props 是只讀的,Vue 底層會監測你對 props 的修改,如果進行了修改,就會發出警告,若業務需求確實需要修改,那麼請複製 props 的內容到 data 中一份,然後去修改 data 中的數據。
      // 警告 
      // Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders.
      // this.studentAge += 10;
      this.age += 10
    }
  }
};
</script>

1.4 混入

1.4.1 使用說明

  1. 功能:可以把多個組件共用的配置提取成一個混入對象

  2. 使用方式:

    第一步定義混入:

    {
        data(){....},
        methods:{....}
        ....
    }
    

    第二步使用混入:
    ​ - 全局混入:Vue.mixin(xxx)
    ​ - 局部混入:mixins:['xxx']

1.4.2 代碼示例

定義混入 mixin.js

// 定義一個混入配置信息
// 說明:如果混入中配置的數據、方法,在組件中有同樣的數據定義、方法名稱,會載入組件中的數據和方法,混入中的數據和方法就不起作用
const mixin1 = {
    data() {
        return {
            x: 200,
            y: 100
        }
    },
    methods: {
        showName() {
            alert(this.name)
        }
    },
}
// 說明:生命周期中的函數,如果混入、組件中都有配置的話,二者都會執行
const mixin2 = {
    mounted() {
        console.log("mixin 中的 mounted... ")
    },
}

export {
    mixin1,
    mixin2
}

在組件中使用混入:

<template>
  <div>
    <h2>學校名稱: {{ name }}</h2>
    <h2>學校地址: {{ address }}</h2>
    <button @click="showName">點我提示信息</button>
  </div>
</template>

<script>
// 引入混入
import { mixin1 } from "@/mixin";

export default {
  name: "School",
  // 混入配置項
  mixins: [mixin1],
  data() {
    return {
      name: "北京大學",
      address: "北京",
    };
  },
  methods: {
    // showName() {
    //   alert(this.name);
    // },
  },
};
</script>
<template>
  <div>
    <h2>學生姓名: {{ name }}</h2>
    <h2>學生性別: {{ sex }}</h2>
    <h2>學生年齡: {{ age }}</h2>
    <button @click="showName">點我提示信息</button>
  </div>
</template>

<script>
// 引入混入
import { mixin1, mixin2 } from "../mixin";
export default {
  name: "Student",
  mixins: [mixin1, mixin2],

  data() {
    return {
      name: "張三",
      sex: "男",
      age: 20,
      x: 1000,
    };
  },
  methods: {
    showName() {
      console.log("student... ");
      alert(this.name + "hello world");
    },
  },
  mounted() {
    console.log("student 中的 mounted... ");
  },
};
</script>

1.5 插件

1.5.1 使用說明

  1. 功能:用於增強 Vue

  2. 本質:包含 install 方法的一個對象,install 的第一個參數是 Vue,第二個以後的參數是插件使用者傳遞的數據。

  3. 定義插件:

    對象.install = function (Vue, options) {
        // 1. 添加全局過濾器
        Vue.filter(....)
    
        // 2. 添加全局指令
        Vue.directive(....)
    
        // 3. 配置全局混入(合)
        Vue.mixin(....)
    
        // 4. 添加實例方法
        Vue.prototype.$myMethod = function () {...}
        Vue.prototype.$myProperty = xxxx
    }
    
  4. 使用插件:Vue.use()

1.5.2 代碼示例

定義插件 plugins.js

export default {
    install(Vue) {
        console.log(Vue, "@@@@@");

        // 全局定義過濾器
        Vue.filter("strSlice", function (value) {
            return value.slice(0, 4)
        })

        // 全局定義指令
        Vue.directive("fbind", {
            // 指令與元素成功綁定時 一上來
            bind(element, binding) {
                element.value = binding.value
            },
            // 指令所在元素插入頁面時
            inserted(element, binding) {
                element.focus()
            },
            // 指令所在模板被重新解析時
            updated(element, binding) {
                element.value = binding.value
            },
        })
        // 給 Vue 原型上添加一個方法 vm、vc 都能使用
        Vue.prototype.hello = () => {
            console.log("hello world ");
        }
    },

}

main.js 中使用插件

// 引入插件
import plugins from './plugins'

// 使用插件
Vue.use(plugins)

1.6 scoped 樣式

  1. 作用:讓樣式在局部生效,防止衝突。

  2. 寫法:

    <style scoped>
      .demo {
        background-color: orange;
        // less 與 css 的一個區別就是 less 可以疊加寫,css 不可以
        .title {
          font-size: 40px;
        }
      }
    </style>
    

1.7 組件化編碼流程

  1. 組件化編碼流程:
    1. 拆分靜態組件:組件要按照功能點拆分,命名不要與 html 元素衝突。
    2. 實現動態組件:考慮好數據的存放位置,數據是一個組件在用,還是一些組件在用:
      1. 一個組件在用:放在組件自身即可。
      2. 一些組件在用:放在他們共同的父組件上(狀態提升)。
      3. 實現交互:從綁定事件開始。
  2. props 適用於:
    1. 父組件 ==> 子組件 通信
    2. 子組件 ==> 父組件 通信(要求父先給子一個函數)
  3. 使用 v-model 時要切記:v-model 綁定的值不能是 props 傳過來的值,因為 props 是不可以修改的!
  4. props 傳過來的若是對象類型的值,修改對象中的屬性時 Vue 不會報錯,但不推薦這樣做。

1.8 webStorage

1.8.1 使用說明

  1. 存儲內容大小一般支持 5MB 左右(不同瀏覽器可能還不一樣)

  2. 瀏覽器端通過 Window.sessionStorageWindow.localStorage 屬性來實現本地存儲機制

  3. 相關API:

    1. xxxxxStorage.setItem('key', 'value');
      該方法接受一個鍵和值作為參數,會把鍵值對添加到存儲中,如果鍵名存在,則更新其對應的值

    2. xxxxxStorage.getItem('person');
      ​該方法接受一個鍵名作為參數,返回鍵名對應的值

    3. xxxxxStorage.removeItem('key');
      ​該方法接受一個鍵名作為參數,並把該鍵名從存儲中刪除

    4. xxxxxStorage.clear()

      該方法會清空存儲中的所有數據

  4. 備註:

    1. SessionStorage 存儲的內容會隨著瀏覽器視窗關閉而消失
    2. LocalStorage 存儲的內容,需要手動清除才會消失
    3. xxxxxStorage.getItem(xxx) 如果 xxx 對應的 value 獲取不到,那麼 getItem 的返回值是 null
    4. JSON.parse(null) 的結果依然是 null

1.8.2 代碼示例

LocalStorage

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>localStorage 瀏覽器本地存儲</title>
</head>
<body>
    <div>
        <h2>localStorage 瀏覽器本地存儲</h2>
        <button onclick="save()">點我保存一個數據</button>
        <button onclick="read()">點我讀取一個數據</button>
        <button onclick="remove()">點我刪除一個數據</button>
        <button onclick="clearAll()">點我清空數據</button>
    </div>

    <script type="text/javascript">
        let person = {name: "張三", age: 19}

        // localStorage 保存數據時最終都是 字元串
        function save() {
            // 保存字元串
            localStorage.setItem("name", "張三")
            // 保存數字
            localStorage.setItem("age", 18)
            // 保存對象數據
            // localStorage.setItem("person", person)
            localStorage.setItem("person", JSON.stringify(person))
        }

        function read() {
            // 讀取字元串
            console.log(localStorage.getItem("name"))
            // 讀取數字
            console.log(localStorage.getItem("age"))
            // 讀取對象
            console.log(localStorage.getItem("person"))
            console.log(JSON.parse(localStorage.getItem("person")))
        }

        function remove() {
            // 刪除字元串
            localStorage.removeItem("name")
            // 移除數字
            localStorage.removeItem("age")
            // 移除對象
            localStorage.removeItem("person")
        }

        function clearAll() {
            console.log("clear...");
            localStorage.clear()
        }
    </script>
</body>
</html>

SessionStorage

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>sessionStorage 瀏覽器本地存儲</title>
</head>
<body>
    <div>
        <h2>sessionStorage 瀏覽器本地存儲</h2>
        <button onclick="save()">點我保存一個數據</button>
        <button onclick="read()">點我讀取一個數據</button>
        <button onclick="remove()">點我刪除一個數據</button>
        <button onclick="clearAll()">點我清空數據</button>
    </div>

    <script type="text/javascript">
        let person = {name: "張三", age: 19}

        // sessionStorage 保存數據時最終都是 字元串
        function save() {
            // 保存字元串
            sessionStorage.setItem("name", "張三")
            // 保存數字
            sessionStorage.setItem("age", 18)
            // 保存對象數據
            // sessionStorage.setItem("person", person)
            sessionStorage.setItem("person", JSON.stringify(person))
        }

        function read() {
            // 讀取字元串
            console.log(sessionStorage.getItem("name"))
            // 讀取數字
            console.log(sessionStorage.getItem("age"))
            // 讀取對象
            console.log(sessionStorage.getItem("person"))
            console.log(JSON.parse(sessionStorage.getItem("person")))
        }

        function remove() {
            // 刪除字元串
            sessionStorage.removeItem("name")
            // 移除數字
            sessionStorage.removeItem("age")
            // 移除對象
            sessionStorage.removeItem("person")
        }

        function clearAll() {
            console.log("clear...");
            sessionStorage.clear()
        }
    </script>
</body>
</html>

1.9 組件的自定義事件

1.9.1 使用說明

  1. 一種組件間通信的方式,適用於:子組件 ===> 父組件

  2. 使用場景:A 是父組件,B 是子組件,B 想給 A 傳數據,那麼就要在 A 中給 B 綁定自定義事件(事件的回調在 A 中)。

  3. 綁定自定義事件:

    1. 第一種方式,在父組件中:<Demo @helloWorld="test"/><Demo v-on:helloWorld="test"/>

    2. 第二種方式,在父組件中:

      <Demo ref="demo"/>
      ......
      mounted(){
         this.$refs.xxx.$on('helloWorld', this.test)
      }
      
    3. 若想讓自定義事件只能觸發一次,可以使用 once 修飾符,或 $once 方法。

  4. 觸發自定義事件:this.$emit('helloWorld',數據)

  5. 解綁自定義事件this.$off('helloWorld')

  6. 組件上也可以綁定原生 DOM 事件,需要使用 native 修飾符。

  7. 註意:通過 this.$refs.xxx.$on('helloWorld',回調) 綁定自定義事件時,回調要麼配置在methods中要麼用箭頭函數,否則 this 指向會出問題!

1.9.2 代碼示例

父組件 App

<template>
  <div id="app" class="app">
    <h1>學校名稱是:{{ schoolName }}</h1>
    <h1>學生姓名是:{{ studentName }}</h1>

    <!-- 通過 props 來實現子組件給父組件傳遞數據 -->
    <School :getSchoolName="getSchoolName" />

    <!-- 第一種寫法:通過父組件給子組件綁定一個自定義事件來實現子組件給父組件傳遞數據 使用 @ 或者 v-on -->
    <!-- <Student @getStudentName="getStudentName" /> -->
    
    <!-- 第二種寫法:通過父組件給子組件綁定一個自定義事件來實現子組件給父組件傳遞數據 使用 ref-->
    <Student ref="student" />
    
    <!-- 通過父組件給子組件綁定一個自定義事件來實現子組件給父組件傳遞數據,只觸發一次 -->
    <!-- <Student @getStudentName.once="getStudentName"/> -->
    <!-- <Student ref="student" /> -->
    
    <!-- 使用組件原生的方法 -->
    <!-- <Student @click.native="show" /> -->
    
    <!-- <Student @getStudentName="getStudentName" @getDemo="getDemo" /> -->
  </div>
</template>

<script>
import School from "./components/School.vue";
import Student from "./components/Student.vue";
export default {
  components: { School, Student },
  data() {
    return {
      schoolName: "",
      studentName: "",
    };
  },

  methods: {
    // 接收 School 子組件傳遞來的數據
    getSchoolName(name) {
      console.log("App 組件收到了學校名稱", name);
      this.schoolName = name;
    },

    // 接收 Student 子組件傳遞來的數據
    getStudentName(name) {
      console.log("App 組件收到了學生姓名", name);
      this.studentName = name;
    },

    // 接收多個數據
    getDemo(...params) {
      console.log(...params);
    },

    show() {
      alert(123)
    }
  },

  mounted() {
    // 寫法一
    this.$refs.student.$on("getStudentName", (name) => {
      // 普通函數寫法 此時 this 是 VueComponent 實例 Student
      // 箭頭函數寫法 此時 this 是 vm 
      console.log(this,"@@@", name);
       this.studentName = name
    })
    // 寫法二
    // this.$refs.student.$on("getStudentName", this.getStudentName)
    // this.$refs.student.$once("getStudentName", this.getStudentName)
  },
};
</script>

<style>
.app {
  background-color: gray;
  padding: 5px;
}
</style>

子組件 School

<template>
  <div class="school">
    <h2>學校名稱: {{ name }}</h2>
    <h2>學校地址: {{ address }}</h2>
    <button @click="sendSchoolName">把學校名稱給 App 組件</button>
  </div>
</template>

<script>
export default {
  name: "School",
  props: ["getSchoolName"],
  data() {
    return {
      name: "北京大學",
      address: "北京",
    };
  },
  methods: {
    sendSchoolName() {
      this.getSchoolName(this.name);
    },
  },
};
</script>

<style>
.school {
  background-color: skyblue;
  padding: 5px;
}
</style>

子組件 Student

<template>
  <div class="student">
    <h2>學生姓名: {{ name }}</h2>
    <h2>學生性別: {{ sex }}</h2>
    <h2>學生年齡: {{ age }}</h2>
    <button @click="sendStudentName">把學生姓名給 App 組件</button>
    <button @click="unbind">解綁自定義事件</button>
    <button @click="death">銷毀當前組件實例</button>
  </div>
</template>

<script>
// 引入混入
export default {
  name: "Student",

  data() {
    return {
      name: "張三",
      sex: "男",
      age: 20,
    };
  },
  methods: {
    sendStudentName() {
      // 觸發 student 組件實例的 getStudentName 事件
      this.$emit("getStudentName", this.name);
      this.$emit("getDemo", 1, 2, 3, 4);
    },
    // 解綁自定義事件
    unbind() {
      // 解綁一個自定義事件
      // this.$off("getStudentName");

      // 解綁多個自定義事件
      this.$off(["getStudentName", "getDemo"]);
    },
    // 銷毀當前組件實例
    death() {
      // 銷毀了當前Student組件的實例,銷毀後所有Student實例的自定義事件全都不奏效。
      this.$destroy()
    }
  },
};
</script>

<style lang="less" scoped>
.student {
  background-color: orange;
  padding: 5px;
  margin-top: 30px;
}
</style>

1.10 全局事件匯流排

1.10.1 使用說明

  1. 一種組件間通信的方式,適用於任意組件間通信

  2. 安裝全局事件匯流排:

    new Vue({
    	......
    	beforeCreate() {
    		Vue.prototype.$bus = this //安裝全局事件匯流排,$bus就是當前應用的vm
    	},
        ......
    }) 
    
  3. 使用事件匯流排:

    1. 接收數據:A 組件想接收數據,則在 A 組件中給 $bus 綁定自定義事件,事件的回調留在 A 組件自身。

      methods(){
        demo(data){......}
      }
      ......
      mounted() {
        this.$bus.$on('xxxx',this.demo)
      }
      
    2. 提供數據:this.$bus.$emit('xxxx',數據)

  4. 最好在 beforeDestroy 鉤子中,用 $off 去解綁當前組件所用到的事件。

1.10.2 代碼示例

main.js 中安裝全局事件匯流排

import Vue from 'vue'

import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  el: "#app",
  render: h => h(App),
  beforeCreate() {
    // 安裝全局事件匯流排
    Vue.prototype.$bus = this
  }
})

在組件 School 中掛載全局事件

<template>
  <div class="demo">
    <h2>學校名稱: {{ name }}</h2>
    <h2>學校地址: {{ address }}</h2>
  </div>
</template>

<script>
export default {
  name: "School",
  data() {
    return {
      name: "北大大學",
      address: "北京",
    };
  },
  methods: {},
  // 在組件掛載時綁定一個事件
  mounted() {
    this.$bus.$on("getStudentName", (data) => {
      // 此時 this 是 VueComponent 的實例 School
      console.log(this);
      console.log("School 組件收到了數據:", data);
    });
  },
  // 在組件銷毀前解綁事件
  beforeDestroy() {
    this.$bus.$off("getStudentName")
  }
};
</script>

<style>
.demo {
  background-color: skyblue;
}
</style>

Student 組件中觸發全局事件

<template>
  <div class="demo">
    <h2 class="title">學生姓名: {{ name }}</h2>
    <h2>學生性別: {{ sex }}</h2>
    <h2>學生年齡: {{ age }}</h2>
    <button @click="sendStudentName">把學生名字給 School 組件</button>
  </div>
</template>

<script>
// 引入混入
export default {
  name: "Student",

  data() {
    return {
      name: "張三",
      sex: "男",
      age: 20,
    };
  },
  methods: {
    sendStudentName() {
      // 觸發事件
      this.$bus.$emit("getStudentName", this.name)
    }
  },
};
</script>

<!-- <style>
  .demo {
    background-color: orange;
  }
</style> -->
<!-- 不指定,預設使用 css -->
<!--  scoped: 表示樣式只對指定的組件起作用-->
<!-- <style scoped>
  .demo {
    background-color: orange;
  }
</style> -->

<!-- lang: 指定用什麼樣式  -->
<!-- less 需要引入 less-loader:npm install less-loader 指定版本:npm install less-loader@7 -->
<!-- npm view webpack versions 查看 webpack 版本命令,同理: -->
<style lang="less" scoped>
  .demo {
    background-color: orange;
    // less 與 css 的一個區別就是 less 可以疊加寫,css 不可以
    .title {
      font-size: 40px;
    }
  }
</style>

1.11 消息訂閱與發佈

1.11.1 說明使用

  1. 一種組件間通信的方式,適用於任意組件間通信

  2. 它包含以下操作:

    1. 訂閱消息--對應綁定事件監聽
    2. 發佈消息--分發事件
    3. 取消消息訂閱--解綁事件監聽
  3. PubSub.js

    1. 線上文檔
    2. 安裝:
    3. 相關語法:
      • import PubSub from 'pubsub-js' : 引入
      • PubSub.subscribe(‘msgName’, functon(msgName, data){}): 訂閱
      • PubSub.publish(‘msgName’,data): 發佈消息,觸發訂閱的回調函數調用
      • PubSub.unsubscribe(token): 取消消息的訂閱
  4. 使用步驟:

    1. 安裝 pubsubnpm i pubsub-js

    2. 引入: import pubsub from 'pubsub-js'

    3. 接收數據:A組件想接收數據,則在A組件中訂閱消息,訂閱的回調留在A組件自身。

      methods(){
        demo(data){......}
      }
      ......
      mounted() {
        this.pid = pubsub.subscribe('xxx',this.demo) //訂閱消息
      }
      
    4. 提供數據:pubsub.publish('xxx',數據)

    5. 最好在 beforeDestroy 鉤子中,用 PubSub.unsubscribe(pid)取消訂閱。

1.11.2 代碼示例

School 組件訂閱消息

<template>
  <div class="demo">
    <h2>學校名稱: {{ name }}</h2>
    <h2>學校地址: {{ address }}</h2>
  </div>
</template>

<script>
import pubsub from "pubsub-js";
export default {
  name: "School",
  data() {
    return {
      name: "北大大學",
      address: "北京",
    };
  },
  methods: {},
  mounted() {
    // 訂閱消息
    const pubId = pubsub.subscribe("sendStudentName", (messageName, data) => {
      // 箭頭函數寫法 此時 this 是 VueComponent 實例 School
      console.log(this);
      console.log(messageName, data);
    })
    // pubsub.subscribe("sendStudentName", function (messageName, data) {
    //   // 普通函數寫法,此時 this undefined
    //   console.log(this);
    //   console.log(messageName, data);
    // });
  },
  beforeDestroy() {
    // 取消訂閱消息
    // 取消訂閱消息時要用 pubId 去取消訂閱
    pubsub.unsubscribe(this.pubId);
  },
};
</script>

<style>
.demo {
  background-color: skyblue;
}
</style>

Student 組件消費消息

<template>
  <div class="demo">
    <h2 class="title">學生姓名: {{ name }}</h2>
    <h2>學生性別: {{ sex }}</h2>
    <h2>學生年齡: {{ age }}</h2>
    <button @click="sendStudentName">把學生姓名給 School 組件</button>
  </div>
</template>

<script>
// 引入消息訂閱
import pubsub from "pubsub-js";
export default {
  name: "Student",
  data() {
    return {
      name: "張三",
      sex: "男",
      age: 20,
    };
  },
  methods: {
    sendStudentName() {
      // 發佈消息
      // 第一個參數是消息名
      pubsub.publish("sendStudentName", this.name);
    },
  },
};
</script>

<!-- <style>
  .demo {
    background-color: orange;
  }
</style> -->
<!-- 不指定,預設使用 css -->
<!--  scoped: 表示樣式只對指定的組件起作用-->
<!-- <style scoped>
  .demo {
    background-color: orange;
  }
</style> -->

<!-- lang: 指定用什麼樣式  -->
<!-- less 需要引入 less-loader:npm install less-loader 指定版本:npm install less-loader@7 -->
<!-- npm view webpack versions 查看 webpack 版本命令,同理: -->
<style lang="less" scoped>
.demo {
  background-color: orange;
  // less 與 css 的一個區別就是 less 可以疊加寫,css 不可以
  .title {
    font-size: 40px;
  }
}
</style>

1.12 nextTick

  1. 語法:this.$nextTick(回調函數)
  2. 作用:在下一次 DOM 更新結束後執行其指定的回調
  3. 什麼時候用:當改變數據後,要基於更新後的新 DOM 進行某些操作時,要在 nextTick 所指定的回調函數中執行

1.13 過度與動畫

1.13.1 使用說明

  1. 作用:在插入、更新或移除 DOM 元素時,在合適的時候給元素添加樣式類名

  2. 寫法:

    1. 準備好樣式:

      • 元素進入的樣式:
        1. v-enter:進入的起點
        2. v-enter-active:進入過程中
        3. v-enter-to:進入的終點
      • 元素離開的樣式:
        1. v-leave:離開的起點
        2. v-leave-active:離開過程中
        3. v-leave-to:離開的終點
    2. 使用<transition>包裹要過度的元素,並配置 name 屬性:

      <transition name="hello">
      	<h1 v-show="isShow">你好啊!</h1>
      </transition>
      
    3. 備註:若有多個元素需要過度,則需要使用:<transition-group>,且每個元素都要指定 key

1.13.2 代碼示例

transition

<template>
  <div>
    <button @click="isShow = !isShow">顯示/隱藏</button>
    <!-- appear 表示頁面一進來就進行動畫效果 -->
    <transition name="hello" appear>
      <h1 v-show="isShow">Hello World</h1>
    </transition>
  </div>
</template>

<script>
export default {
  name: "Test1",
  data() {
    return {
      isShow: true,
    };
  },
};
</script>

<style scoped>
h1 {
  background-color: orange;
}

.hello-enter-active {
  animation: helloWorld 0.5s linear;
}

.hello-leave-active {
  animation: helloWorld 0.5s linear reverse;
}

@keyframes helloWorld {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(0px);
  }
}
</style>

transition-group

<template>
  <div>
    <button @click="isShow = !isShow">顯示/隱藏</button>
    <!-- appear 表示頁面一進來就進行動畫效果 -->
    <!-- transition-group 包裹一組標簽,需要指定 key -->
    <transition-group name="hello" appear="">
      <h1 v-show="isShow" key="1">Hello</h1>
      <h1 v-show="isShow" key="2">World</h1>
    </transition-group>
  </div>
</template>

<script>
export default {
  name: "Test2",
  data() {
    return {
      isShow: true,
    };
  },
};
</script>

<style scoped>
h1 {
  background-color: skyblue;
}

/* 進入的起點,離開的終點 */
.hello-enter,
.hello-leave-to {
  transform: translateX(-100%);
}

.hello-enter-active,
.hello-leave-active {
  transition: 0.5s linear;
}

/* 離開的起點,進入的重點 */
.hello-leave,
.hello-enter-to {
  transform: translateX(0);
}
</style>

使用第三方動畫庫 Animate.css

<template>
  <div>
    <button @click="isShow = !isShow">顯示/隱藏</button>
    <!-- 使用第三方動畫庫 -->
    <transition-group
      appear
      name="animate__animated animate__bounce"
      enter-active-class="animate__swing"
      leave-active-class="animate__backOutUp"
    >
      <h1 v-show="isShow" key="1">Hello</h1>
      <h1 v-show="isShow" key="2">World</h1>
    </transition-group>
  </div>
</template>

<script>
// Animate.css 使用步驟
// 0.官網地址:https://animate.style/
// 1.安裝:npm install animate.css --save
// 2.引入: import "animate.css";

import "animate.css";
export default {
  name: "Test3",
  data() {
    return {
      isShow: true,
    };
  },
};
</script>

<style scoped>
h1 {
  background-color: orange;
}
</style>

1.14 插槽

1.14.1 使用說明

  1. 作用:讓父組件可以向子組件指定位置插入 html 結構,也是一種組件間通信的方式,適用於 父組件 ===> 子組件

  2. 分類:預設插槽、具名插槽、作用域插槽

1.14.2 預設插槽

父組件

<Category>
    <div>html結構1</div>
</Category>

子組件

<template>
	<div>
        <!-- 定義插槽 -->
        <slot>插槽預設內容...</slot>
    </div>
</template>

1.14.3 具名插槽

父組件中

<Category>
    <template slot="center">
        <div>html結構1</div>
    </template>

    <template v-slot:footer>
        <div>html結構2</div>
    </template>
</Category>

子組件中

<template>
	<div>
        <!-- 定義插槽 -->
        <slot name="center">插槽預設內容...</slot>
        <slot name="footer">插槽預設內容...</slot>
    </div>
</template>

1.14.4 作用域插槽

  1. 理解:數據在組件的自身,但根據數據生成的結構需要組件的使用者來決定。games 數據在 Category 組件中,但使用數據所遍歷出來的結構由 App 組件決定)

  2. 具體編碼:

    父組件中

    <Category>
        <template scope="scopeData">
            <!-- 生成的是ul列表 -->
            <ul>
                <li v-for="g in scopeData.games" :key="g">{{g}}</li>
            </ul>
        </template>
    </Category>
    
    <Category>
        <template slot-scope="scopeData">
            <!-- 生成的是h4標題 -->
            <h4 v-for="g in scopeData.games" :key="g">{{g}}</h4>
        </template>
    </Category>
    

    子組件

    <template>
        <div>
            <slot :games="games"></slot>
        </div>
    </template>
    
    <script>
        export default {
            name:'Category',
            props:['title'],
            //數據在子組件自身
            data() {
                return {
                    games:['紅色警戒','穿越火線','勁舞團','超級瑪麗']
                }
            },
        }
    </script>
    

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 摘要:ForkJoin是由JDK1.7之後提供的多線程併發處理框架。 本文分享自華為雲社區《【高併發】什麼是ForkJoin?看這一篇就夠了!》,作者: 冰 河。 在JDK中,提供了這樣一種功能:它能夠將複雜的邏輯拆分成一個個簡單的邏輯來並行執行,待每個並行執行的邏輯執行完成後,再將各個結果進行彙總 ...
  • 牛客競賽傳送門: 本題鏈接:G-Fibonacci_第 45 屆國際大學生程式設計競賽(ICPC)亞洲區域賽(上海)(重現賽) (nowcoder.com) 比賽完整題單:牛客競賽_ACM/NOI/CSP/CCPC/ICPC演算法編程高難度練習賽_牛客競賽OJ (nowcoder.com) 通過率:7 ...
  • 1、引入依賴 spring-boot版本2.7.3,如未特殊說明版本預設使用此版本 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactI ...
  • 長連接與短連接 所謂長連接,指在一個TCP連接上可以連續發送多個數據包,在TCP連接保持期間,如果沒有數據包發送,需要雙方發檢測包以維持此連接,一般需要自己做線上維持。 短連接是指通信雙方有數據交互時,就建立一個TCP連接,數據發送完成後,則斷開此TCP連接,一般銀行都使用短連接。 比如http的, ...
  • NBA 2K23 Arcade Edition for Mac是一款深受歡迎的籃球游戲,NBA 2K23 街機版是世界著名的 NBA 2K 系列的最新作品,玩家在《NBA 2K23》中可以享受更身臨其境和超真實的NBA游戲體驗,享受現場解說員和色彩分析師的解說,喜歡的朋友們快來游戲中建立你的專屬王朝 ...
  • GreatSQL社區原創內容未經授權不得隨意使用,轉載請聯繫小編並註明來源。 GreatSQL是MySQL的國產分支版本,使用上與MySQL一致。 前文回顧 實現一個簡單的Database1(譯文) 實現一個簡單的Database2(譯文) 實現一個簡單的Database3(譯文) 實現一個簡單的D ...
  • 前言 本篇文章主要介紹的調用微信公眾號和小程式之後的開發流程,主要以實現步驟為主。 前提準備 已經申請了微信公眾號和小程式(由於官方文檔寫的很詳細,這裡就不在進行說明瞭); 微信公眾號和小程式的進行關聯了(主要是為了消息推送); 小程式的開發流程 提前註冊微信小程式,註冊地址:https://mp. ...
  • 因為工作需要,需要將Unity項目生成Android工程導入到Android Studio中,其中主要遇到的問題: 1.缺乏依賴包 2.依賴包重覆 有關問題1:詳細問題太多,這裡不贅述,可能涉及庫版本相容等問題,可自行百度解決。 有關問題2:這個問題也是本隨筆的主要問題,我遇到的主要是對於Volle ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...