VUE 學(xué)習(xí)筆記

vue 學(xué)習(xí)

1. 組件基礎(chǔ)

1.1 什么是組件

組件是可以服用的 vue 實(shí)例坎背,說(shuō)白了是一組可以重復(fù)使用的模板。組件里面可以套用組件。

//定義組件
//使用Vue.component來(lái)定義組件
Vue.component("my-component-li",{
    template: "<li>這是一個(gè)名為my-component-li的組件</li>"
})

//組件定義好了钮孵,引用組件
<div>
    <ul>
        <my-component-li v-for="item in items" v-bind:item="item"></my-component-li> //1
    </ul>
</div>
//但是上面的方法只是把li 顯示出來(lái)戈泼,一般li 是需要做列表渲染的婿禽,也就是要把數(shù)據(jù)傳進(jìn)去的,所以需要做一些改動(dòng)
//1.要把data數(shù)據(jù)里的數(shù)組渲染到 li 里大猛,先給 li 組件綁定 v-for 循環(huán)扭倾。
//2.然后把 item替換到li里
<script>
    //定義組件
    Vue.component("my-component-li",{
        props:["item"],//這里是把 template 里的 item 關(guān)聯(lián)上了,為了把item 跟<my-component-li v-for="item in items"></my-component-li> 這里的 item 關(guān)聯(lián)挽绩,需要用到 v-bind:item 方法
        template:"<li>{{item}}</li>"http://2
    })
    var app = new Vue({
        //掛載元素 
        el:"#app",
        data:{
         items:['衛(wèi)青','霍去病','張騫']
    }
       
    })
</script>

2. 前端膛壹,服務(wù)器和數(shù)據(jù)庫(kù)

[圖片上傳失敗...(image-3a922-1656668459121)]

解釋:前端可以是 vue 等框架,服務(wù)器可以是由 node 搭建的也可以是 node 的框架 express唉堪,數(shù)據(jù)庫(kù)使用 MySQL

3 vue 從零開(kāi)始一個(gè)項(xiàng)目

3.1 安裝 vue

安裝 vue 的方法有四種

  • 在頁(yè)面上以 CDN 引入

    <script src="https://unpkg.com/vue@next"></script>
    
  • 下載 javascript 文件并自行托管

    即下載 vue 的 .js 文件然后放到自己的工程文件中模聋,然后在項(xiàng)目中去引用。

  • 使用 npm 安裝它

    npm 為你和你的團(tuán)隊(duì)打開(kāi)了連接整個(gè) JavaScript 天才世界的一扇大門(mén)唠亚。它是世界上最大的軟件注冊(cè)表链方,每星期大約有 30 億次的下載量,包含超過(guò) 600000 個(gè) 包(package) (即代碼模塊)灶搜。來(lái)自各大洲的開(kāi)源軟件開(kāi)發(fā)者使用 npm 互相分享和借鑒祟蚀。包的結(jié)構(gòu)使您能夠輕松跟蹤依賴項(xiàng)和版本工窍。
    
    下面是關(guān)于 npm 的快速介紹:
    
    npm 由三個(gè)獨(dú)立的部分組成:
    
    網(wǎng)站
    注冊(cè)表(registry)
    命令行工具 (CLI)
    網(wǎng)站 是開(kāi)發(fā)者查找包(package)、設(shè)置參數(shù)以及管理 npm 使用體驗(yàn)的主要途徑前酿。
    
    注冊(cè)表 是一個(gè)巨大的數(shù)據(jù)庫(kù)患雏,保存了每個(gè)包(package)的信息。
    
    CLI 通過(guò)命令行或終端運(yùn)行薪者。開(kāi)發(fā)者通過(guò) CLI 與 npm 打交道纵苛。
    
  • 使用 vue 腳手架 CLI 來(lái)構(gòu)建它。推薦使用 vue 腳手架言津。

    Vue 提供了一個(gè)官方的 CLI攻人,為單頁(yè)面應(yīng)用 (SPA) 快速搭建繁雜的腳手架。它為現(xiàn)代前端工作流提供了功能齊備的構(gòu)建設(shè)置悬槽。只需要幾分鐘的時(shí)間就可以運(yùn)行起來(lái)并帶有熱重載怀吻、保存時(shí) lint 校驗(yàn),以及生產(chǎn)環(huán)境可用的構(gòu)建版本初婆。更多詳情可查閱 Vue CLI 的文檔
    

3.1.1 使用 vue-cli 創(chuàng)建項(xiàng)目

  • 安裝 node.js 使用 vue-cli 必須先安裝 node

  • 安裝 vue cli

    npm install -g @vue/cli
    
  • 創(chuàng)建項(xiàng)目名

    vue create 項(xiàng)目名
    
  • 根據(jù)提示進(jìn)行選擇

ps. 因?yàn)?npm 的包的下載速度很慢蓬坡,可以使用淘寶的鏡像資源 cnpm 來(lái)加快速度:

npm install -g cnpm --registry=https://registry.npm.taobao.org
使用 npm 去安裝 cnpm

當(dāng)項(xiàng)目使用 vue create 項(xiàng)目名并且選擇配置完成以后會(huì)自動(dòng)生成一些文件

cd 項(xiàng)目名 // 進(jìn)入項(xiàng)目中
npm run serve 啟動(dòng)項(xiàng)目
  App running at:
  - Local:   http://localhost:8080/
  - Network: http://192.168.31.146:8080/
  即項(xiàng)目啟動(dòng)成功

