vue3笔记

一、vue3项目

创建vue3项目 : 基于构建工具webpack

vue create 项目名称
  • 基于webpack的项目有一个问题,就是编译慢
  • 解决:使用vite
  • vite优势:在开发过程中大大提升我们的效率

二、 创建vue3项目 : 基于vite

npm init vite 项目名称

**如果选择vue的项目,默认版本是vue3

vite + vue3 的方式:

  • 把create创建vue的src整个复制粘贴到基于vite的项目中
  • 把create创建的package.json中的
"dependencies": {
			    "core-js": "^3.6.5",
			    "vue": "^3.0.0",
			    "vue-router": "^4.0.0-0",
			    "vuex": "^4.0.0-0"
			    },

                **复制粘贴到vite的项目中

  • npm i :安装依赖

  • npm run dev 启动修改错误

vite + vue2 的方式:

  • 把create创建vue的src整个复制粘贴到基于vite的项目中
  • 把create创建的package.json中的
"dependencies": {
    "core-js": "^3.6.5",
    "vue": "^2.6.11",
    "vue-router": "^3.2.0",
    "vuex": "^3.4.0"
},

                **复制粘贴到vite的项目中

  • npm i :安装依赖

  • 注意会报错,在安装npm install vite-plugin-vue2 -D

  • 在vite.config.js配置

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

export default {
  plugins: [
    createVuePlugin(/* options */)
  ],
}
  • cnpm i vue-template-compiler -S

三、vue-cli : vue3

//vue2写法
<script>
	import HelloWorld from "../components/HelloWorld.vue";
	export default {
	  name: "Home",
	  data () {
	    return {
	      
	    }
	  },
	  components: {
	    HelloWorld,
	  },
	};
</script>


//vue3写法
<script setup>

</script>

四、vue-cli : vue3

1.1、v-if 与 v-for 的优先级对比

2.x 版本中  v-for > v-if
3.x 版本中  v-if  > v-for

1.2、v-for 中的 Ref 数组

  • vue2.x 会自动把ref填充内容
  • vue3.x 需要手动添加
  <ul>
    <li v-for="item in 5" :key="item" :ref="setItemRef">{{ item }}</li>
  </ul>


methods: {
  setItemRef(el){
    this.arr.push(el);
  }
}

1.3 $children

  • vue2.x : 访问当前实例的子组件
  • vue3.x : 在 3.x 中,$children 已被移除,且不再支持。

                设置:<HelloWorld msg="Welcome" ref='hw'/>

                访问:this.$refs.hw

五、setup

是什么 : 组合式 API

来解决什么问题 :  使用 (data、computed、methods、watch) 组件选项来组织逻辑通常都很有效。然而,当我们的组件开始变得更大时,逻辑关注点的列表也会增长。尤其对于那些一开始没有编写这些组件的人来说,这会导致组件难以阅读和理解。

响应区别:

  • vue2.x : Object.defineProperty()
  • vue3.x : Proxy

Object.defineProperty()存在的问题

  • 不能监听数组的变化
  • 必须遍历对象的每一个属性

Proxy 不需要遍历 

使用渲染函数:

  • ref : 就是定义数据的     简单类型
  • reactive : 就是定义数据的    复杂类型

setup语法糖插件 : unplugin-auto-import 

解决场景 : 在组件中开发无需每次都引入 import { ref,reactive } from 'vue'

1、下载安装

npm i unplugin-auto-import -D

 2、配置:vite.config.js中

import AutoImport from 'unplugin-auto-import/vite'
export default defineConfig({
  plugins: [
    AutoImport({
      imports: ['vue', 'vue-router']//自动导入vue和vue-router相关函数
    })
  ],
})

toRefs:

        toRefs 函数 来完成数据的解构

computed:

  1. let obj = reactive({
      name: '张三',
      age: 18,
      str: computed(() => {
        return obj.name.slice(1, 2)
      })
    })
    

  2. let msgChange = computed(() => {
      return msg.value.slice(1, 3);
    })

  3. let msgChange = computed({
      get() {
        return msg.value.slice(1, 3);
      },
      set() {
        console.log('设置了')
      }
    })

watch:

vue2.x :

watch: {
  obj: {
    handler(newVal, oldVal){
      console.log(newVal, oldVal)
    },
    immediate: true,
    deep: true
  }
}

