父子组件如何传递方法,方法预置一些参数
常见的问题/坑
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)
vue单文件组件返回值
import App from './App.vue'
console.log(App)
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>