[圖片上傳失敗...(image-974b78-1656668459121)]

img

[圖片上傳失敗...(image-27abf5-1656668459121)]

方法和計(jì)算屬性

方法定義在
methods(){
    方法體
}
computed:{
    計(jì)算屬性
}
兩個(gè)使用中非常相似,不同點(diǎn)是計(jì)算屬性是靜態(tài)的磅叛。相當(dāng)于把計(jì)算結(jié)果緩存起來(lái)成為靜態(tài)的屬性屑咳,避免系統(tǒng)開(kāi)銷

4. mysql

mysql 環(huán)境變量配置了以后可以直接用 cmd 去啟動(dòng) mysql

mysql -uroot -p
//連接的命令
如果不配置環(huán)境變量,則每次需要進(jìn)入到 mysql 的安裝文件的bin目錄的去啟動(dòng)弊琴,本機(jī)的安裝目錄是 C:\Program Files\MySQL\MySQL Server 8.0\bin 
即兆龙,如果沒(méi)有配置環(huán)境變量,則需要在 cmd 中輸入 cd C:\Program Files\MySQL\MySQL Server 8.0\bin 進(jìn)入到這個(gè)目錄中再鏈接數(shù)據(jù)庫(kù)敲董。

本數(shù)據(jù)庫(kù)的賬戶密碼都是 root

5. node.js

5.1 創(chuàng)建一個(gè)經(jīng)典的服務(wù)器

  1. 創(chuàng)建空文件夾 nodejsdemo

  2. 初始化 npm init

  3. 在文件目錄中看到主入口文件是 index.js, 所以創(chuàng)建 index.js

  4. [圖片上傳失敗...(image-1d4eff-1656668459121)]

  5. 在 index.js 中寫(xiě)入 console.log(1234), 終端輸入node index.js 運(yùn)行輸出 1234說(shuō)明 node 運(yùn)行了 index.js

  6. 這樣一個(gè)簡(jiǎn)單的服務(wù)器就做好了

    
    // setServers
    
    const http = require("http"); // require 引入模塊的方法紫皇,http 是一個(gè)默認(rèn)的模塊,所以可以直接寫(xiě)不用再?gòu)牡谌揭?const hostname = "127.0.0.1"; //定義本地地址(服務(wù)器地址)
    const port = 3000; //定義端口號(hào)
    
    //http有createServer 方法(接受參數(shù)腋寨,req 為請(qǐng)求參數(shù)聪铺,res 為響應(yīng)參數(shù))
    var server = http.createServer((req,res)=>{
        res.statusCode = 200;
        res.setHeader("Content-type","text/plain")
        res.write("hello node")
        res.end()
    });
    
    //server 啟動(dòng)以后使用listion 方法去看是否啟動(dòng)成功
    server.listen(port, hostname, ()=>{
        console.log("服務(wù)器已啟動(dòng)");
    })
    
    • nodemon 自動(dòng)重新啟動(dòng)項(xiàng)目
      • 先全局安裝 npm i nodemon -g
      • 然后在 package.json 文件里添加 “serve”:nodemon index.js

    5.2 node中的 http 模塊

    1. http 服務(wù)端

      • 在服務(wù)端使用

      • 請(qǐng)求對(duì)象(IncomingMessage類的實(shí)例)和相應(yīng)對(duì)象(ServerResponse類的實(shí)例)

    2. http客戶端

      • 客戶端使用(request, get)
      • 請(qǐng)求對(duì)象(ClientRequest類的實(shí)例)和相應(yīng)對(duì)象(IncomingMessage類的實(shí)例)

    5.3 node 的其他模塊(看文檔)

    • Buffer 模塊
    • url 模塊
    • fs 模塊
    • crypto模塊
    • path模塊
    • 模板引擎

6. express.js

基于 node.js 的極簡(jiǎn),快速萄窜,開(kāi)放的 web 開(kāi)發(fā)框架铃剔。exprss 和 node 的關(guān)系就如同 jQuery 和 js 的關(guān)系。

6.1 express 安裝

  • npm init 初始化文件

  • 安裝 express 并將其保存在依賴列表中

    npm install express //因?yàn)閑xpress 是第三方的庫(kù)查刻,所以要安裝才能使用
    
  • 安裝完成進(jìn)入 hello wold 頁(yè)面

    const express = require("express"); //引入express模塊
    var app=express(); //express 函數(shù)運(yùn)行以后賦值給 app键兜。 app 即是應(yīng)用對(duì)象
    
    //使用get方法
    app.get("/",function(req,res){
        res.send("hello express")
    })
    
    //使用 liston方法監(jiān)聽(tīng)
    app.listen(3000,function(){
        console.log("運(yùn)行環(huán)境")
    })
    
  • 代碼賦值到 index.js(如果在 package.jason文件中改了入口文件,那么就需要運(yùn)行改動(dòng)后的文件赖阻。index.js 是默認(rèn)的入口文件), node 運(yùn)行 index.js

  • 瀏覽器中運(yùn)行 localhost:3000

6.2 請(qǐng)求本地的 json 數(shù)據(jù)

module.expors={
    "name":"zhangsan",
    "age":20
}
//module.exports 意思是當(dāng)我們創(chuàng)建了一個(gè) data的js 文件以后蝶押,我們要把這個(gè)文件暴露出去,這樣別的程序可以訪問(wèn)的到

6.3 靜態(tài)資源

為了提供如圖片火欧,js棋电,css文件之類的靜態(tài)資源茎截,使用 express 中的中間件 express.static.

