vue 方法使用注意事项

1.Vuex

dispatch

state:相当于Vue的data

mutations:类似于事件,每个 mutation 都有一个字符串的事件类型 (type)和 一个回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数

actions: Action 类似于 mutation,不同在于Action 提交的是 mutation,而不是直接变更状态,Action 可以包含任意异步操作

getters:可以认为是 store 的计算属性,就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算,接受 state 作为其第一个参数

好了,就这么简单可以用了

localStorage 和 SessionStorage的区别:

localStorage:关闭窗口后数据一直存在,并且在同源不同窗口下也能共享;

seesionStorage:当前窗口关闭前有效

nextTick();

在下次DOM更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM,在引入VUE的地方引入 不可单独引入否则会报错(elementUI框架中VUE3的写法)

延迟调用优先级:Promise > MutationObserver > setImmediate > setTimeout

next-tick.js 对外暴露了nextTick这一个参数,所以每次调用Vue.nextTick时会执行:

  • 把传入的回调函数cb压入callbacks数组
  • 执行timerFunc函数,延迟调用 flushCallbacks 函数
  • 遍历执行 callbacks 数组中的所有函数

这里的 callbacks 没有直接在 nextTick 中执行回调函数的原因是保证在同一个 tick 内多次执行nextTick,不会开启多个异步任务,而是把这些异步任务都压成一个同步任务,在下一个 tick 执行完毕。

使用Vue.nextTick()是为了可以获取更新后的DOM 。

触发时机:在同一事件循环中的数据变化后,DOM完成更新,立即执行Vue.nextTick()的回调。

同一事件循环中的代码执行完毕 -> DOM 更新 -> nextTick callback触发

链接:浅析Vue.nextTick()原理 - 简书

生命周期

beforeCreate

场景:

在实例初始化之后,数据观测(data observer)和 event/watcher事件配置之前调用

created

场景:

在实例创建完成后立即被调用,实例已完成数据观测(data observer),属性和方法的运算,watch/event事件回调,挂载阶段还没开始

beforeMount

场景:

在挂载开始之前被调用,相关的render函数首次被调用

ps:该钩子在服务器端渲染期间不被调用

mounted

场景:

el 被创建的 vm.$el 替换,并在挂载到实例上去之后调用该钩子,如果root实例挂载了一个文档元素,当mounted被调用 vm.$el 也在文档内

beforeUpdate

场景:

数据更新时调用,发生在虚拟DOM打补丁之前,这里适合在更新之前访问现有的DOM,比如手动移除已添加的事件监听器

该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行。

updated

场景:

数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。

该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行。

activated

场景:

keep-alive 组件激活时调用。

该钩子在服务器端渲染期间不被调用。

vue3 生命周期

生命周期钩子vue2到vue3映射关系

beforeCreate -> use setup() created -> use setup() beforeMount -> onBeforeMount mounted -> onMounted beforeUpdate -> onBeforeUpdate updated -> onUpdated beforeDestroy -> onBeforeUnmount destroyed -> onUnmounted errorCaptured -> onErrorCaptured

引用时只需导入钩子并将它们包在 setup 方法中即可。

vue3中使用Proxy代理

var proxy = new Proxy(target, handler);

var obj = new Proxy({}, { get: function (target, propKey, receiver) { console.log(`getting ${propKey}!`); return Reflect.get(target, propKey, receiver); }, set: function (target, propKey, value, receiver) { console.log(`setting ${propKey}!`); return Reflect.set(target, propKey, value, receiver); } });

handler可以有以下几种属性

get(target, propKey, receiver):拦截对象属性的读取,比如proxy.foo和proxy['foo']。 set(target, propKey, value, receiver):拦截对象属性的设置,比如proxy.foo = v或proxy['foo'] = v,返回一个布尔值。 has(target, propKey):拦截propKey in proxy的操作,返回一个布尔值。 deleteProperty(target, propKey):拦截delete proxy[propKey]的操作,返回一个布尔值。 ownKeys(target):拦截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy)、for...in循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,而Object.keys()的返回结果仅包括目标对象自身的可遍历属性。 getOwnPropertyDescriptor(target, propKey):拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。 defineProperty(target, propKey, propDesc):拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。 preventExtensions(target):拦截Object.preventExtensions(proxy),返回一个布尔值。 getPrototypeOf(target):拦截Object.getPrototypeOf(proxy),返回一个对象。 isExtensible(target):拦截Object.isExtensible(proxy),返回一个布尔值。 setPrototypeOf(target, proto):拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。 apply(target, object, args):拦截 Proxy 实例作为函数调用的操作,比如proxy(...args)、proxy.call(object, ...args)、proxy.apply(...)。 construct(target, args):拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(...args)。

vue2定义数据使用data,定义方法使用methods

export default {
    name: 'App',
    data(){
        return {
            title: 'vue3',
            num: 3
        }
    },
    methods:{
        hello () {
            alert('hello vue3');
        }
    }
}

vue3定义数据和方法在setup()方法里面,return一个对象

export default {
    name: 'App',
    setup(){
        return {
            title: 'vue3',
            num: 3,
            hello () {
                alert('hello vue3');
            }
        }
    }
}

在 2.x 中,在组件上使用 v-model 相当于绑定 value的prop 并触发input 事件

