2023-4-19 前端達(dá)人
Vue2.0使用Object.defineProperty
原理:通過使用 Object.defineProperty 來劫持對(duì)象屬性的 geter 和 seter 操作,當(dāng)數(shù)據(jù)發(fā)生改變發(fā)出通知
// 數(shù)據(jù) let data = { title: '', // 備份數(shù)據(jù) _data: {} } // 定義特性 Object.defineProperty(data, 'title', { // 定義特性屬性或者特性方法 // 取值方法 get() { // console.log('get') // 注意:不能通過自身屬性取值 // return this.title // 返回備份的數(shù)據(jù) return this._data.title; }, // 賦值方法 set(value) { // this指向?qū)ο? // 注意:不能為自身屬性賦值 // this.title = value // 我們可以向備份數(shù)據(jù)中存儲(chǔ) this._data.title = value; // console.log('set') // 更新視圖 updateView(this._data) } }) // 視圖模板 let tpl = document.getElementById('app').innerHTML // 實(shí)現(xiàn)更新視圖的方法 function updateView(data) { // 處理模板 let html = tpl.replace(/{{(w+)}}/g, (match, $1) => { // 從data中獲取數(shù)據(jù) return data[$1] || '' }) // 更新視圖 document.getElementById('app').innerHTML = html; }
使用ES6的新特性porxy
原理:通過ES6的新特性proxy來劫持?jǐn)?shù)據(jù),當(dāng)數(shù)據(jù)改變時(shí)發(fā)出通知
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="yingaxiang" content="width=device-width, initial-scale=1.0"> <title>vue3.0數(shù)據(jù)雙向綁定</title> </head> <body> <div> <input type="text" id="input"> <span id="text"></span> </div> </body> </html> <script> var obj = {}; var obj1 = new Proxy(obj, { // target就是第一個(gè)參數(shù)obj, receive就是返回的obj(返回的proxy對(duì)象) get: function (target, key, receive) { // 返回該屬性值 return target[key]; }, set: function (target, key, newVal, receive) { // 執(zhí)行賦值操作 target[key] = newVal; document.getElementById('text').innerHTML = target[key]; } }) document.addEventListener('keyup', function (e) { obj1[0] = e.target.value; }); </script>
總結(jié):
Vue2.x版本中的雙向綁定不能檢測(cè)到下標(biāo)的變化
proxy可以劫持整個(gè)對(duì)象,并返回一個(gè)新對(duì)象
未創(chuàng)建過vue腳手架得同學(xué) 或者從線上拉項(xiàng)目下來得同學(xué) 可以首先 查一下 當(dāng)前版本
1:查看當(dāng)前版本,如果是2開頭說明當(dāng)前使用的是vue-cli2,3開頭的話就是vue-cli4
vue --version
2:如果無法識(shí)別vue命令說明沒有安裝vue-cli,使用以下說明進(jìn)行安裝
安裝3.0版本: 目前新項(xiàng)目搭建腳手架默認(rèn)安裝得是3.0版本
npm install -g vue-cli
如果是舊項(xiàng)目2.0版本到3.0切換得同學(xué),即卸載當(dāng)前版本,安裝另外的版本
從2.0升級(jí)到3.0:
npm uninstall -g vue-cli
npm install -g @vue/cli
如果想從新版本降到舊版本得同學(xué) 看這里?。?
從3.0降到2.0:
npm uninstall -g @vue/cli
npm install -g vue-cli
項(xiàng)目初始化
初始化,vue init <模板名稱(webpack比較常用)> [項(xiàng)目名稱]
vue init webpack cli2-test
2.0項(xiàng)目初始化參數(shù)介紹
//項(xiàng)目名稱 Project name ... //作者的信息,會(huì)默認(rèn)從git中讀取信息 Project description ... Author ... //vue build的選項(xiàng) 1.runtime-compiler 2.runtime-only (一般選第一個(gè)就好) vue build ... //是否安裝vue-router,一般選用YES,省去手動(dòng)創(chuàng)建路由 Install vue-router? .. //是否使用ESLint檢測(cè)代碼規(guī)范,規(guī)范可根據(jù)選項(xiàng)選擇不同的規(guī)范庫(kù)或者自己添加規(guī)范 use ESLint to link your code //是否寫單元測(cè)試 (一般不使用) Set up unit tests //是否使用Nightwatch來進(jìn)行e2e測(cè)試 (2代表to e to e 點(diǎn)對(duì)點(diǎn)) Setup e2e test with Nightwatch? //使用npm或者yarn包管理工具 use npm use yarn
3.0初始化,vue create [項(xiàng)目名稱]
vue create cli3-test ?項(xiàng)目初始化參數(shù)介紹 //選擇一個(gè)配置方式 please pick a perset (一般選最后一個(gè)Manually select features(手動(dòng)選擇特性) ) //選擇對(duì)于你的工程所需要的特性 (用空格選擇) check the features needed for your project ( ) Babel //轉(zhuǎn)碼器,可以將ES6代碼轉(zhuǎn)為ES5代碼,從而在現(xiàn)有環(huán)境執(zhí)行。 ( ) TypeScript// TypeScript是一個(gè)JavaScript(后綴.js)的超集(后綴.ts)包含并擴(kuò)展了 JavaScript 的語法,需要被編譯輸出為 JavaScript在瀏覽器運(yùn)行,目前較少人再用 ( ) Progressive Web App (PWA) Support// 漸進(jìn)式Web應(yīng)用程序 ( ) Router // vue-router(vue路由) ( ) Vuex // vuex(vue的狀態(tài)管理模式) ( ) CSS Pre-processors // CSS 預(yù)處理器(如:less、sass) ( ) Linter / Formatter // 代碼風(fēng)格檢查和格式化(如:ESlint) ( ) Unit Testing // 單元測(cè)試(unit tests) ( ) E2E Testing // e2e(end to end) 測(cè)試 //對(duì)應(yīng)的配置文件單獨(dú)生成還是放在package.json里 where do you prefer placing config for babel //要不要把剛才自己選擇的配置保存下來 save this as a preset for future projects?
總結(jié):
我們可以通過在項(xiàng)目根目錄下手動(dòng)創(chuàng)建不同環(huán)境的配置文件,具體的環(huán)境變量名稱由package.json中運(yùn)行參數(shù)決定,下面舉個(gè)例子添加development、production和uat版本的環(huán)境變量:
// .env.delelopment NODE_ENV=development VUE_APP_MODE=development BASE_URL=/develop // .env.production NODE_ENV=production VUE_APP_MODE=production BASE_URL=/api // .env.uat NODE_ENV=production VUE_APP_MODE=uat BASE_URL=/uat 不同得環(huán)境發(fā)不同的包 同學(xué)要配置得可以參考 // package.json ---- "scripts": { "serve": "vue-cli-service serve", "build:uat": "vue-cli-service build --mode uat", // 通過 --mode來運(yùn)行不同的環(huán)境,自動(dòng)識(shí)別到.env.uat配置文件 "build:production": "vue-cli-service build --mode production", "lint": "vue-cli-service lint" },
3.0版本中不同環(huán)境的webpack配置文件也沒有了(webpack.base.conf.js / webpack.dev.conf.js / webpack.prod.conf.js)
同樣,我們也可以再根目錄中創(chuàng)建vue.config.js文件來進(jìn)行webpack和vue的一些配置
const path = require('path') module.exports = { publicPath: './', // 基本路徑,打包時(shí)加上. outputDir: process.env.outputDir, // 輸出文件目錄 lintOnSave: false, // eslint-loader 是否在保存的時(shí)候檢查 // see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md // webpack配置 chainWebpack: (config) => { config.resolve.symlinks(true) }, configureWebpack: (config) => { if (process.env.VUE_APP_MODE === 'production') { // 為生產(chǎn)環(huán)境修改配置... config.mode = 'production' } else { // 為開發(fā)環(huán)境修改配置... config.mode = 'development' } Object.assign(config, { // 開發(fā)生產(chǎn)共同配置 resolve: { alias: { '@': path.resolve(__dirname, './src'), '@c': path.resolve(__dirname, './src/components'), '@p': path.resolve(__dirname, './src/views') } // 別名配置 } }) }, productionSourceMap: false, // 生產(chǎn)環(huán)境是否生成 sourceMap 文件 // css相關(guān)配置 css: { // extract: true, // 是否使用css分離插件 ExtractTextPlugin sourceMap: false, // 開啟 CSS source maps? loaderOptions: { css: {}, // 這里的選項(xiàng)會(huì)傳遞給 css-loader less: { modifyVars: { // less vars,customize ant design theme // 'primary-color': '#F5222D', // 'link-color': '#F5222D', // 'border-radius-base': '4px' }, // DO NOT REMOVE THIS LINE javascriptEnabled: true }, postcss: { plugins: [ // 把px單位換算成rem單位 require('postcss-pxtorem')({ rootValue: 75, // 換算的基數(shù)(設(shè)計(jì)圖750的根字體為32) selectorBlackList: ['.van-'], // 要忽略的選擇器并保留為px。 propList: ['*'], // 可以從px更改為rem的屬性。 minPixelValue: 2 // 設(shè)置要替換的最小像素值。 }), require('autoprefixer') ] // plugins: [ // require('autoprefixer') // ] } // 這里的選項(xiàng)會(huì)傳遞給 postcss-loader }, // css預(yù)設(shè)器配置項(xiàng) 詳見https://cli.vuejs.org/zh/config/#css-loaderoptions // modules: false, // 啟用 CSS modules for all css / pre-processor files. requireModuleExtension: true }, parallel: require('os').cpus().length > 1, // 是否為 Babel 或 TypeScript 使用 thread-loader。該選項(xiàng)在系統(tǒng)的 CPU 有多于一個(gè)內(nèi)核時(shí)自動(dòng)啟用,僅作用于生產(chǎn)構(gòu)建。 pwa: {}, // PWA 插件相關(guān)配置 see https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-pwa // webpack-dev-server 相關(guān)配置 devServer: { open: false, // 自動(dòng)打開瀏覽器 host: '0.0.0.0', // 允許外部ip訪問 port: 8000, // 端口 https: false, // 啟用https overlay: { warnings: true, errors: true }, // 錯(cuò)誤、警告在頁面彈出 // proxy: 'http://localhost:4000' // 配置跨域處理,只有一個(gè)代理 proxy: { '/api': { target: '<url>', ws: true, changeOrigin: true }, '/foo': { target: '<other_url>' } }, // 配置多個(gè)代理 }, // 第三方插件配置 pluginOptions: {}
https://blog.csdn.net/qq_41328247/article/details/109286022
2.0 周期名稱
3.0 周期名稱
說明
beforeCreate
setup
組件創(chuàng)建之前
created
setup
組件創(chuàng)建完成
beforeMount
onBeforeMount
組件掛載之前
mounted
onMounted
組件掛載完成
beforeUpdate
onBeforeUpdate
數(shù)據(jù)更新,虛擬 DOM 打補(bǔ)丁之前
updated
onUpdated
數(shù)據(jù)更新,虛擬 DOM 渲染完成
beforeDestroy
onBeforeUnmount
組件銷毀之前
destroyed
onUnmounted
組件銷毀后
<template> <router-link to="/">點(diǎn)這里去首頁</router-link> <hr> <div class="home"> 這里是一個(gè)計(jì)數(shù)器 >>> <span class="red">{{count}}</span> <br> <button @click="countAdd">點(diǎn)擊加數(shù)字</button> </div> </template> <script> // 你需要使用到什么生命周期,就引出來什么生命周期 import { onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted, ref } from 'vue' export default { // setup 函數(shù),就相當(dāng)于 vue 2.0 中的 created setup () { const count = ref(0) // 其他的生命周期都寫在這里 onBeforeMount (() => { count.value++ console.log('onBeforeMount', count.value) }) onMounted (() => { count.value++ console.log('onMounted', count.value) }) // 注意,onBeforeUpdate 和 onUpdated 里面不要修改值,會(huì)死循環(huán)的哦! onBeforeUpdate (() => { console.log('onBeforeUpdate', count.value) }) onUpdated (() => { console.log('onUpdated', count.value) }) onBeforeUnmount (() => { count.value++ console.log('onBeforeUnmount', count.value) }) onUnmounted (() => { count.value++ console.log('onUnmounted', count.value) }) // 定義一個(gè)函數(shù),修改 count 的值。 const countAdd = () => { count.value++ } return { count, countAdd } } } </script> 首先,在 vue 3.0 中,生命周期是從 vue 中導(dǎo)出的,我們需要用到哪些,就導(dǎo)出哪些。
可能不少看官會(huì)認(rèn)為多次一舉,但實(shí)則不然。vue 提供這么多的生命周期,有幾個(gè)是我們常用的?在大多數(shù)的組件中,我們用不到生命周期。即便是頁面級(jí)別的應(yīng)用,可能用到最多的是 onMounted 即可。
當(dāng)然,那些綁定時(shí)間的操作會(huì)用到解綁,因此會(huì)用到 onUnmounted。其它的生命周期,正常情況下是基本用不到的。所以,通過引入使用的這種設(shè)定,可以減少我們的最終編譯的項(xiàng)目的體積。而且,這樣的引入使用,更加的邏輯清晰。
其次,除 setup 之外,其他的生命周期函數(shù),都是在 setup 里面直接書寫函數(shù)即可。
Vue2.x 版本啟動(dòng)
npm run dev
Vue3.x 版本啟動(dòng)
npm run serve
1.v-model
語法糖廢棄,改用modelValue
<input v-model="value" />
<input modelValue="value" />
2.棄用全局APInew Vue
,使用createApp
const app =?Vue.createApp({})
3.棄用Vue.prototype
,在Vue3中,我們可以使用如下定義方式
const app = Vue.createApp({})
app.config.globalProperties.$http = () => {}
4.全局方法現(xiàn)在全部在app實(shí)例上,例如:
`app.directive`,`app.use`等
5.現(xiàn)在你需要手動(dòng)掛載根節(jié)點(diǎn)
main.js
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
6.不能再使用Vue.nextTick
/this.$nextTick
,Vue3中你可以用:
import { nextTick } from 'vue'
nextTick(() => {
// something
})
7.Vue3允許template
設(shè)置key
。
8.正式棄用scopedSlots
正式棄用,舊的不去新的不來。
9.監(jiān)聽數(shù)組變化需要使用deep
屬性,否則只能監(jiān)聽到整個(gè)數(shù)組被替換。
10.棄用$children
,訪問子組件可以使用$ref
11.filter
被移除,我X,不能再使用|
了。
12.移除事件API,$on
,$once
,$off
不再使用。EventBus
方法也不再使用。
2.x 版本中,使用 Vue.set 來給對(duì)象新增一個(gè)屬性時(shí),這個(gè)對(duì)象的所有 watcher 都會(huì)重新運(yùn)行
3.x 版本中,只有依賴那個(gè)屬性的 watcher 才會(huì)重新運(yùn)行。
藍(lán)藍(lán)設(shè)計(jì)的小編 http://sillybuy.com