例如,圖片放在 static 文件加下面赶盔,我們?nèi)绻褂眠@些靜態(tài)資源則使用

app.use(express.static("static"))企锌,那么 static 文件夾里的文件就對(duì)外開(kāi)放了。

app.use(express.static("",))

6.4 路由

路由的目的于未,上面的所有g(shù)et/put/path等接口都寫(xiě)在了主文件 mian.js里撕攒,這樣太亂了,為了把這些接口函數(shù)放到一個(gè)專門(mén)的地方烘浦,所以引入了路由的概念抖坪。

  • 創(chuàng)建一個(gè)文件夾 route
  • 在文件夾里創(chuàng)建文件 index.js 文件

7. 鏈接 mysql

  • 現(xiàn)在終端安裝mysql

    npm install mysql
    
  • 在路由文件去引入 mysql

var mysql = require(mysql)

8. dos 命令

  • cd xx 進(jìn)入到哪個(gè)文件
  • cd ../ or cd.. 進(jìn)入上一個(gè)文件夾
  • cls 清除

實(shí)戰(zhàn)項(xiàng)目

  1. 安裝 node 搭建后臺(tái) (略)

  2. 搭建后臺(tái)項(xiàng)目

    1. cmd 輸入 npm init 初始化項(xiàng)目。 (npm init -y 快速初始化項(xiàng)目)
    2. 初始化成功后將在項(xiàng)目里出現(xiàn) package.json 文件
    3. 創(chuàng)建與入口文件同名的文件js
    4. 新增項(xiàng)目啟動(dòng)命令
    5. nodemon: 自動(dòng)重啟項(xiàng)目當(dāng)code內(nèi)容改變以后
      npm i nodemon -g
      然后在 package.json 文件里添加 “serve”:nodemon index.js
    
  3. package.json 字段解釋

    "dependencies": 項(xiàng)目依賴
    "devDependencies":開(kāi)發(fā)依賴(只在開(kāi)發(fā)的時(shí)候會(huì)用闷叉,項(xiàng)目打包上線的時(shí)候擦俐,這個(gè)部分不會(huì)被打包)
    "name": "expressdemo", 項(xiàng)目名稱
    "version": "1.0.0", 項(xiàng)目版本
    "description": "", 項(xiàng)目描述
    "main": "main.js" 項(xiàng)目的入口文件
    
  4. 如果 npm 比較滿,安裝一下淘寶鏡像 cnpm

  5. 安裝并使用 koa + koa-router

    koa 基于 node.js 的下一代 web 開(kāi)發(fā)框架握侧。

    koa 是新的框架由 express 原班人馬打造蚯瞧,致力于成為 web 應(yīng)用和 api 開(kāi)發(fā)的更小的,更富有表現(xiàn)力的基石品擎。

    koa 建立在 es6+ 之上埋合,提升現(xiàn)代的 js 語(yǔ)法。

    使用 generators 和 async / await

    優(yōu)雅萄传,簡(jiǎn)潔甚颂,靈活,體積小

    相關(guān)名利 npm - koa -s, npm - koa-router -s

//入口文件的基本設(shè)置

//1. 引入 koa 
const Koa = require("koa");

//2. 實(shí)例化 koa
const App = new Koa();

//3. 搭建服務(wù)
App.use(async ctx=>{
    ctx.body = "荊承鵬學(xué)習(xí)前端";
})

//4. 監(jiān)聽(tīng)端口
App.listen(5000, ()=>{
    console.log("服務(wù)器啟動(dòng)成功:5000")
})

// nodemon index.js 啟動(dòng)服務(wù) http://localhost:5000 可以訪問(wèn)

// 這個(gè)時(shí)候有個(gè)問(wèn)題盲再,上面的無(wú)法指定特定的 api 端口西设,比如 http://localhost:5000/index瓣铣, http://localhost:5000/index1 是不同的路徑答朋,這個(gè)時(shí)候就需要 koa-router