vue3.x :

  1. 监听数据数据「初始化监听」
    
    watch(msg, (newVal, oldVal) => {
      console.log(newVal, oldVal)
    }, {
      immediate: true
    })
  2. 监听多个数据「一起监听」
    watch([msg, str], (newVal, oldVal) => {
      console.log(newVal, oldVal)
    }, {
      immediate: true
    })
    

  3. 监听“对象”中某个对象
    watch(() => obj.arr, (newVal, oldVal) => {
      console.log(newVal, oldVal)
    })
    

  4. 立即执行监听函数
    watchEffect(() => {
      console.log(msg.value)
    })

    参考链接:https://v3.cn.vuejs.org/api/computed-watch-api.html#watcheffect

六、生命周期

选项式 API

  • beforeCreate
  • created
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • ....

setup 组合式API

        注意:没有beforeCreate和created

        其他生命周期要使用前面加"on" 例如:onMounted

参考链接:https://v3.cn.vuejs.org/guide/composition-api-lifecycle-hooks.html

七、路由

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

八、组件之间的通信(特别重要)

父传子:

父:

<template>
  <div>
    <List :msg="msg"></List>
  </div>
</template>

<script setup>
  import List from '../components/List.vue'
  let msg = ref('这是父传过去的数据');
</script>

子:

<template>
  <div>这是子组件 ==> {{ msg }}</div>
</template>

<script setup>
defineProps({
  msg: {
    type: String,
    default: '1111'
  }
})
</script>

子传父:

一、第一种给方式:

子:

<template>
  <div>
    这是子组件 ==> {{ num }}
    <button @click="changeNum">按钮</button>
  </div>
</template>

<script setup lang='ts'>
let num = ref(200);

const emit = defineEmits<{
  (e: "fn", id: number): void;
}>();

const changeNum = () => {
  emit("fn", num);
};
</script>

父:

<template>
  <div>
    <List @fn="changeHome"></List>
  </div>
</template>

<script setup>
import List from '../components/List.vue'
const changeHome = (n) => {
  console.log(n.value);
}
</script>

二、第二种给方式:

子:

<template>
  <div>
    <button @click="mesBtn">按钮</button>
  </div>
</template>

<script setup>
const num = ref(10000)

const emit = defineEmits(['fn'])

const mesBtn = () => {
  emit('fn', num)
}


</script>

父:

<template>
  <div>
    <Hellow @fn="changeList"></Hellow>
    <h3>{{str}}</h3>
  </div>
</template>

<script setup>
import Hellow from '../components/Hellow.vue'
const str = ref();

const changeList = (n) => {
  str.value = n.value;
}

</script>

v-model传值(双向的,可以修改)

父:

<template>
  <div>
    <h1>
      <Hellow v-model:List="List"></Hellow>
    </h1>
  </div>
</template>

<script setup>
import Hellow from '../components/Hellow.vue';
const List = ref('永远爱你是我说过')
</script>

子:

<template>
  <div>
    子:{{List}}
    <button @click="btn">按钮</button>
  </div>
</template>
<script setup>
const props = defineProps({
  List: {
    type: String,
    default: '安安'
  }
})
const emit = defineEmits(['update:List'])
const btn = () => {
  emit('update:List', '啊和你说过');
}
</script>

兄弟组件之间的传值:

一、下载安装

  • npm install mitt -S

二、plugins/Bus.js

  • mport mitt from 'mitt';
  • const emitter = mitt();
  • export default emitter;

三、A组件

  • emitter.emit('fn',str);

四、B组件

emitter.on('fn', e => {

  s.value = e.value;

})

八、插槽

匿名插槽

父:

    <A>
      这是xxxxx数据
      这是yyyyy数据
    </A>

子:

    <header>
      <div>头部</div>
      <slot></slot>
    </header>

    <footer>
      <div>底部</div>
      <slot></slot>
    </footer>

具名插槽

父:

    <A>
      <template v-slot:xxx>这是xxxxx数据</template>

      <template v-slot:yyy>这是yyyyy数据</template>
    </A>

                         ***简写:<template #xxx>

子:

    <header>
      <div>头部</div>
      <slot name="xxx"></slot>
      <slot name="yyy"></slot>
    </header>

    <footer>
      <div>底部</div>
      <slot name="xxx"></slot>
    </footer>