<ChildComponent v-model="pageTitle" />
<!-- 是以下的简写: -->
<ChildComponent :value="pageTitle" @input="pageTitle = $event" />

在 3.x 中, v-model 相当于传递了 mo

<ChildComponent v-model="pageTitle" />
<!-- 是以下的简写: -->
<ChildComponent
  :modelValue="pageTitle"
  @update:modelValue="pageTitle = $event"
/>
###### 变化
prop:value => modelValue
事件:input => update:modelValue

delValue的 prop 并接收抛出的 update:modelValue 事件

<ChildComponent v-model="pageTitle" />
<!-- 是以下的简写: -->
<ChildComponent
  :modelValue="pageTitle"
  @update:modelValue="pageTitle = $event"
/>
###### 变化
prop:value => modelValue
事件:input => update:modelValue

v-if 和 v-for 优先级

同一元素使用时在vue2中v-for高于v-if

在vue3中v-if的优先级要高

修饰符: v-on.native

vue3移除native修饰符。

在vue2中,v-on.native修饰符把原生的事件绑定到子组件根元素上。

vue2:

<my-component v-on:close="handleComponentEvent" v-on:click.native="handleNativeClickEvent" />

vue3:

在vue3中,.native 修饰符已被移除。同时新增的 emits 选项,子组件定义真正会被触发的事件。

未在子组件emits定义为组件触发的所有事件监听器,Vue 现在将把它们作为原生事件监听器添加到子组件的根元素中 (除非在子组件的选项中设置了 inheritAttrs: false)+。

my-component v-on:close="handleComponentEvent" v-on:click="handleNativeClickEvent" />

子组件中

script> export default { emits: ['close'] } script>

v-for绑定key值,为什么不建议使用index作为key值?

如果只是展示列表数据,key值可以是索引;如果列表中的数据会经常发生变化,特别是列表数据的位置会发生变化,这时候key一定要设置为对象身上的唯一属性,目的是:当列表更新时,会大大提高列表重新渲染的性能损耗。

因为vue在渲染数据时,先将数据生成一份虚拟DOM,再将虚拟DOM生成对应的真实DOM挂载到页面中。当vue中的数据修改后,会重新生成一份虚拟DOM,并跟之前的虚拟DOM进行匹配,如果两份虚拟DOM中的key和key对应的值完全相同,不会重新生成对应的真实DOM;只有key和key对应的值不同的虚拟DOM,才会生成新的真实DOM并挂载的页面中。

div class="home">添加button> ul> li v-for="item in list" :key="item.id">{{ item }}li> ul> div>

VUE项目中使用this.$forceUpdate();解决页面v-for中修改item属性值后页面v-if不改变的问题

yield*

yield*表达式用于委托另一个generator或可迭代对象

语法:yield*[[expression]];

expression 返回一个可迭代对象的表达式。

描述 yield* 表达式迭代操作数,并返回他产生的每个值。

yield* 表达式本身的值是当迭代器关闭时返回的值(即done为true时)。

委托给其他生成器

g1() yield出去的每个值都会在g2()的next()方法中返回,就像那些yield语句是写在g2()里一样

function* g1() {

yield 2;

yield 3;

yield 4;

}

function* g2() {

yield 1;

yield* g1();

yield 5;

}

var iterator = g2();

console.log(iterator.next()); // { value: 1, done: false }

console.log(iterator.next()); // { value: 2, done: false }

console.log(iterator.next()); // { value: 3, done: false }

console.log(iterator.next()); // { value: 4, done: false }

console.log(iterator.next()); // { value: 5, done: false }

console.log(iterator.next()); // { value: undefined, done: true }

委托给其他可迭代对象

出=除了生成器对象这一种可迭代对象,yield*换可以yield其他任意可以迭代的对象,比如说数组、字符串、arguments对象等等

function* g3() {

yield* [1, 2];

yield* "34";

yield* arguments;

}

var iterator = g3(5, 6);

console.log(iterator.next()); // { value: 1, done: false }

console.log(iterator.next()); // { value: 2, done: false }

console.log(iterator.next()); // { value: "3", done: false }

console.log(iterator.next()); // { value: "4", done: false }

console.log(iterator.next()); // { value: 5, done: false }

console.log(iterator.next()); // { value: 6, done: false }

console.log(iterator.next()); // { value: undefined, done: true }

yield* 表达式的值

yield* 是一个表达式,不是语句,所以它会有自己的值。

function* g4() {

yield* [1, 2, 3];

return "foo";

}

var result;

function* g5() {

result = yield* g4();

}

var iterator = g5();

console.log(iterator.next()); // { value: 1, done: false }

console.log(iterator.next()); // { value: 2, done: false }

console.log(iterator.next()); // { value: 3, done: false }

console.log(iterator.next()); // { value: undefined, done: true },

// 此时 g4() 返回了 { value: "foo", done: true }

console.log(result); // "foo"

vue3

路由导航守卫提示报错信息

vue-router4路由 No match found for location with path警告

场景

1.动态路由

通过前端静态路由地址分模块按照约定值控制菜单路由

解决方案

在初始静态路由文件下增加

{

    path: '/:pathMatch(.*)*',

    component: () => import('@/views/error-page/404.vue')

  }

或检查其路由配置(正常来说按照正常来说 路由文件配置问题会在第一时间将错误抛出)

  • 36
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值