// 安裝 koa-router : npm i koa-router -s
  1. 引入 koa-router 以后需要做的

    //1. 引入 koa 
    const Koa = require("koa");
    const Router = require("koa-router");
    
    //2. 實(shí)例化 koa
    const App = new Koa();
    const router = new Router();
    
    //3. 搭建服務(wù)
    // App.use(async ctx=>{
    //     ctx.body = "荊承鵬學(xué)習(xí)前端";
    // })
    // 使用 koa-router 來(lái)啟動(dòng)服務(wù),并且可以指定不同的路徑
    
    router.get("/index", async ctx=>{
        ctx.status = 200;
        ctx.body = "荊承鵬學(xué)習(xí)前端koa-router";
    })
    
    router.get("/index1", async ctx=>{
        ctx.status = 200;
        ctx.body = "月薪過(guò)萬(wàn)不是夢(mèng)"
    })
    
    //配置路由
    // 調(diào)用router.routes()來(lái)組裝匹配好的路由棠笑,返回一個(gè)合并好的中間件
    // 調(diào)用router.allowedMethods()獲得一個(gè)中間件梦碗,當(dāng)發(fā)送了不符合的請(qǐng)求時(shí),會(huì)返回 `405 Method Not Allowed` 或 `501 Not Implemented`
    App.use(router.routes());
    App.use(router.allowedMethods());
    
    
    
    //4. 監(jiān)聽(tīng)端口
    App.listen(5000, ()=>{
        console.log("服務(wù)器啟動(dòng)成功:5000")
    })
    
  1. 搭建數(shù)據(jù)庫(kù)環(huán)境 (安裝 mysql 略)

  2. 安裝 Navicat premium (mysql 的圖形管理系統(tǒng))

  3. 編寫(xiě)后臺(tái)接口

    使用 node 連接 sql 數(shù)據(jù)庫(kù)
    安裝依賴
     數(shù)據(jù)庫(kù) npm i mysql -s
     跨域 npm i koa2-cors -s 
     獲取body 請(qǐng)求參數(shù) npm i koa-bodyparser -s
    封裝 bd.js: 對(duì)鏈接數(shù)據(jù)庫(kù)的函數(shù)進(jìn)行模塊封裝
    編寫(xiě)接口:接口 koa-router+mysql編寫(xiě)接口
    測(cè)試接口:使用 vscode 中postman 插件進(jìn)行接口測(cè)試
    
    bd.js 內(nèi)容
    // 引入 bd.js 作為數(shù)據(jù)庫(kù)的鏈接文件
    // 引入 mysql
    const mysql = require("mysql");
    
    //聲明變量用來(lái)存儲(chǔ)數(shù)據(jù)庫(kù)綁定連接以后的對(duì)象屬性
    
    const poolSql = mysql.createPool({
        host: "localhost",
        user:"root",
        password:"root",
        port: "3306",
        database:"test"
    
    }) 
    
    function query(sql, value){
        return new Promise((resolve,reject)=>{
            poolSql.query(sql,value, (err,result)=>{
                if(err){
                    reject(err)
                }else{
                    resolve(result)
                }
            })
        })
    }
    
    module.exports = query;
    

    入口頁(yè)面 index.js 內(nèi)容

    //1. 引入 koa 
    const Koa = require("koa");
    const Router = require("koa-router");
    const Pool = require("mysql/lib/Pool");
    //引入bd.js 里的模塊
    const poopSql = require("./bd.js");
    const cors = require("koa2-cors"); //跨域
    const bodyparser = require("koa-bodyparser");//body 參數(shù)
    
    //2. 實(shí)例化 koa
    const App = new Koa();
    const router = new Router();
    
    //3. 搭建服務(wù)
    // App.use(async ctx=>{
    //     ctx.body = "荊承鵬學(xué)習(xí)前端";
    // })
    // 使用 koa-router 來(lái)啟動(dòng)服務(wù)蓖救,并且可以指定不同的路徑
    
    router.get("/index", async ctx=>{
        ctx.status = 200;
        ctx.body = "荊承鵬學(xué)習(xí)前端koa-router";
    })
    
    router.get("/query", async ctx=>{
        ctx.status = 200;
        try {
            let _sql = "SELECT * FROM t_user";
            let _data = await poopSql(_sql);
            ctx.body = {
                errorMessage : "",
                result:true,
                data: _data
            }
        } catch (error) {
            ctx.body = {
                errorMessage : "查詢失敗",
                result:false,
                data: null
            }
        }
    })
    
    //配置路由
    // 調(diào)用router.routes()來(lái)組裝匹配好的路由洪规,返回一個(gè)合并好的中間件
    // 調(diào)用router.allowedMethods()獲得一個(gè)中間件,當(dāng)發(fā)送了不符合的請(qǐng)求時(shí)循捺,會(huì)返回 `405 Method Not Allowed` 或 `501 Not Implemented`
    App.use(router.routes());
    App.use(router.allowedMethods());
    App.use(cors());
    App.use(bodyparser());
    
    
    //4. 監(jiān)聽(tīng)端口
    App.listen(5000, ()=>{
        console.log("服務(wù)器啟動(dòng)成功:5000")
    })
    
  1. 查詢斩例,添加,修改从橘,刪除數(shù)據(jù)庫(kù)字段的寫(xiě)法

    // bd.js
    //1. 引入 koa 
    const Koa = require("koa");
    const bodyparser = require("koa-bodyparser");//body 參數(shù)
    const Router = require("koa-router");
    const Pool = require("mysql/lib/Pool");
    //引入bd.js 里的模塊
    const poolSql = require("./bd.js");
    const cors = require("koa2-cors"); //跨域
    
    
    //2. 實(shí)例化 koa
    const App = new Koa();
    const router = new Router();
    
    //3. 搭建服務(wù)
    // App.use(async ctx=>{
    //     ctx.body = "荊承鵬學(xué)習(xí)前端";
    // })
    // 使用 koa-router 來(lái)啟動(dòng)服務(wù)念赶,并且可以指定不同的路徑
    
    router.get("/index", async ctx => {
        ctx.status = 200;
        ctx.body = "荊承鵬學(xué)習(xí)前端koa-router";
    })
    
    //查詢數(shù)據(jù)庫(kù)
    router.get("/query", async ctx => {
        ctx.status = 200;
        try {
            let _sql = "SELECT * FROM t_user";
            let _data = await poolSql(_sql);
            ctx.body = {
                errorMessage: "",
                result: true,
                data: _data
            }
        } catch (error) {
            ctx.body = {
                errorMessage: "查詢失敗",
                result: false,
                data: null
            }
        }
    })
    //向數(shù)據(jù)庫(kù)表中添加信息
    router.post("/add", async ctx => {
        ctx.status = 200;
        let _info = ctx.request.body; //上下文request 里的 body 的內(nèi)容賦給 _info
    
        //表中username 是必填項(xiàng)础钠,所以先判斷一下
        if(!_info.name){
            ctx.body = {
                errorMessage:"name 是必填項(xiàng)目",
                result:false,
                data:null
            }
            return
        }
        try {
            let _sql = "INSERT INTO demo (id,name,number,price) VALUES (?,?,?,?)";
            let _value = [_info.id,_info.name, _info.number, _info.price];
            await poolSql(_sql,_value);
            ctx.body = {
                errorMessage: "",
                result: true,
                data: null
            }
        } catch (error) {
            ctx.body = {
                errorMessage: "添加失敗",
                result: false,
                data: null
            }
        }
    })
    //向數(shù)據(jù)庫(kù)表中修改信息
    router.put("/put", async ctx=>{
        ctx.status = 200;
        let _info = ctx.request.body;
        if(!_info.id){
            ctx.body = {
                errorMessage:"id 是必填項(xiàng)目",
                result:false,
                data:null
            }
            return
        }else if(!_info.name){
            ctx.body = {
                errorMessage:"name 是必填項(xiàng)目",
                result:false,
                data:null
            }
            return
        }
        try{
            let _sql = "UPDATE demo SET name=?,number=?,price=? WHERE id=?";
            let _value = [_info.name, _info.number, _info.price,_info.id];
            await poolSql(_sql, _value);
            ctx.body = {
                errorMessage: "",
                result: true,
                data: null
            }
        }catch(err){
            ctx.body = {
                errorMessage: "修改失敗",
                result: false,
                data: null
            }
        }
    
    })
    //刪除數(shù)據(jù)庫(kù)中的數(shù)據(jù),通過(guò)路徑傳參的方式
    router.delete("/delete/:id", async ctx=>{
        ctx.status = 200;
        console.log(ctx);
        let _info = ctx.params;
        try{
            let _sql = "DELETE FROM demo WHERE id=?";
            let _value = [_info.id];
            await poolSql(_sql,_value);
            ctx.body ={
                errorMessage: "",
                result: true,
                data: null
            }
        }catch(err){
            ctx.body = {
                errorMessage:"刪除錯(cuò)誤",
                result:false,
                data:null
            }
        }
    })
    
    
    //配置路由
    // 調(diào)用router.routes()來(lái)組裝匹配好的路由叉谜,返回一個(gè)合并好的中間件
    // 調(diào)用router.allowedMethods()獲得一個(gè)中間件旗吁,當(dāng)發(fā)送了不符合的請(qǐng)求時(shí),會(huì)返回 `405 Method Not Allowed` 或 `501 Not Implemented`
    App.use(cors()).use(bodyparser()).use(router.routes()).use(router.allowedMethods());
    
    
    
    //4. 監(jiān)聽(tīng)端口
    App.listen(5000, () => {
        console.log("服務(wù)器啟動(dòng)成功:5000")
    })
    
  1. 搭建前端框架

    使用 vue3 + vite 搭建項(xiàng)目

    此步驟以前的都是服務(wù)器端的設(shè)置停局,項(xiàng)目里新建文件夾把服務(wù)器端的項(xiàng)目文件命名為 server 然后在這個(gè)項(xiàng)目里開(kāi)始搭建前端很钓。

    $ npm create vite@latest // 快速搭建一個(gè)項(xiàng)目
    

    Vue3 基礎(chǔ) api

    - defineComponent
    這是對(duì) setup 函數(shù)進(jìn)行封裝,返回 options 的對(duì)象董栽,主要就是為了服務(wù) ts 而存在的码倦。
    - ref
    接受一個(gè)內(nèi)部值返回一個(gè)響應(yīng)式可變的 ref 對(duì)象。 ref 對(duì)象具有指向內(nèi)部值的單個(gè) property.value
    - reactive
    與 ref 類似锭碳,不同的是它用來(lái)定義更為復(fù)雜的數(shù)據(jù)類型
    - toRefs
    將響應(yīng)式對(duì)象轉(zhuǎn)為普通對(duì)象叹洲,其中結(jié)果對(duì)象的每個(gè) property 都指向原始對(duì)象對(duì)應(yīng)的 property 的 ref
    - toRaw
    只是對(duì)原生數(shù)據(jù)進(jìn)行修改,不改變更新 ui 視圖
    - setup 函數(shù)
    這個(gè)函數(shù)主要是為了使用組合式 api工禾,使用setup函數(shù)時(shí)候运提,有兩個(gè)參數(shù)
    props: 可以從中獲取組件的 props 參數(shù),他是響應(yīng)式的闻葵,也就是傳入新的 prop 時(shí)候民泵,它被更新;
    context: context是一個(gè)普通的 JavaScript對(duì)象槽畔,暴露了其他可能在 setup 中有用的值栈妆。這些值就是之前 vue2中 this 上暴露的 property 屬性,比如 attrs, slots, emit
    注意:在setup() 中, this 不是該活躍實(shí)例的引用厢钧。
    

