技海泛舟(个人技术研究)

  • 首页
  • 日积月累
  • 学习计划
  • 随想
  • project
  • 关于
技海泛舟
一个技术宅的博客
  1. 首页
  2. 日积月累
  3. vue
  4. 正文

vue2、vue3对比学习

2022年6月13日 1083点热度

创建 vue3 项目,基于 vite

npm init @vitejs/app appname
npm install vue-router@4

vue3 基于 webpack 改 vite

1、复制 scr 目录
2、复制 package.json 中的 dependencies
3、npm i 安装依赖,并 npm run dev 修改 bug

vue2 基于 webpack 改 vite

1、复制 scr 目录
2、复制 package.json 中的 dependencies
3、npm i 安装依赖,
4、安装报错的 npm install @vue/compiler-sfc vue-template-compiler -S 和 npm install vite-plugin-vue2 -D
5、vite.config.js 修改

import { defineConfig } from 'vite'
import {createVuePlugin} from 'vite-plugin-vue2'

export default {
  plugins: {
    createVuePlugin()
  }
}

5、npm run dev 修改路径、router 等 bug

vue2 和 vue3 区别

vue2 采用 Object.defineProperty(),1、不能监听数组的变化,2、必须遍历对象每一个属性
vue3 采用 proxy, 不需要遍历对象每一个属性。

vue3

ref() 基本类型

reactive() 对象

setup 语法糖插件:unplugin-auto-import 解决场景:在组件开发中无需每次都手动引入

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";

import AutoImport from "unplugin-auto-import/vite";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue(), AutoImport({ imports: ["vue", "vue-router"] })], // 自动导入vue和vue-router相关函数
});

toRefs 用于 解构对象、数组时 保持响应状态。

obj=Reactive{
  name:'san',
  sex:1
}
return {
  ...toRefs(obj)
}

computed,可以用get()\set()

let msg = ref("sdfsfsere fs");
let msgchange = computed(() => {
  return msg.value.slice(1, 3);
});
return {
  msg,
  msgchange,
};

watch

// vue2
<template>
  <div><input type="text" name="" v-model="msg">{{msg}}</div>
</template>
<script>
export default {
  data() {
    return {
      msg:'hello',
      obj: {
        a:1
      }
    }
  },
  watch: {
  msg(newVal,oldVal) {
    console.log(newVal,oldVal)
  },
  obj: {
    handler(newVal,oldVal) {
      console.log(newVal,oldVal)
    },
    immediate: true,  // 获取初始化的值
    deep:true   // 深度获取
  }
}
}
</script>
// vue3 
<template>
  <div><input type="text" name="" v-model="msg">{{msg}}</div>
  <div><input type="text" name="" v-model="str">{{str}}</div>
</template>
<script setup>
export default {
  setup() {

    let msg = ref("hello");
    let str = ref("oo")
    let obj= reactive({
      a:2,
      arr:['a','b','c']
    })
    // 方式一,单独监听
    watch(msg,(newVal,oldVal) {
      console.log(newVal,oldVal)
    },{immediate:true})                 // hello,undefined
    // 方式二,监听多个值,一起监听
    watch([msg,str],(newVal,oldVal) {
      console.log(newVal,oldVal)
    },{immediate:true})  
    //  监听对象的  某个属性             
    watch(()=>obj.arr,(newVal,oldVal) {
      console.log(newVal,oldVal)
    },{immediate:true})                 

    return {
      msg
    }
  }
}
</script>

组合监听

const nums = ref(9)
const demo = reactive({
    name: '前端小玖',
    nickName: '小玖',
    soulmate: {
        name: '',
        nickName: ''
    }
})

什么是组合监听呢?举个例子,比如我想同时监听 demo 对象的 name 属性,和基础类型 nums,只要他们其中任何一个发生变更,那么就触发 watch 方法。

watch([() => demo.name, nums], ([newName, newNums], [oldName, oldNums]) => {
    console.log('watch 已触发: name', newName)
    console.log('watch 已触发: nums', newNums)
})

注意,此时的第一个参数是一个数组,且第二参数箭头函数的参数也是数组的形式。

路由

useRoute => this.route
useRouter => this.router

import { useRouter } from 'vue-router';
let router = useRouter()
  let go =()=> {
    router.push('/about')
  }
// 导航守卫
router.beforeEach((to, from, next) => {
  if (to.name !== "Login" && !isAuthenticated) next({ name: "Login" });
  else next();
});

组件传值 父传子

vue2、vue3通用方式

//  father
<template>
<div>
<div>
 <span>父组件数据</span>
  <input v-model="msg"/>
 </div>