作用域插槽

父:

    <A>
      <template v-slot="{data}">{{ data.name }} --> {{ data.age }}</template>
    </A>

                *****简写:<template #default='{data}'>

子:

    <div v-for="item in list" :key="item.id">
      <slot :data="item"></slot>
    </div>

动态插槽:

就是通过数据进行切换

父:

<template #[xxx]>这是xxxxx数据</template>

<script setup>

    let xxx = ref('xxx');

</script>

子:

<slot name="xxx"></slot>

九、Teleport : 传送

      <teleport to="#container"></teleport>
      <teleport to=".main"></teleport>
      <teleport to="body"></teleport>

                ***必须传送到有这个dom的内容【顺序】

十、动态组件

<component :is="动态去切换组件"></component>

十一、异步组件

***用来提升性能

        vueuse : https://vueuse.org/core/useintersectionobserver/

使用场景1

        组件按需引入:当用户访问到了组件再去加载该组件

        

<template>
  <div>
    <div ref="target">
      <C v-if="targetIsVisible"></C>
    </div>
  </div>
</template>


<script setup>

import { useIntersectionObserver } from '@vueuse/core'

const C = defineAsyncComponent(() =>
  import('../components/C.vue')
)

const target = ref(null);
const targetIsVisible = ref(false);

const { stop } = useIntersectionObserver(
  target,
  ([{ isIntersecting }]) => {
    if (isIntersecting) {
      targetIsVisible.value = isIntersecting
    }
  },
)
</script>

使用场景2

		<Suspense>
			<template #default>
				<A></A>
			</template>
			<template #fallback>
				加载中...
			</template>
		</Suspense>

		<script setup>
		const A = defineAsyncComponent(() =>
		  import('../components/A.vue')
		)
		</script>

打包分包处理

		npm run build打包完成后,异步组件有单独的js文件,是从主体js分包出来的

		A.c7d21c1a.js
		C.91709cb2.js

十二、Mixin : 混入

是什么:来分发 Vue 组件中的可复用功能

setup写法

        mixins/mixin.js

import { ref } from 'vue'
export default function () {

  let num = ref(1);
  let fav = ref(false);

  let favBtn = () => {
    num.value += 1;
    fav.value = true;
    setTimeout(() => {
      fav.value = false;
    }, 2000)
  }

  return {
    num,
    fav,
    favBtn
  }

}

        组件:

<template>
  <div>
    这是A组件{{num}}
    <button @click="favBtn">{{fav?'收藏中':'收藏'}}</button>
  </div>
</template>
<script setup>
import mixin from '../mixins/mixin';

let { num, fav, favBtn } = mixin();
</script>

选项式api写法

        mixins/mixin.js

export const fav = {
	data() {
		return {
			num: 10
		}
	},
	methods: {
		favBtn(params) {
			this.num += params
		}
	}
}

        组件:

			<template>
				<div>
					<h1>A组件</h1>
					{{ num }}
					<button @click='favBtn(1)'>按钮</button>
				</div>
			</template>

			<script type="text/javascript">
			import { fav } from '../mixins/mixin.js'
			export default{
				data () {
					return {
						str:'你好'
					}
				},
				mixins:[fav]
			}
			</script>

十三、Provide / Inject ==> 依赖注入

提供:(父组件)

<script setup>
    const num =ref(111);
    provide('changeNum', num );
</script>

注入:(子组件==》包括孙子辈分的)

<template>
  <div>
    <h1>B组件</h1>
    {{ bNum }}
  </div>
</template>

<script setup>
  const bNum = inject('changeNum');
</script>

十三、Vuex


import { useStore } from 'vuex';

const store = useStore();



state:
		let num = computed( ()=> store.state.num );
getters:
		let total = computed( ()=> store.getters.total );
mutations:
		store.commit('xxx')
actions:
		store.dispatch( 'xxx' )
modules: 
    和之前的版本使用一样

Vuex持久化存储【插件】

  1. npm i vuex-persistedstate -S​​​​​​​
  2. import persistedState from 'vuex-persistedstate'
  3. export default createStore({
    	modules: {
    		user
    	},
    	plugins: [
    		persistedState({
    			key: 'xiaoluxian',
    			paths: ['user']
    		})
    	]
    })
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值