引用 ant design vue

npm install ant-design-vue --save

當(dāng)前端界面完成鳞尔,開(kāi)始前端和聯(lián)調(diào)

使用 axios 封裝 api

axios 是一個(gè)基于 promise 的 http 庫(kù),可以在瀏覽器和node.js 中使用早直。

它符合現(xiàn)在的 mvvm 浪潮寥假。

vue筆記

1. vue 零碎的知識(shí)點(diǎn)

-Vue中有兩種數(shù)據(jù)綁定,v-band 和 v-module
1. 單向數(shù)據(jù)綁定 v-band:xxx 簡(jiǎn)寫(xiě):xxx; 數(shù)據(jù)只能從 data 流向頁(yè)面霞扬。
2. 雙向數(shù)據(jù)綁定 v-model:xxx 簡(jiǎn)寫(xiě)為 v-model = ""

  • el 和 data 的兩種寫(xiě)法
    1. el的兩種寫(xiě)法
      (1) new Vue 時(shí)候配置el 的屬性
      (2)先創(chuàng)建實(shí)例子糕韧,然后通過(guò)$monunt("掛載")
    2. data的兩種寫(xiě)法:對(duì)象式,函數(shù)式
      (1)對(duì)象式 data:{
      //寫(xiě)入data 的值喻圃,可以直接用在模板中
      }
      (2)函數(shù)式寫(xiě)法 data(){
      return {
      //寫(xiě)入data 的值萤彩,可以直接用在模板中
      }
      }
      在實(shí)際的項(xiàng)目中,主要謝函數(shù)式
      上面是這個(gè)的變形寫(xiě)法 data:function(){
      return {
      //寫(xiě)入data 的值斧拍,可以直接用在模板中
      }
      }
    3. 一個(gè)重要的原則:由 Vue 管理的函數(shù)一定不要寫(xiě)箭頭函數(shù)雀扶,一旦寫(xiě)了箭頭函數(shù) this 的指向就不再是 Vue 了。