这是父组件,htmlz中需要用kebab-case命名,字符串模板没有这一限制
<Son :for-child-msg="msg"></Son>  
</div>
</template>
<script>
import Son from '../components/Son.vue'
export default {
  components: {
    Son
  },
  data() {
    return {
      msg:'这是父传给子的数据'
    }
  }

}
</script>
// Son
<template>
<div>
这是son组件
{{msg}}
</div>
</template>
<script>
export default {
  props:{'forChildMsg':String}
  data() {
    return {
      ownChildMsg:this.forChildMsg
    }
  },
  watch: {
    forChildMsg() {
      this.ownChildMsg = this.forChildMsg
    }
  }
}
</script>

修改 props 数据

1.定义一个局部变量,并用 prop 的值初始化它,只有默认值传递给了 ownChildMsg,父组件改变只会变化到 forChildMsg,不会修改 ownChildMsg。

  props: {
    "for-child-msg": String
  },
  data() {
    return { ownChildMsg: this.forChildMsg };
  }
  ```
2. 定义一个计算属性,处理 prop 的值并返回
  ```js 
props: {
    "for-child-msg": String
  },
  computed: {
    ownChildMsg() {
      return this.forChildMsg + "---ownChildMsg";
    }
  }
  ```
3. 最推荐的方式是使用变量存储 prop 的初始值,并用 watch 来观察 prop 值得变化。发生变化时,更新变量的值。
   ```js 
  props: {
    "for-child-msg": String
  },
  data() {
    return {
      ownChildMsg: this.forChildMsg
    };
  },
  watch: {
    forChildMsg() {
      this.ownChildMsg = this.forChildMsg;
    }
  }
   ```
#### vue3 方式一 setup语法糖方式
```js
//  father
<template>
<div>
<div>
 <span>父组件数据</span>
  <input v-model="msg"/>
 </div>
这是父组件,htmlz中需要用kebab-case命名,字符串模板没有这一限制
<Son :for-child-msg="msg"></Son>  
</div>
</template>
<script setup>
  import Son from '../components/Son.vue'
  let msg = ref('这是父传给子的数据')
</script></code></pre>
<pre><code class="language-js">// Son
<template>
<div>
这是son组件
{{msg}}
</div>
</template>
<script setup>
import {defineProps} from 'vue'
const props = defineProps({
'forChildMsg':{type:String,default:"111"}
})
const {forChildMsg:msg} = toRefs(props)  // 重命名解构
}
</script>
</code></pre>
<h4>vue3 方式二 setup props接受</h4>
<pre><code class="language-js"><script lang="ts">
import { toRefs } from 'vue'
interface Data {
    [key:string]:unknown
}
export default {
    props:{
        text:{
            type:String,
            default:""
        },
        message:Number
    },
    setup(props:Data){
        const {text} = toRefs(props)
        const formatText = <code>Hi,${text.value}</code>
        return {
            formatText
        }
    }
}
</script></code></pre>
<h3>组件 子传父</h3>
<h4>vue2子传父</h4>
<pre><code class="language-js">// Son
<template>
<div>
这是son组件
{{ownChildMsg}}
<button @click="toFatherMsg">自定义子传父</button>
</div>
</template>
<script>
export default {
  data() {
    return {
      ownChildMsg:1111
    }
  },
  methods: {
    toFatherMsg() {
      this.$emit('fn',this.forChildMsg) 
    }
  }
}</code></pre>
<p>```js
//  father
<template>
<div>
<div>
<span>父组件数据</span>
<input v-model="msg"/>
</div>
这是父组件,htmlz中需要用kebab-case命名,字符串模板没有这一限制
<Son :for-child-msg="msg" @fn="changeMsg"></Son><br />
</div>
</template>
<script>
import Son from &#039;../components/Son.vue&#039;
export default {
components: {
Son
},
data() {
return {
msg:&#039;这是子传给父的数据&#039;
}
},
methods: {
changeMsg(value) {
console.log(value)  // 子组件传过的的值“1111”
this.msg = value
}
}
}</p>
<pre><code>####  vue3子传父 方式一  setup api
```js
// Son
<template>
<div>
这是son组件
{{ownChildMsg}}
</div>
<button @click="toFatherMsg">自定义子传父</button>
</template>
<script>
export default {
  data() {
    return {
      ownChildMsg:1111
    }
  },
  setup(props,{emit}) {
    let ownChildMsg = ref(100);
    const toFatherMsg = () => {
      emit('fn',toFatherMsg)
    }
  }
}
//  father
<template>
<div>
<div>
 <span>父组件数据</span>
  <input v-model="msg"/>
 </div>
