Vue是用于创建用户界面的开源JavaScript框架,也是创建单页应用的Web应用框架;用于构建用户界面的渐进式框架,是目前三大主流的框架之一。Vue观众MVC当中的视图层,能更好的获取到组件的数据状态,通过组件内的方法进行视图和模型之间的更新。

Vue2和Vue3de 区别

1、数据监听响应式的区别

Vue2使用Object.defineProperty来实现数据和视图之间的实时更新,通过劫持对象属性的 geterseter,在数据发生变化的时候发出通知

Vue3使用ES6的新特性Porxy来劫持数据,当数据改变时发出通知。消除了Vue2在新对象属性的增加、直接修改数组元素 不会触发响应式机制

Porxy单独为IE浏览器做了适配,解决了Vue在IE不能运行的弊端。

2、项目初始化

Vue2:vue init <模板名称(webpack)> [项目名称]

vue init webpack test

Vue3:vue create [项目名称]

vue create test

3、根节点支持

Vue2仅支持单个根节点

Vue3取消了限制,可支持多个节点共存

4、对TypeScript的支持

vue2:不适合使用ts,vue2是Option API(选项API)风格。options是个简单对象,而ts是一种类型系统、面向对象的语法。

vue3:打造了defineComponent(组合API)函数,使组件在ts下,可以更好的利用参数类型推断

5、创建方法

Vue2

export default {
    props: {
        title: String
    },
    data () {
        return {
            a: '',
            b: ''
        }
    },
    methods: {
        c() {
            
        }
    }
}

Vue3

export default {
    props: {
        title: String
    },
    setup () {
        const state = reactive({
            a: '',
            b: ''
        })
        const c= () => {
            
        }
        return {
            c,
            state
        }
    }
}

在组合API中,我们需要将生命周期钩子导入到项目中,才能使用

// 组合 API
import { onMounted } from 'vue'

6、生命周期

Vue2的周期函数

  • beforeCreate
  • create
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • beforeDestroy
  • destroyed
  • errorCaptured

Vue3除了beforeCreate和create方法被setup()代替,Vue3还有如下周期函数

  • onBeforeMount ,挂在开始前被调用
  • onMonuted,挂载时调用
  • onBeforeUpdate,数据更新时调用,适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器
  • onUpdated,数据更改导致的虚拟 DOM 重新渲染
  • onBeforeUnmounted,卸载组件实例之前调用
  • onUnmounted,卸载组件实例后调用
  • onActivated,缓存(keep-alive )的组件激活时调用
  • onDeactivated, 缓存的组件(keep-alive )停用时调用
  • onErrorCaprured

7、文件目录

Vue3中不在包含(webpack.base.conf.js/webpack.dev.conf.js/webpack.prod.conf.js),我们可以在根目录中设置vue.config.js来进行webpack的一些配置

import path from 'path';
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import styleImport from 'vite-plugin-style-import';
import visualizer from 'rollup-plugin-visualizer';
const envConfig = require('./proxy.config');

const NODE_ENV = process.env.NODE_ENV || 'development';
const PORT = process.env.PORT || 10002;
const proxy = process.env.proxy;
const isDev = NODE_ENV === 'development'; // build mode: development

const apiProxy = envConfig.getApiProxy();

const plugins = [
  vueJsx({
    // options are passed on to @vue/babel-plugin-jsx
  }),
  styleImport({
    libs: [
      {
        libraryName: 'vant',
        esModule: true,
        resolveStyle: (name) => {
          return `vant/es/${name}/style/index`;
        },
      },
      {
        libraryName: 'ant-design-vue',
        esModule: true,
        resolveStyle: (name) => {
          return `ant-design-vue/es/${name}/style/css`;
        },
      },
    ],
  }),
  vue(),
];

if (process.env.NODE_ENV === 'production') {
  // 打包依赖展示
  plugins.push(
    visualizer({
      open: true,
      gzipSize: true,
      brotliSize: true,
    })
  );
}