2. mvvm 模型

MVVM 模型肆汹,細(xì)說(shuō)其實(shí)是 M-V-VM 模型
M (model:指的是 data 中的數(shù)據(jù))
V (view) 視圖:模板代碼愚墓,即顯示在頁(yè)面中的內(nèi)容
VM (ViewModel) 視圖模型窍侧,即 Vue 實(shí)例所做的事情

發(fā)現(xiàn):1: data 中所有數(shù)據(jù)都出現(xiàn)在了 vm 身上;vm身上所有屬性转绷,包括從原型鏈上繼承來(lái)的都可以直接使用在模板中直接使用伟件。

3. vue2 數(shù)據(jù)雙向綁定的原理

Object.defineProperty() 實(shí)現(xiàn)數(shù)據(jù)代理

  1. vue中的數(shù)據(jù)代理
    通過(guò)vm對(duì)象來(lái)代理data對(duì)象中的屬性的操作(讀/寫(xiě))
  2. vue中的數(shù)據(jù)代理的好處
    更加方便的操作data中的數(shù)據(jù)
  3. 基本原理
    • 通過(guò)Object.defineProperty()把data中的對(duì)象所有屬性添加到vm上。
    • 為每個(gè)添加到vm的屬性议经,都指定一個(gè)getter/setter.
    • 在getter/setter內(nèi)部去操作(讀/寫(xiě))data中對(duì)應(yīng)的的屬性

4. 事件處理

  1. 使用v-on:xxx或者@xxx綁定事件斧账,其中xxx是事件名稱;
  2. 事件回調(diào)需要配置在methods對(duì)象中煞肾,最終會(huì)在vm上咧织;
  3. methods中配置的函數(shù),不要用箭頭函數(shù)籍救,否則this就不是vm了习绢;
  4. methods中配置的函數(shù),都是被vue所管理的函數(shù)蝙昙,this的指向是vm或者組件實(shí)例對(duì)象闪萄;
  5. @lick="demo"和@lick="demo($event)"效果一致,但是后者可以傳參奇颠。

5. 事件修飾符

描述:就是修飾事件的

  1. prevent:阻止默認(rèn)事件(常用)
  2. stop:阻止事件冒泡(常用)
  3. once:事件只觸發(fā)一次(常用)
  4. capture:使用事件的捕獲模式
  5. self:只有event.target是當(dāng)前操作的元素時(shí)才觸發(fā)事件
  6. passive:事件的默認(rèn)行為立即執(zhí)行败去,不用等事件回調(diào)執(zhí)行完畢。
    案例:@click.once="showMe",這個(gè)事件只執(zhí)行一次烈拒;@click.prevent="showMe"阻止事件的默認(rèn)行為圆裕,比如在 a 標(biāo)簽上添加此修飾符,在點(diǎn)擊a標(biāo)簽以后荆几,執(zhí)行showMe函數(shù)吓妆,a標(biāo)簽的跳轉(zhuǎn)行為不執(zhí)行。
  7. 修飾符可以連續(xù)寫(xiě)

6. 鍵盤(pán)事件

  1. vue中常用的按鍵別名:

    • 回車 => enter
    • 刪除 => delete (捕獲刪除和退格鍵)
    • 退出 => esc
    • 空格 => space
    • 換行 => tab
    • 上 => up
    • 下 => down
    • 左 => left
    • 右 => right
  2. vue未提供別名的按鍵吨铸,可以使用按鍵原始的key值去綁定行拢,但是要注意轉(zhuǎn)換為kebab-case(短橫線命名)

  3. 系統(tǒng)修飾鍵(用法特殊):ctrl, alt, shift, meta

    • 配合keyup使用:按下修飾鍵的同時(shí),再按其他鍵釋放后觸發(fā);
    • 配合keydown使用:正常觸發(fā)事件焊傅。
  4. 也可以使用keycode去指定具體的案件(不推薦)

  5. Vue.config.keycodes.自定義按鍵名 = 鍵碼剂陡,可以去定制按鍵別名狈涮。

  6. 案例:@keyup.enter="showMe" (鍵盤(pán)的按鍵輸入enter鍵狐胎,在按鍵升起的時(shí)候觸發(fā))「桠桑或者@keydown.enter="showMe" (鍵盤(pán)的按鍵輸入enter鍵握巢,在按鍵按下的時(shí)候觸發(fā))。

