vue3小知识总结

修改vue的默认配置

vue官网生态系统脚手架Vue CLI的配置参考,在根目录新建vue.config.js (之后重启项目)
在这里插入图片描述

vue3如何关闭检查

也是跟修改配置一样,新建一个文件夹vue.config.js,官网文档
在这里插入图片描述
在这里插入图片描述

ref属性

放在html标签上和id是差不多的,但是放在组件标签上会不同
id是获取到dom对象
在这里插入图片描述

在这里插入图片描述

props属性

子组件传值给父组件
在这里插入图片描述
父组件接收
在这里插入图片描述
props的值的直接存在了vue实例里面(this),直接打印this.name即可查看
原则上props的值不能更改,但是vue检测的比较浅,直接改变量会报错,如果是对象不会报错,因为是更改对象里面的一个值,vu检测不到

混合配置(js)

新建一个js,放共同配置

export const hunhe = {
	methods: {
		showName(){
			alert(this.name)
		}
	},
	mounted() {
		console.log('你好啊!')
	},
}
export const hunhe2 = {
	data() {
		return {
			x:100,
			y:200
		}
	},
}

加粗样式
在这里插入图片描述

直接安装less-loader报错

由于vue用的是4.46.0较为稳定版本(5.0以上还有待检验)
直接npm i less-loader是安装最新版本,最新版本8-9是为5.0安装的,所以需要降一个版本安装7的
查看各版本的命令:npm view less- loader versions
在这里插入图片描述
所以需要安装的是npm i less-loader@7,才不会报错,同样安装sass也是一样的,需要降低版本安装

父组件传递函数给子组件,子组件可以通过函数将信息传给父组件

在这里插入图片描述
在这里插入图片描述

遍历列表时虚拟DOM的作用

数据变化话会先将新虚拟DOM的内容与旧的进行对比,如果是一样的就从真实DOM里直接拿,不一样要将新虚拟DOM的内容转化成真实内容
以index作为key有时会出现问题(后面数据错位)
在这里插入图片描述
以数据里的id作为key才不会出现问题
在这里插入图片描述

一个字符串里面是包含空字符串的

'abcd'.indexOf('') ==0
'abcd'.indexOf('a') ==0

过滤


	data:{
				keyWord:'',
				persons:[
					{id:'001',name:'马冬梅',age:19,sex:'女'},
					{id:'002',name:'周冬雨',age:20,sex:'女'},
					{id:'003',name:'周杰伦',age:21,sex:'男'},
					{id:'004',name:'温兆伦',age:22,sex:'男'}
				],
				filPerons:[]
			},
//用watch进行过滤
watch:{
				keyWord:{
					immediate:true,//因为初始化的时候keyWord是空数组,一开始如果不先执行一下watch,会初始化无数据,随便写个数据删除之后可以显示所有数据(一个字符串里面是包含空字符串的)
					handler(val){
						this.filPerons = this.persons.filter((p)=>{
							return p.name.indexOf(val) !== -1
						})
					}
				}
			}
//用computed进行过滤
	computed: {
				filPerons() {
					return this.persons.filter((p) => {
						return p.name.indexOf(this.keyWord) !== -1
					})
				}
			}

可以对上面过滤到的数据进行筛选

data:{
					keyWord:'',
					sortType:0, //0原顺序 1降序 2升序
					persons:[
						{id:'001',name:'马冬梅',age:30,sex:'女'},
						{id:'002',name:'周冬雨',age:31,sex:'女'},
						{id:'003',name:'周杰伦',age:18,sex:'男'},
						{id:'004',name:'温兆伦',age:19,sex:'男'}
					]
				},
				computed:{
					filPerons(){
						const arr = this.persons.filter((p)=>{
							return p.name.indexOf(this.keyWord) !== -1
						})
						//判断一下是否需要排序
						if(this.sortType){
							arr.sort((p1,p2)=>{
								return this.sortType === 1 ? p2.age-p1.age : p1.age-p2.age
							})
						}
						return arr
					}
				}

Vue监测数据改变的原理_数组

在Vue修改数组中的某个元素一定要用如下方法:
1.使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
2.Vue.set() 或 vm.$set()
如果直接修改arr[0]='xxx’页面是无法更新的,内部数据更改了,但是vue检测不到,vue检测得到数据变化得数组使用那7个api
但是对数组整个进行更替是可以的。例如:arr=[‘a’,‘b’]

vue检测总结

