vue2.0与vue3.0的区别,快速上手
1:vue3.0和2.0的区别
2.0数据双向绑定方面
Vue2.0使用Object.defineProperty
原理:通过使用 Object.defineProperty 来劫持对象属性的 geter 和 seter 操作,当数据发生改变发出通知
// 数据 let data = { title: '', // 备份数据 _data: {} } // 定义特性 Object.defineProperty(data, 'title', { // 定义特性属性或者特性方法 // 取值方法 get() { // console.log('get') // 注意:不能通过自身属性取值 // return this.title // 返回备份的数据 return this._data.title; }, // 赋值方法 set(value) { // this指向对象 // 注意:不能为自身属性赋值 // this.title = value // 我们可以向备份数据中存储 this._data.title = value; // console.log('set') // 更新视图 updateView(this._data) } }) // 视图模板 let tpl = document.getElementById('app').innerHTML // 实现更新视图的方法 function updateView(data) { // 处理模板 let html = tpl.replace(/{{(\w+)}}/g, (match, $1) => { // 从data中获取数据 return data[$1] || '' }) // 更新视图 document.getElementById('app').innerHTML = html; }
Vue3.0数据绑定
使用ES6的新特性porxy
原理:通过ES6的新特性proxy来劫持数据,当数据改变时发出通知
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="yingaxiang" content="width=device-width, initial-scale=1.0"> <title>vue3.0数据双向绑定</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就是第一个参数obj, receive就是返回的obj(返回的proxy对象) get: function (target, key, receive) { // 返回该属性值 return target[key]; }, set: function (target, key, newVal, receive) { // 执行赋值操作 target[key] = newVal; document.getElementById('text').innerHTML = target[key]; } }) document.addEventListener('keyup', function (e) { obj1[0] = e.target.value; }); </script>
总结:
Vue2.x版本中的双向绑定不能检测到下标的变化
proxy可以劫持整个对象,并返回一个新对象
2: 创建项目
未创建过vue脚手架得同学 或者从线上拉项目下来得同学 可以首先 查一下 当前版本
1:查看当前版本,如果是2开头说明当前使用的是vue-cli2,3开头的话就是vue-cli4
vue --version
vue -V
2:如果无法识别vue命令说明没有安装vue-cli,使用以下说明进行安装
安装3.0版本: 目前新项目搭建脚手架默认安装得是3.0版本
npm install -g vue-cli
如果是旧项目2.0版本到3.0切换得同学,即卸载当前版本,安装另外的版本
从2.0升级到3.0:
npm uninstall -g vue-cli
npm install -g @vue/cli
如果想从新版本降到旧版本得同学 看这里!!
从3.0降到2.0:
npm uninstall -g @vue/cli
npm install -g vue-cli
项目初始化
初始化,vue init <模板名称(webpack比较常用)> [项目名称]
vue init webpack cli2-test
2.0项目初始化参数介绍
//项目名称 Project name ... //作者的信息,会默认从git中读取信息 Project description ... Author ... //vue build的选项 1.runtime-compiler 2.runtime-only (一般选第一个就好) vue build ... //是否安装vue-router,一般选用YES,省去手动创建路由 Install vue-router? .. //是否使用ESLint检测代码规范,规范可根据选项选择不同的规范库或者自己添加规范 use ESLint to link your code //是否写单元测试 (一般不使用) Set up unit tests //是否使用Nightwatch来进行e2e测试 (2代表to e to e 点对点) Setup e2e test with Nightwatch? //使用npm或者yarn包管理工具 use npm use yarn
3.0初始化,vue create [项目名称]
vue create cli3-test
项目初始化参数介绍
//选择一个配置方式 please pick a perset (一般选最后一个Manually select features(手动选择特性) ) //选择对于你的工程所需要的特性 (用空格选择) check the features needed for your project ( ) Babel //转码器,可以将ES6代码转为ES5代码,从而在现有环境执行。 ( ) TypeScript// TypeScript是一个JavaScript(后缀.js)的超集(后缀.ts)包含并扩展了 JavaScript 的语法,需要被编译输出为 JavaScript在浏览器运行,目前较少人再用 ( ) Progressive Web App (PWA) Support// 渐进式Web应用程序 ( ) Router // vue-router(vue路由) ( ) Vuex // vuex(vue的状态管理模式) ( ) CSS Pre-processors // CSS 预处理器(如:less、sass) ( ) Linter / Formatter // 代码风格检查和格式化(如:ESlint) ( ) Unit Testing // 单元测试(unit tests) ( ) E2E Testing // e2e(end to end) 测试 //对应的配置文件单独生成还是放在package.json里 where do you prefer placing config for babel //要不要把刚才自己选择的配置保存下来 save this as a preset for future projects?
3:项目的目录
Vue2.0版本目录
Vue3.x 版本目录
总结:
vue-cli2.0与3.0在目录结构方面,有明显的不同
vue-cli3.0移除了配置文件目录,config 和 build 文件夹
同时移除了 static 静态文件夹,新增了 public 文件夹,打开层级目录还会发现, index.html 移动到 public 中
3.0 config文件已经被移除,但是多了.env.production和env.development文件,除了文件位置,实际配置起来和2.0没什么不同
没了config文件,跨域需要配置域名时,从config/index.js 挪到了vue.config.js中,配置方法不变
移除了 static 文件夹,新增 public 文件夹,并且 index.html 移动到 public 中
在 src 文件夹中新增了 views 文件夹,用于分类 视图组件 和 公共组件
4: 3.0版本中项目环境变量配置文件没有了(dev.env.js / prod.env.js)
我们可以通过在项目根目录下手动创建不同环境的配置文件,具体的环境变量名称由package.json中运行参数决定,下面举个例子添加development、production和uat版本的环境变量:
// .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
不同得环境发不同的包 同学要配置得可以参考
// package.json ---- "scripts": { "serve": "vue-cli-service serve", "build:uat": "vue-cli-service build --mode uat", // 通过 --mode来运行不同的环境,自动识别到.env.uat配置文件 "build:production": "vue-cli-service build --mode production", "lint": "vue-cli-service lint" },
3.0版本中不同环境的webpack配置文件也没有了(webpack.base.conf.js / webpack.dev.conf.js / webpack.prod.conf.js)
同样,我们也可以再根目录中创建vue.config.js文件来进行webpack和vue的一些配置
const path = require('path') module.exports = { publicPath: './', // 基本路径,打包时加上. outputDir: process.env.outputDir, // 输出文件目录 lintOnSave: false, // eslint-loader 是否在保存的时候检查 // 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') { // 为生产环境修改配置... config.mode = 'production' } else { // 为开发环境修改配置... config.mode = 'development' } Object.assign(config, { // 开发生产共同配置 resolve: { alias: { '@': path.resolve(__dirname, './src'), '@c': path.resolve(__dirname, './src/components'), '@p': path.resolve(__dirname, './src/views') } // 别名配置 } }) }, productionSourceMap: false, // 生产环境是否生成 sourceMap 文件 // css相关配置 css: { // extract: true, // 是否使用css分离插件 ExtractTextPlugin sourceMap: false, // 开启 CSS source maps? loaderOptions: { css: {}, // 这里的选项会传递给 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, // 换算的基数(设计图750的根字体为32) selectorBlackList: ['.van-'], // 要忽略的选择器并保留为px。 propList: ['*'], // 可以从px更改为rem的属性。 minPixelValue: 2 // 设置要替换的最小像素值。 }), require('autoprefixer') ] // plugins: [ // require('autoprefixer') // ] } // 这里的选项会传递给 postcss-loader }, // css预设器配置项 详见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。该选项在系统的 CPU 有多于一个内核时自动启用,仅作用于生产构建。 pwa: {}, // PWA 插件相关配置 see https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-pwa // webpack-dev-server 相关配置 devServer: { open: false, // 自动打开浏览器 host: '0.0.0.0', // 允许外部ip访问 port: 8000, // 端口 https: false, // 启用https overlay: { warnings: true, errors: true }, // 错误、警告在页面弹出 // proxy: 'http://localhost:4000' // 配置跨域处理,只有一个代理 proxy: { '/api': { target: '<url>', ws: true, changeOrigin: true }, '/foo': { target: '<other_url>' } }, // 配置多个代理 }, // 第三方插件配置 pluginOptions: {}
5:steup()函数 参考另一篇文章
https://blog.csdn.net/qq_41328247/article/details/109286022
6:2.0与3.0生命周期函数比较:
<template> <router-link to="/">点这里去首页</router-link> <hr> <div class="home"> 这里是一个计数器 >>> <span class="red">{{count}}</span> <br> <button @click="countAdd">点击加数字</button> </div> </template> <script> // 你需要使用到什么生命周期,就引出来什么生命周期 import { onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted, ref } from 'vue' export default { // setup 函数,就相当于 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 里面不要修改值,会死循环的哦! 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) }) // 定义一个函数,修改 count 的值。 const countAdd = () => { count.value++ } return { count, countAdd } } } </script>
首先,在 vue 3.0 中,生命周期是从 vue 中导出的,我们需要用到哪些,就导出哪些。
可能不少看官会认为多次一举,但实则不然。vue 提供这么多的生命周期,有几个是我们常用的?在大多数的组件中,我们用不到生命周期。即便是页面级别的应用,可能用到最多的是 onMounted 即可。
当然,那些绑定时间的操作会用到解绑,因此会用到 onUnmounted。其它的生命周期,正常情况下是基本用不到的。所以,通过引入使用的这种设定,可以减少我们的最终编译的项目的体积。而且,这样的引入使用,更加的逻辑清晰。
其次,除 setup 之外,其他的生命周期函数,都是在 setup 里面直接书写函数即可。
7.对文件的引用上
- Vue2.x中new出的实例对象,所有的东西都在这个vue对象上,这样其实无论你用到还是没用到,都会跑一变。
- vue3.0中可以用ES module imports按需引入,如:keep-alive内置组件、v-model指令,等等。
8.项目的启动
Vue2.x 版本启动
npm run dev
Vue3.x 版本启动
npm run serve
9.语法方面
1.v-model
语法糖废弃,改用 modelValue
<input v-model="value" /> <input modelValue="value" />
2.弃用全局API new Vue
,使用 createApp
const app = Vue.createApp({})
3.弃用Vue.prototype
,在Vue3中,我们可以使用如下定义方式
const app = Vue.createApp({})
app.config.globalProperties.$http = () => {}
4.全局方法现在全部在app实例上,例如:
`app.directive`,`app.use`等
5.现在你需要手动挂载根节点
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设置key。
8.正式弃用scopedSlots正式弃用,旧的不去新的不来。
9.监听数组变化需要使用deep属性,否则只能监听到整个数组被替换。
10.弃用$children,访问子组件可以使用$ref
11.filter被移除,我X,不能再使用|了。
12.移除事件API,$on,$once,$off不再使用。EventBus方法也不再使用。
10 新加入了 TypeScript 以及 PWA 的支持
11:更精准的变更通知
2.x 版本中,使用 Vue.set 来给对象新增一个属性时,这个对象的所有 watcher 都会重新运行
3.x 版本中,只有依赖那个属性的 watcher 才会重新运行。