7. 內(nèi)置指令

  1. v-bind:單向綁定解析表達(dá)式松却,可以簡(jiǎn)寫(xiě)為:xxx

  2. v-model:雙向數(shù)據(jù)綁定

  3. v-for:遍歷數(shù)據(jù)暴浦、對(duì)象溅话、字符串

  4. v-on:綁定事件監(jiān)聽(tīng),簡(jiǎn)寫(xiě)為@xxx

  5. v-if:條件渲染(動(dòng)態(tài)控制節(jié)點(diǎn)是否存在)

  6. v-show:條件渲染(動(dòng)態(tài)控制節(jié)點(diǎn)是否展示)

  7. v-else:條件渲染(動(dòng)態(tài)控制節(jié)點(diǎn)是否存在)

  8. v-text:向所在節(jié)點(diǎn)中添加渲染文本內(nèi)容歌焦;與插值語(yǔ)法區(qū)別:v-text會(huì)替換掉節(jié)點(diǎn)中的內(nèi)容飞几,{{xxx}}則不會(huì)。

  9. v-html

    • 作用:向指定節(jié)點(diǎn)中渲染包含html結(jié)構(gòu)的內(nèi)容独撇;
    • 與插值語(yǔ)法的區(qū)別:v-html會(huì)替換掉節(jié)點(diǎn)中所有的內(nèi)容屑墨,{{xxx}}不會(huì)
    • 嚴(yán)重注意:v-html有安全性問(wèn)題。在網(wǎng)站上動(dòng)態(tài)渲染任意html是非常危險(xiǎn)的纷铣,容易導(dǎo)致xss攻擊
    • 一定要在可信的內(nèi)容上使用v-html,永遠(yuǎn)不要用在用戶輸入上卵史。
  10. v-once

    • v-once所在節(jié)點(diǎn)在初次動(dòng)態(tài)渲染后,就視為靜態(tài)內(nèi)容了搜立。
    • 以后數(shù)據(jù)的改變不會(huì)引起v-once所在結(jié)構(gòu)的更新以躯,可以用于優(yōu)化性能。
  11. v-pre

    • 跳過(guò)其所在節(jié)點(diǎn)的編譯過(guò)程
    • 可用它跳過(guò)沒(méi)有使用指令語(yǔ)法啄踊,沒(méi)有使用插值語(yǔ)法的節(jié)點(diǎn)忧设,會(huì)加快編譯
  12. v-cloak: v-cloak(沒(méi)有值)

- 本質(zhì)是一個(gè)特殊屬性,vue實(shí)例創(chuàng)建完畢并接管容器以后會(huì)刪除v-cloak的屬性
- 使用css配合v-cloak可以解決網(wǎng)速慢時(shí)頁(yè)面展示出插值語(yǔ)法的問(wèn)題颠通。

8. 自定義指令

  1. 定義語(yǔ)法
    • 局部指令:
new Vue({
    directives:{指令名稱:配置對(duì)象}
})
或者
new Vue({
    directives:{指令名:回調(diào)函數(shù)}
})
- 全局指令
Vue.directive(指令名见转,配置對(duì)象)或者Vue.directive(指令名,回調(diào)函數(shù))
  1. 配置對(duì)象中的常用的三個(gè)回調(diào)

    • .bind:指令與元素成功綁定是調(diào)用
    • .inserted:指令所在元素被插入頁(yè)面時(shí)調(diào)用
    • .updated:指令所在模板結(jié)構(gòu)被重新解析時(shí)調(diào)用
  2. 備注:

    • 指令定義時(shí)不加v-蒜哀,但是使用時(shí)需要加v-
    • 指令名如果是多個(gè)單詞斩箫,要使用連字符鏈接,不要用駝峰命名

9. 計(jì)算屬性

  1. 定義:要用的屬性不存在撵儿,需要通過(guò)已有屬性計(jì)算而來(lái)乘客。
  2. 原理:底層借助了Object.defineProperty()方法提供的getter和setter
  3. get函數(shù)什么時(shí)候執(zhí)行?
    • 初次讀取的時(shí)候會(huì)運(yùn)行一次淀歇;
    • 當(dāng)依賴的數(shù)據(jù)發(fā)生變化時(shí)會(huì)被再次調(diào)用易核。
  4. 優(yōu)勢(shì):與methods相比,內(nèi)部有緩存機(jī)制(復(fù)用)浪默,效率更高牡直,測(cè)試方便
  5. 備注:計(jì)算屬性會(huì)最終出現(xiàn)在 vm 上,直接讀取使用即可纳决;如果計(jì)算屬性要被修改碰逸,那必須寫(xiě)set函數(shù)去相應(yīng)修改,且set中要引起計(jì)算時(shí)依賴的數(shù)據(jù)發(fā)生改變阔加。

10. 監(jiān)視屬性 watch

  1. 當(dāng)被監(jiān)視的屬性發(fā)生變化時(shí)饵史,回調(diào)函數(shù)自動(dòng)調(diào)用,進(jìn)行相關(guān)操作。
  2. 監(jiān)視屬性必須存在胳喷,才能進(jìn)行監(jiān)視
  3. 監(jiān)視的兩種寫(xiě)法:
    • new Vue 時(shí)傳入 watch 配置
    • 通過(guò)vm.$watch("",{})監(jiān)視