这是父组件,htmlz中需要用kebab-case命名,字符串模板没有这一限制
<Son :for-child-msg="msg" @fn="changeMsg"></Son>  
</div>
</template>
<script>
import Son from '../components/Son.vue'
export default {
  components: {
    Son
  },
  setup () {
    let msg =ref(200)
    let     changeMsg(value) = (value)=>{
     console.log(value)  // 子组件传过的的值“1111”
     msg.value = value.value
    }
    return {
      changeMsg,
      msg
    }
  }
}

vue3子传父 方式二 setup 语法糖

// Son
<template>
<div>
这是son组件
{{toFatherMsg}}
<button @click="toFatherMsg">自定义子传父</button>
</div>
</template>
<script setup lang='ts'>
let toFatherMsg = ref("111")
// const emit = defineEmits<{(e:'fn',id:number):void}>()  // ts方式
const emit = defineEmits(['fn'])  // setup方式
const toFatherMsg = () => {
      emit('fn',toFatherMsg)
    }
  }
}
//  father
<template>
<div>
<div>
 <span>父组件数据</span>
  <input v-model="msg"/>
 </div>
这是父组件,htmlz中需要用kebab-case命名,字符串模板没有这一限制
<Son :for-child-msg="msg" @fn="changeMsg"></Son>  
</div>
</template>
<script setup>
import Son from '../components/Son.vue'
export default {
  components: {
    Son
  },
  data() {
    return {
      msg:'这是子传给父的数据'
    }
  },
    methods: {
    changeMsg(value) {
     console.log(value)  // 子组件传过的的值“1111”
     this.msg = value
    }
  }
}

组件 v-model传值,即实现父子组件双向绑定修改

//  father
<template>
<div>
<div>
 <span>父组件数据</span>
  <input v-model="msg"/>
 </div>
这是父组件,htmlz中需要用kebab-case命名,字符串模板没有这一限制
<Son v-model:for-child-msg="msg" @fn="changeMsg"></Son>  
</div>
</template>
<script setup>
import Son from '../components/Son.vue'
export default {
  components: {
    Son
  },
  data() {
    return {
      msg:'这是子传给父的数据'
    }
  },
    methods: {
    changeMsg(value) {
     console.log(value)  // 子组件传过的的值“1111”
     this.msg = value
    }
  }
}
// Son
<template>
<div>
这是son组件
{{toFatherMsg}}
<button @click="toFatherMsg">双向绑定的子传父</button>
这是父传子的数据:{{for-child-msg}}
</div>
</template>
<script setup >
const props = defineProps({
  'forChildMsg':{
    type:Number,
    default:20
  }
})
let toFatherMsg = ref("111")
// const emit = defineEmits<{(e:'fn',id:number):void}>()  // ts方式
const emit = defineEmits(['update:forChildMsg'])  // setup方式
const toFatherMsg = () => {
      emit('update:forChildMsg',toFatherMsg)
    }
  }
}
本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: 暂无
最后更新:2022年6月13日
< 上一篇
下一篇 >
归档
  • 2024 年 11 月
  • 2024 年 8 月
  • 2024 年 5 月
  • 2024 年 2 月
  • 2023 年 12 月
  • 2023 年 11 月
  • 2023 年 9 月
  • 2023 年 6 月
  • 2022 年 12 月
  • 2022 年 11 月
  • 2022 年 10 月
  • 2022 年 9 月
  • 2022 年 8 月
  • 2022 年 7 月
  • 2022 年 6 月
  • 2022 年 5 月
  • 2022 年 4 月
  • 2022 年 3 月
  • 2022 年 2 月
  • 2022 年 1 月
  • 2021 年 12 月
  • 2021 年 11 月
  • 2021 年 10 月
  • 2021 年 5 月
分类
  • Android
  • Arduino
  • cordova
  • css
  • go
  • html5
  • JavaScript
  • nodejs
  • oracle
  • project
  • system
  • uni-app
  • vscode
  • vue
  • 学习计划
  • 摘抄
  • 随想
最新 热点 随机
最新 热点 随机
windows安装mysql ,VSCODE连接MySQL数据库 创建api的逻辑 观看七战奥运会 德国波尔告别 go utils工具 Go语言中的sort包帮我们实现了对任一类型的数组进行排序。 vue + go安装
canvascanvas 科技动画背景 、图板填鸭及切换画笔、擦除、清除、保存 读阮一峰老师-未来娱乐业 学习计划 css 第三天 windows安装mysql ,VSCODE连接MySQL数据库 接站点餐住宿综合管理平台

COPYRIGHT © 技海泛舟(个人技术研究). 2021-2023. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

黑ICP备19002110号-1

黑公网安备 23060202000432号