const config = {
  plugins,
  /**
   * 在生产中服务时的基本公共路径。
   * @default '/'
   */
  base: '',
  /**
   * 与“根”相关的目录,构建输出将放在其中。如果目录存在,它将在构建之前被删除。
   * @default 'dist'
   */
  outDir: 'assets',
  emitManifest: true,
  // 引入第三方的配置
  optimizeDeps: {
    include: ['axios'],
    exclude: ['koa2', 'koa-body', 'autoprefixer', 'koa-static-cache', '@vue/server-renderer', 'vue-style-loader'],
    esbuildOptions: {
      keepNames: false,
    },
  },
  resolve: {
    alias: {
      // vite中alias必须以斜线开头和结尾,暂时未知原因,这样其实挺不方便的
      // 所以在eslint配置alias和文件中导入路径也要相应的修改
      '~': path.resolve(__dirname, './src'),
    },
  },
  //这里注意,键名是scss不是sass!一字之差能让你折腾好久
  css: {
    preprocessorOptions: {
      scss: {
        // 自动导入全局样式
        // globalScss: "@import '~/styles/index.scss';",
        javascriptEnabled: true,
      },
    },
  },
  define: {
    __client__: true,
    __dev__: isDev,
    __local_proxy__: !!proxy,
  },
  build: {
    // target: 'modules', // browsers with native ES module support.
    outDir: `dist`,
    assetsDir: '',
    emptyOutDir: true,
    brotliSize: false, // 禁用 brotli 压缩大小报告
    // sourcemap: true,
    rollupOptions: {
      output: {
        manualChunks: {
          lodash: ['lodash'],
          // vant: ['vant'],
          // antd: ['ant-design-vue'],
        },
      },
    },
  },
  server: {
    port: PORT,
    cors: true,
    // 是否自动在浏览器打开
    open: false,
    // 是否开启 https
    https: false,
    // 服务端渲染
    ssr: false,
    proxy: apiProxy
      ? {
          // 如果是 /api 打头,则访问地址如下
          '/api': apiProxy,
          '/service': apiProxy,
        }
      : {},
  },
};

export default defineConfig(config);

8、父子传参

Vue2中父组件使用:xxx来向子组件传递参数

<insureinfo-module :form-data="params.policyHolderInfoDto" />

 子组件通过props来接受

export default {
	props :{
		//数据
		formData : {
			type : Object,
			default(){
				return {
					name : '',
					identifyNumber : '',
					phone : ''
				}
			}
		},
	}
}

 Vue3父传子和Vue2传值方式一样 ,Vue3接受参数的方式成为了

//父传子
<OrderItem v-for="item in list" :key="item" :detail="item"
</OrderItem>

子组件通过setup函数接受父组件传递的参数,可以通过toRefs、ref来解构参数,引用方法前需要引入 

//子接受,通过setup函数接受
import { reactive, defineComponent, toRefs, onMounted } from 'vue';
import FetchSpanWithColor from '~/modules-pc/components/FetchSpanWithColor.vue';
export default defineComponent({
  name: 'OrderItem',
  props: {
    detail: {
      type: Object,
      required: true,
    },
    keyList: {
      type: Array
    }
  },
  components: { FetchSpanWithColor },
  setup(props, context) {
    return { StatusOpts, StatusColorList };
  },
});

子传父,事件

Vue2如果监听子组件返回的参数,定义方式是@aa="test"的方式,在父组件中定义test方法,获取子组件传回的数据

//父
<ensure-module @input="getPlanPremium" />

getPlanPremium(val, premium, productCode) {
	this.params.premium = premium
	this.perPremium = premium
	this.$set(this.params, 'productCode', productCode)
	if(this.userFormData.insured[0].staffCount != '') {
		this.params.premium = premium * this.userFormData.insured[0].staffCount
	}
}

子组件

//子组件通过$emit方法通知父组件
this.$emit('input', val, this.planPremium, this.planProductCode);

Vue3中父组件接受和Vue2中的保持一致,子组件回传的方式改变。通过setup函数中的context来触发emit方法,Vue3不在提供this

import { defineComponent, toRefs, computed } from 'vue';
export default defineComponent({
    props: {
       hideCheck: {
         type: Boolean,
         default: false,
       },
       checked: {
         type: Boolean,
       },
    },
    emits: ['change'],
    setup(props, context) {
        context.emit('change', value)
    }
)}

 持续更新中...

Logo

前往低代码交流专区

更多推荐