父子组件如何传递方法,方法预置一些参数

常见的问题/坑

https://segmentfault.com/a/11...

https://segmentfault.com/a/11...

基础问题 https://juejin.im/post/59fa92...

模板解析

Vue的模板是DOM模板,使用浏览器原生的解析器而不是自己实现一个。相比字符串模板,DOM模板有一些好处,但是也有问题,它必须是有效的HTML片段。一些HTML元素对什么元素可以放在它里面有限制。常见的限制有:

a不能包行其他的交互元素(如按钮、链接)

ul和ol只能直接包含li。

select只能包含option和optgroup。

table只能直接包含thead、tbody、ftoot、tr、caption、col、colgroup。

tr只能直接包含th和td。

在实际应用中,这些限制会导致意外的结果。尽管再简单的情况下它可能可以工作,但是我们不能依赖自定义组件在浏览器验证之前展开结果。==例如<my-select><option>....</option></my-select>不是有效的模板,即使my-select组件最终展开为<select>...</select>。==

另一个结果是,自定义标签(包括自定义元素和特殊标签,如<component>、<template>、<partial>)不能用在ul、select、table等对内部元素有限制的标签内。放在这些元素内的自定义标签将被提到元素的外面,因而渲染不正确。

自定义元素应当使用is特性,如
<table>
    <tr is="my-component"></tr>
</table>
<template>

不能用在<table>内,这时应该使用<tbody>,<table>可以有多个<tbody>。如下:
<table>
    <tbody v-for="item in items">
        <tr>Even row</tr>
        <tr>Odd row</tr>
    </tbody>
</table>

v-for常用tips

当在组件中使用 v-for 时,key 现在是必须的。

<ul>
  <li v-for='(item, key) in items' :key='key'> {{ key }} - {{ item }}
</ul>

项目路径配置

其中 assetsSubDirectory 指静态资源文件夹,也就是打包后的 js、css、图片等文件所放置的文件夹,这个默认一般不会有问题。

  assetsPublicPath 指静态资源的引用路径,默认配置为 /,即网站根目录,与 assetsSubDirectory 组合起来就是完整的静态资源引用路径 /static。

build.assetsSubDirectory: 'static'
build.assetsPublicPath: './'

dev.assetsSubDirectory: 'static'
dev.assetsPublicPath: '/'

只要把根目录改为相对目录就好了:

使用ESnext class 特性

异步组件

异步路由组件

const AsyncComponent = () => import('./AsyncComponent')

异步组件工厂

Vue.component(
  'async-webpack-example',
  () => import('./my-async-component')
)

相比于异步路由组建,异步组件工厂一般适用于组件内进一步小颗粒度的拆分处理,如:大体量组件内初次加载时的非必要组件(组件内嵌套的弹窗组件或 Popover 组件等)。

数据双向绑定问题

  • 多处共用一份数据,一份地方改了,其他引用数据的地方都会自动更新
  • 某处的初始数据是另一个地方的数据,它修改只影响自己,不影响其他地方。解决方案就是:==某处组件接收prop作为初始数据,对它深拷贝(全量)(或者按需取字段构成自己的data,只拿部分),作为自己的data,然后修改时只会修改这份自己的数据,不影响其他==,

引用图片

图片引用问题。直接把本地图片地址放在src里没问题。但如果把地址提取出来写在data里或者通过method动态给src赋值则引用不到。

因为放在template模板里会被webpack打包所以可以,而放在data或者动态赋值,图片路径只是一个字符串webpack不会处理所以引用不到。

解决办法:通过import或者required引入。import src from ‘../../img.png’或者data:{img:require(‘../../img.png’)}

对象数组深度监听

后端传过来的数组是一个数组对象,页面中绑定对象中某一具体的属性,当该值变化时调用某个函数,自然想到就是watch方法。但如何==watch数组对象中某一个具体的属性==,显然不可能一个个属性写watch。
解决办法:

  • 1.==watch整个对象,设置deep为true==,当该对象发生改变时,调用处理函数。
  • 2.==将页面中绑定的属性写在computed函数中,watch这个computed中的函数==,当对象值改变时会进入computed函数中,进而进入watch函数中,再调用处理函数。

动态增加class

有一个正常的class, 有一个v-bind:class

<div class="test" :class="{'hasClass': ifHasClass}"></div>

给元素动态增加class时,可以在模板中通过:class={‘hasClass’: ifHasClass}来实现,当ifHasClass为true时,该元素会自动加上hasClass的样式。

动态绑定的class可以与正常写的一起使用,但如果在一个元素中使用了两个class则会报错

vue实例,vue单文件组件返回值,watch或生命周期中的箭头函数中的this

vue实例对象

let vm = new Vue({
    el: '#app',
    render: h => h(App)
})

console.log(vm)

image

vue单文件组件返回值

import App from './App.vue'

console.log(App)

image

watch或生命周期中的箭头函数中的this

watch: {
    //使用了箭头函数,则this是 {a: {}}, 不是当前vue实例
    text: (val, oldval) => {
        console.log(this)
    }
}

是和vue单文件组件返回值一致的,只是外面又包了个对象,将返回值作为属性值使用了。

兄弟组件通信

在公共的父组件有一个标志位,组件A通过$emit('event', value)来修改该标志位,将该标志位传给组件B,组件B watch该标志位,触发行为。

小示例

当外部某一组件想触发keep-alive其中一个非激活状态的component的方法时,可以加个标志位,组件内watch该标志位, 变化时触发指定方法。

this.$refs.component 是指的实时的当前激活的组件

<keep-alive>
    <component :is="currentFollowComponent"
               :project-refresh.sync="followProjectRefresh"
    >
    </component>
</keep-alive>

littlelightss
406 声望14 粉丝