11.條件渲染

  1. v-in
    • 寫(xiě)法:v-if湃番、v-else-if,v-else
    • 適用于切換頻率較低的場(chǎng)景
    • 特點(diǎn):不展現(xiàn) dom節(jié)點(diǎn)。dom直接被移除
    • 注意:v-if可以和v-else-if,v-else 一起使用吭露,但是要求結(jié)構(gòu)不能被打斷吠撮。
  2. v-show
    • 寫(xiě)法:v-show
    • 適用于切換場(chǎng)景較高的場(chǎng)景
    • 不展示dom,但是dom被隱藏
  3. 備注:使用v-if時(shí)讲竿,元素可能無(wú)法獲取到纬向,而是用v-show的時(shí)候時(shí)可以獲取到的

12 v-for 指令

  1. 用于展示列表信息
  2. 語(yǔ)法:v-for="(item, index) in xxx" :key="yyy"
  3. 可以遍歷:數(shù)組,對(duì)象戴卜,字符串(用的少)逾条,指定次數(shù)(用的少)

12. 面試題 react,vue中key的作用(key的內(nèi)部原理)

  1. 虛擬 dom 中 key 的作用:key是虛擬dom對(duì)象的標(biāo)識(shí)投剥,當(dāng)數(shù)據(jù)發(fā)生變化時(shí)师脂,vue會(huì)根據(jù)新數(shù)據(jù)生成新的虛擬dom,隨后vue進(jìn)行新虛擬dom與舊虛擬dom的差異比較江锨,比較規(guī)則如下:
    • 舊虛擬dom用到了與新dom相同的key:
      (1)若虛擬dom中內(nèi)容沒(méi)有變化吃警,直接復(fù)用之前的真是dom;
      (2)虛擬dom內(nèi)容變化了啄育,則生成新的真實(shí)dom酌心,隨后替換掉頁(yè)面中舊的真實(shí)dom
    • 舊虛擬dom沒(méi)有找到與新虛擬dom相同的key:創(chuàng)建新的真實(shí)dom,然后渲染到頁(yè)面上挑豌;
  2. 用 index 作為key可能會(huì)引發(fā)的問(wèn)題
    • 若對(duì)數(shù)據(jù)進(jìn)行逆序添加安券,逆序刪除等破壞順序的操作,會(huì)產(chǎn)生沒(méi)有必要的真實(shí)dom更新 ---> 頁(yè)面沒(méi)有問(wèn)題氓英,但是效率低侯勉。
    • 如果結(jié)構(gòu)中還包含輸入類的dom,會(huì)產(chǎn)生錯(cuò)誤的dom更新 --> 界面會(huì)有問(wèn)題
  3. 開(kāi)發(fā)中如何選擇key
    • 最好使用每條數(shù)據(jù)唯一的標(biāo)識(shí)作為key铝阐,比如id址貌,手機(jī)號(hào),身份證號(hào)等徘键。
    • 如果不存在對(duì)數(shù)據(jù)的逆序添加练对,逆序刪除等破壞順序的操作,僅用于渲染列表的展示吹害,使用index作為key是沒(méi)有問(wèn)題的螟凭。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市赠制,隨后出現(xiàn)的幾起案子赂摆,更是在濱河造成了極大的恐慌挟憔,老刑警劉巖钟些,帶你破解...
    沈念sama閱讀 212,294評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件烟号,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡政恍,警方通過(guò)查閱死者的電腦和手機(jī)汪拥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,493評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)篙耗,“玉大人迫筑,你說(shuō)我怎么就攤上這事∽谕洌” “怎么了脯燃?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,790評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)蒙保。 經(jīng)常有香客問(wèn)我辕棚,道長(zhǎng),這世上最難降的妖魔是什么邓厕? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,595評(píng)論 1 284
  • 正文 為了忘掉前任逝嚎,我火速辦了婚禮,結(jié)果婚禮上详恼,老公的妹妹穿的比我還像新娘补君。我一直安慰自己,他們只是感情好昧互,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,718評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布挽铁。 她就那樣靜靜地躺著,像睡著了一般敞掘。 火紅的嫁衣襯著肌膚如雪屿储。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,906評(píng)論 1 290
  • 那天渐逃,我揣著相機(jī)與錄音够掠,去河邊找鬼。 笑死茄菊,一個(gè)胖子當(dāng)著我的面吹牛疯潭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播面殖,決...
    沈念sama閱讀 39,053評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼竖哩,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了脊僚?” 一聲冷哼從身側(cè)響起相叁,我...
    開(kāi)封第一講書(shū)人閱讀 37,797評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤遵绰,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后增淹,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體椿访,經(jīng)...
    沈念sama閱讀 44,250評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,570評(píng)論 2 327
  • 正文 我和宋清朗相戀三年虑润,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了成玫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,711評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡拳喻,死狀恐怖哭当,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情冗澈,我是刑警寧澤钦勘,帶...
    沈念sama閱讀 34,388評(píng)論 4 332
  • 正文 年R本政府宣布,位于F島的核電站亚亲,受9級(jí)特大地震影響彻采,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜朵栖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,018評(píng)論 3 316
  • 文/蒙蒙 一颊亮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧陨溅,春花似錦终惑、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,796評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至臼寄,卻和暖如春霸奕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背吉拳。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,023評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工质帅, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人留攒。 一個(gè)月前我還...
    沈念sama閱讀 46,461評(píng)論 2 360
  • 正文 我出身青樓煤惩,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親炼邀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子魄揉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,595評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容