对2.(1)对象中后追加的属性:可以添加,但是没有做响应式处理,后面没有set与get的方法
在这里插入图片描述
如果是使用2.(2)Vue.set(target,propertyName/index,value) 或 vm.$set(target,propertyName/index,value)使用了api
在这里插入图片描述

	<!--
		Vue监视数据的原理:
			1. vue会监视data中所有层次的数据。
			2. 如何监测对象中的数据?
							通过setter实现监视,且要在new Vue时就传入要监测的数据。
								(1).对象中后追加的属性,Vue默认不做响应式处理,可以添加属性,但是属性没有响应式
								(2).如需给后添加的属性做响应式,请使用如下API:
												Vue.set(target,propertyName/index,value) 或 
												vm.$set(target,propertyName/index,value)

			3. 如何监测数组中的数据?
								通过包裹数组更新元素的方法实现,本质就是做了两件事:
									(1).调用原生对应的方法对数组进行更新。
									(2).重新解析模板,进而更新页面。

			4.在Vue修改数组中的某个元素一定要用如下方法:
						1.使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
						2.Vue.set() 或 vm.$set()
			
			特别注意:Vue.set() 和 vm.$set() 不能给vm 或 vm的根数据对象 添加属性!!!
	-->

vm与vc

vm的Vue的实例对象(它们的this均是【Vue实例对象】),
vc是vue组件的实例对象(它们的this均是【VueComponent实例对象】)

一个重要的内置关系

1.一个重要的内置关系:VueComponent.prototype.proto === Vue.prototype
2.为什么要有这个关系:让组件实例对象(vc)可以访问到 Vue原型上的属性、方法。
例如:Vue.prototype.x = 99
在组件中可以用this.x直接访问到x
在这里插入图片描述

全局事件总线

任意组件间通信,所以要安装全局事件总线定义一个所有组件或都可以看见的
在这里插入图片描述
安装事件全局总线

new Vue({
	......
	beforeCreate() {
		Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm
	},
    ......
}) 

使用事件总线:
接收数据:School组件想接收student的数据,则在School组件中给$bus绑定自定义事件,事件的回调留在School组件自身。

//school组件
methods(){
  demo(data){......}
}

mounted() {
	this.$bus.$on('hello',(data)=>{
	this.demo(data)
	console.log('我是School组件,收到了数据',data)
			})
}
//也可以这么写
      mounted() {
        this.$bus.$on('hello',this.demo)
      }

student组件提供数据:this. b u s . bus. bus.emit(‘hello’,数据)

消息订阅与发布(pubsub)与全局事件总线很像

安装pubsub:npm i pubsub-js

引入: import pubsub from ‘pubsub-js’

接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身。

methods(){
  demo(data){......}
}
......
mounted() {
  this.pubId= pubsub.subscribe('xxx',this.demo) //订阅消息
}
beforeDestroy() {
		pubsub.unsubscribe(this.pubId)
		},

提供数据:pubsub.publish(‘xxx’,数据)

最好在beforeDestroy钩子中,用PubSub.unsubscribe(pid)去取消订阅。

nextTick

语法:this.$nextTick(回调函数)
作用:在下一次 DOM 更新结束后执行其指定的回调。
什么时候用:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行。
例如:

	//编辑
			handleEdit(todo){
				if(todo.hasOwnProperty('isEdit')){
					todo.isEdit = true //将这个列表的isEdit数据更改成true
				}else{
					// console.log('@')
					this.$set(todo,'isEdit',true)
				}
				//如果不使用this.$nextTick等待DOM 更新结束后执行,会无效,因为dom要等模板都解析完再执行,页面还没有input你却让input标签聚焦,所以无效,要等执行完dom更新再回调
				this.$nextTick(function(){
					this.$refs.inputTitle.focus()
				})
			},

作用域插槽

理解:数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定。(games数据在Category组件中,但使用数据所遍历出来的结构由App组件决定)
数据在子组件中,父组件想拿到
具体编码:

//父组件中:组件的使用者拿到组件插槽的数据,并且显示自定义的展示结构
		<Category>
			<template scope="scopeData">
				<!-- 生成的是ul列表 -->
				<ul>
					<li v-for="g in scopeData.games" :key="g">{{g}}</li>
				</ul>
			</template>
		</Category>

		<Category>
			<template slot-scope="scopeData">
				<!-- 生成的是h4标题 -->
				<h4 v-for="g in scopeData.games" :key="g">{{g}}</h4>
			</template>
		</Category>
//子组件中:将数据传给插槽 <slot :games="games"></slot>
        <template>
            <div>
                <slot :games="games"></slot>
            </div>
        </template>
		
        <script>
            export default {
                name:'Category',
                props:['title'],
                //数据在子组件自身
                data() {
                    return {
                        games:['红色警戒','穿越火线','劲舞团','超级玛丽']
                    }
                },
            }
        </script>

VUEX

1.搭建vuex环境:创建文件:src/store/index.js

//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)

//准备actions对象——响应组件中用户的动作
const actions = {}
//准备mutations对象——修改state中的数据
const mutations = {}
//准备state对象——保存具体的数据
const state = {}

//创建并暴露store
export default new Vuex.Store({
	actions,
	mutations,
	state
})

2.在main.js中创建vm时传入store配置项

......
//引入store
import store from './store'
......

//创建vm
new Vue({
	el:'#app',
	render: h => h(App),
	store
})

3.基本使用
组件中读取vuex中的数据:$store.state.sum

组件中修改vuex中的数据:$store.dispatch(‘action中的方法名’,数据)

备注:若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写dispatch,直接编写commit($store.commit(‘mutations中的方法名’,数据))
例如用最简单的方法

	methods: {
			increment(){
				this.$store.commit('JIA',this.n)
			},
			decrement(){
				this.$store.commit('JIAN',this.n)
			},
			incrementOdd(){
				this.$store.dispatch('jiaOdd',this.n)
			},
			incrementWait(){
				this.$store.dispatch('jiaWait',this.n)
			},
		},

例如在组件中调用并且使用mapState等方法

<template>
	<div>
		<h1>当前求和为:{{sum}}</h1>
		<h3>当前求和放大10倍为:{{bigSum}}</h3>
		<h3>我在{{school}},学习{{subject}}</h3>
		<select v-model.number="n">
			<option value="1">1</option>
			<option value="2">2</option>
			<option value="3">3</option>
		</select>
		<button @click="increment(n)">+</button>
		<button @click="decrement(n)">-</button>
		<button @click="incrementOdd(n)">当前求和为奇数再加</button>
		<button @click="incrementWait(n)">等一等再加</button>
	</div>
</template>

<script>
	import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
	export default {
		name:'Count',
		data() {
			return {
				n:1, //用户选择的数字
			}
		},
		computed:{
			//借助mapState生成计算属性,从state中读取数据。(对象写法)
			// ...mapState({he:'sum',xuexiao:'school',xueke:'subject'}),
			//借助mapState生成计算属性,从state中读取数据。(数组写法)
			...mapState(['sum','school','subject']),
			//借助mapGetters生成计算属性,从getters中读取数据。(对象写法)
			// ...mapGetters({bigSum:'bigSum'})
			//借助mapGetters生成计算属性,从getters中读取数据。(数组写法)
			...mapGetters(['bigSum'])

		},
		methods: {
			//程序员亲自写方法
			/* increment(){
				this.$store.commit('JIA',this.n)
			},
			decrement(){
				this.$store.commit('JIAN',this.n)
			}, */

			//借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法),不需要传参是因为默认把 increment(n)里的n作为参数传递过去了,如果页面中increment方法没有传参的话会把(increment(event))中默认带的event作为参数传递过去
			...mapMutations({increment:'JIA',decrement:'JIAN'}),

			//借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(数组写法)
			// ...mapMutations(['JIA','JIAN']),

			/* ************************************************* */

			//程序员亲自写方法
			/* incrementOdd(){
				this.$store.dispatch('jiaOdd',this.n)
			},
			incrementWait(){
				this.$store.dispatch('jiaWait',this.n)
			}, */

			//借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)
			...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})

			//借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(数组写法)
			// ...mapActions(['jiaOdd','jiaWait'])
		},
		mounted() {
			const x = mapState({he:'sum',xuexiao:'school',xueke:'subject'})
			console.log(x)
		},
	}
</script>

<style lang="css">
	button{
		margin-left: 5px;
	}
</style>

export default {
	namespaced:true,
	actions:{
		jiaOdd(context,value){
			console.log('actions中的jiaOdd被调用了')
			if(context.state.sum % 2){
				context.commit('JIA',value)
			}
		},
		jiaWait(context,value){
			console.log('actions中的jiaWait被调用了')
			setTimeout(()=>{
				context.commit('JIA',value)
			},500)
		}
	},
	mutations:{
		JIA(state,value){
			console.log('mutations中的JIA被调用了')
			state.sum += value
		},
		JIAN(state,value){
			console.log('mutations中的JIAN被调用了')
			state.sum -= value
		},
	},
	state:{
		sum:0, //当前的和
		school:'尚硅谷',
		subject:'前端',
	},
	getters:{
		bigSum(state){
			return state.sum*10
		}
	},
}

flex布局

参考博客链接
了解flex布局是几个属性
flex-direction :设置谁为主轴,子元素是根据主轴来排列的
在这里插入图片描述
justify-content:设置主轴上的子元素排列方式
在这里插入图片描述
flex-wrap:设置是否换行(默认不换行)
在这里插入图片描述
align-items 设置侧轴上的子元素排列方式(单行 )
在这里插入图片描述
align-content 设置侧轴上的子元素的排列方式(多行)
在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值