标签:没有 task hello 最小化 splice 发布者 预编译 lag 属性
vue 实例从创建到销毁的过程就是生命周期。
也就是从开始创建、初始化数据、编译模板、挂在 dom -> 渲染、更新 -> 渲染、卸载等一系列过程
生命周期中有多个事件钩子,让我们在控制整个 vue 实例的过程时更容易形成好的逻辑
8个阶段:创建前/后、载入前/后、更新前/后、销毁前/后
第一次加载会触发 beforeCreate、created、beforeMount、mounted
mounted
生命周期钩子的一些使用方法:
beforecreate : 可以在这加个loading事件,在加载实例时触发
created : 初始化完成时的事件写在这里,(首次拿到data中的值)如在这结束loading事件,异步请求也适宜在这里调用
mounted : 挂载元素,获取到DOM节点 updated : 如果对数据统一处理,在这里写上相应函数
beforeDestroy : 可以做一个确认停止事件的确认框 nextTick : 更新数据后立即操作dom
总共分为8个阶段创建前/后,载入前/后,更新前/后,销毁前/后。
创建前/后
在beforeCreated阶段,vue实例的挂载元素$el和数据对象data都为undefined,还未初始化。
在created阶段,vue实例的数据对象data有了,$el还没有。
载入前/后
在beforeMount阶段,vue实例的$el和data都初始化了,但还是挂载之前为虚拟的dom节点,data.message还未替换。
在mounted阶段,vue实例挂载完成,data.message成功渲染。
更新前/后
当data变化时,会触发beforeUpdate和updated方法。
销毁前/后
在执行destroy方法后,对data的改变不会再触发周期函数,说明此时vue实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在
在数据渲染的时候使用prop渲染数据,将prop绑定到子组件自身的数据上,修改数据更新自身数据来代替prop,watch子组件自身数据的改变,触发事件通知父组件更改绑定到prop的数据。
vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
具体步骤:
第一步:需要 observe 的数据对象进行递归遍历,包括子属性对象的属性,都加上 setter 和 getter
这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化
第二步:compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图
第三步:Watcher订阅者是Observer和Compile之间通信的桥梁,主要做的事情是:
1、在自身实例化时往属性订阅器(dep)里面添加自己
2、自身必须有一个update()方法
3、待属性变动dep.notice()通知时,能调用自身的 update() 方法,并触发Compile中绑定的回调,则功成身退。
第四步:MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。
三种,
(1)、全局导航钩子
router.beforeEach(to, from, next),
router.beforeResolve(to, from, next),
router.afterEach(to, from ,next)
(2)、组件内钩子
beforeRouteEnter, beforeRouteUpdate, beforeRouteLeave
(3)、单独路由独享组件
beforeEnter
vuex 是专门为 vue 开发的数据状态管理模式。组件之间数据状态共享
使用场景:音乐播放、登录状态、购物车
三种,
(1)、全局导航钩子
router.beforeEach(to, from, next),
router.beforeResolve(to, from, next),
router.afterEach(to, from ,next)
(2)、组件内钩子
beforeRouteEnter, beforeRouteUpdate, beforeRouteLeave
(3)、单独路由独享组件
beforeEnter
全局定义指令:在 vue 对象的 directive 方法里面有两个参数, 一个是指令名称, 另一个是函数。
组件内定义指令:directives
钩子函数: bind(绑定事件出发)、inserted(节点插入时候触发)、update(组件内相关更新)
钩子函数参数: el、binding
vuex 是专门为 vue 开发的数据状态管理模式。组件之间数据状态共享
使用场景:音乐播放、登录状态、购物车
有 5 种,分别是 state、getter、mutation、action、module
state负责存储整个应用的状态数据,要注意在入口文件main.js注入store对象,就可以在根组件下的子组件使用this.$store.state获取状态了。
mutation里面写着改变状态数据的方法(一定要写在这里),mutation是同步事件要注意,里面的方法不能写异步的,组件中触发一个mutation的方法store.commit(mutationName)。
action也是一个改变状态数据的事件,但不同的是action改变状态是通过调用mutation来实现的,注意action是个异步事件。直接触发action就使用this.$store.dispatch(actionName)。 |
object是引用类型数据,如果不用function,每个组件的data都是内存的同一个地址,一个数据改变了其他的也改变了。
https://www.cnblogs.com/chinabin1993/p/9115396.html
当 v-if
与 v-for
一起使用时,v-for
具有比 v-if
更高的优先级,这意味着 v-if
将分别重复运行于每个 v-for
循环中
所以,不推荐v-if和v-for同时使用
get和set,分别用来获取计算属性和设置计算属性。
<!--直接复制的官网示例-->
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ‘ ‘ + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(‘ ‘)
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
如果只是监听obj内的某一个属性变化,可以直接obj.key进行监听。
watch: {
‘obj.question‘: function (newQuestion, oldQuestion) {
this.answer = ‘Waiting for you to stop typing...‘
this.debouncedGetAnswer()
}
}
如果对整个obj深层监听
watch: {
obj: {
handler: function (newQuestion, oldQuestion) {
this.answer = ‘Waiting for you to stop typing...‘
this.debouncedGetAnswer()
},
deep: true,
immediate: true
}
}
immediate的作用:当值第一次进行绑定的时候并不会触发watch监听,使用immediate则可以在最初绑定的时候执行。
v-for循环式为什么要加key
ue和react的虚拟DOM的Diff算法大致相同,其核心是基于两个简单的假设
首先讲一下diff算法的处理方法,对操作前后的dom树同一层的节点进行对比,一层一层对比,如下图:
当某一层有很多相同的节点时,也就是列表节点时,Diff算法的更新过程默认情况下也是遵循以上原则。
比如一下这个情况:
我们希望可以在B和C之间加一个F,Diff算法默认执行起来是这样的:
即把C更新成F,D更新成C,E更新成D,最后再插入E,是不是很没有效率?
所以我们需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点。
vue中列表循环需加:key="唯一标识" 唯一标识可以是item里面id index等,因为vue组件高度复用增加Key可以标识组件的唯一性,为了更好地区别各个组件 key的作用主要是为了高效的更新虚拟DOM
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。(官网解释)
解决的问题:有些时候在改变数据后立即要对dom进行操作,此时获取到的dom仍是获取到的是数据刷新前的dom,无法满足需要,这个时候就用到了$nextTick。
vue中的$set用过吗?为什么要用他,解决了什么问题
向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新属性,因为 Vue 无法探测普通的新增属性 (比如 this.myObject.newProperty = ‘hi‘)如果在实例创建之后添加新的属性到实例上,它不会触发视图更新(官方示例)
我自己的理解就是,在vue中对一个对象内部进行一些修改时,vue没有监听到变化无法触发视图的更新,此时来使用$set来触发更新,使视图更新为最新的数据。
https://www.jianshu.com/p/71b1807b1815
const state = Vue.observable({ count: 0 })
const Demo = {
render(h) {
return h(‘button‘, {
on: { click: () => { state.count++ }}
}, `count is: ${state.count}`)
}
}
A、B、C三个组件依次嵌套,A组件和C组件之间跨级通信
<template>
<div class="child-1">
<p>in child1:</p>
<p>props: {{pChild1}}</p>
<p>$attrs: {{$attrs}}</p>
<hr>
<!-- C组件中能直接触发test的原因在于 B组件调用C组件时 使用 v-on 绑定了$listeners 属性 -->
<!-- 通过v-bind 绑定$attrs属性,C组件可以直接获取到A组件中传递下来的props
(除了B组件中props声明的) -->
<child2 v-bind="$attrs" v-on="$listeners"></child2>
</div>
</template>
<script>
import Child2 from ‘./Child2.vue‘;
export default {
props: [‘pChild1‘],
data () {
return {};
},
inheritAttrs: false,
components: { Child2 },
mounted () {
this.$emit(‘test1‘);
}
};
</script>
v-bind属性$attr,保证C组件能够获取到A组件传递下来的props(除props属性中声明的属性以外);
而v-bind属性$listeners,则保证C组件能直接调用A组件的方法。
其实就是将需要缓存的VNode节点保存在this.cache中/在render时,如果VNode的name符合在缓存条件(可以用include以及exclude控制),则会从this.cache中取出之前缓存的VNode实例进行渲染。
组件一旦被<keep-alive></keep-alive>,那么再次渲染的时候不会执行created,mounted等钩子函数,但我们很多业务场景都希望在我们缓存的组件再次被渲染的时候做一些事情,Vue提供了actived钩子函数,他的执行是在<keep-alive></keep-alive>包裹的组件渲染的时候。deactived钩子函数发生在destory钩子函数。
vue data为什么是函数
Object是引用类型数据,如果不用function,每个组件的data都是内存的同一个地址,一个数据改变了其他也会改变。
hash —— 即地址栏 URL 中的 # 符号,比如这个 URL:http://www.abc.com/#/hello,hash 的值为 #/hello,它的特点在于:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面
history —— 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定浏览器支持)这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求7.
一方面modal层通过defineProperty来劫持每个属性,一旦监听到变化通过相关的页面元素更新。另一方面通过编译模板文件,为控件的v-model绑定input事件,从而页面输入能实时更新相关data属性值。
cnpm i vue-i18n
不能同名 因为不管是计算属性还是 data 还是 props 都会被挂载在 vm 实例上,因此 这三个都不能同名
eslint 不允许你这么做
Method "${key}" has already been defined as a data property.
静态资源static存放位置放在src目录下
<img class="logo" :src="logo" alt="公司logo">
export default {
name: "HelloWorld",
data() {
return {
logo:require("./../assets/images/logo.png"),
};
}
};
</script>
因为动态添加src被当做静态资源处理了,没有进行编译,所以要加上require。
activated: 页面第一次进入的时候,钩子触发的顺序是 created->mounted->activated
deactivated: 页面退出的时候会触发 deactivated,当再次前进或者后退的时候只触发 activated
便于 diff 算法的更新,key 的唯一性,能让算法更快的找到需要更新的 dom,需要注意的是,key 要唯一,不然会出现很隐蔽性的更新问题。
vm.$data 可以获取当前状态下的 data
vm.$options.data 可以获取到组件初始化状态下的 data
Object.assign(this.$data, this.$options.data())
设置comments
一些简单的跨组件数据状态共享,简单,轻量
实现组件的私有化,不对全局造成样式污染,表示当前style属性只属于当前模
块
vue处理边界情况之$root,$parents,$refs
root和parent异同
相同点:都能实现访问父组件的属性和方法
不同点:如果存在多级子组件,parent访问到的是最近一级的父组件,root得到的是它的根组件通过在子组件标签定义 ref 属性,在父组件中可以使用$refs 访问子组件实例
1. 直接在子组件中通过this.$parent.event来调用父组件的方法
2.在子组件里用$emit
向父组件触发一个事件,父组件监听这个事件就行了。
3.父组件把方法传入子组件中,在子组件里直接调用这个方法
watch属性:watch是vue实列的一个属性,它是一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个属性。
var vm = new Vue({
data: {
a: 1,
b: 2,
c: 3
},
watch: {
//第一种写法 适用于普通变量(简单类型的值的观测写法)
a: function (val, oldVal) {
console.log(‘new: %s, old: %s‘, val, oldVal)
},
// 第二种写法:方法名
b: ‘someMethod‘,
// 第三种写法:深度 watcher(能观测对象c下多重属性变化)(复杂类型的值的观测写法)
c: {
//当c变化后会回调handler函数
handler: function (val, oldVal) { /* ... */ },
deep: true
}
}
})
vm.a = 2 // -> new: 2, old: 1
注意:不能使用箭头函数定义watcher(回调)函数,因为箭头函数绑定了父级作用域的上下文,所以里面的 this 将不会按照期望指向 Vue 实例**
watch: {
// 这里面的this指向了vue实列 ----Vue$3 {_uid: 0, _isVue: true, $options: Object, _renderProxy: Proxy, _self: Vue$3…}
a: function (val, oldVal) {
console.log(‘new: %s, old: %s‘, val, oldVal)
},
// 箭头函数:这里的this指向的是window-----Window {stop: function, open: function, alert: function, confirm: function, prompt: function…}
b:()=>{
console.log(this.a);
},
// 深度 watcher
c: {
handler: function (val, oldVal) { /* ... */ },
deep: true
}
}
watch的实战-观测数组内所有对象的某个值的变化:
我们常常会遇到请求回来的数据,计算订单的数量和或价格,值变化的时候数量显示也要变化:
<body>
<div id="app">
<span>{{count}}</span>
</div>
<script>
var vm = new Vue({
el:‘#app‘,
data: {
count:0,
items : [
{
id: 336,
title: ‘炒肉‘,
count: 1,
price: 106
},
{
id: 337,
title: ‘生菜‘,
count: 2,
price: 225
}
]
},
watch: {
"items":{
handler(){
this.count = 0
this.items.forEach((item)=>{
this.count +=item.count
});
},
deep:true
}
}
})
</script>
</body>
Vue里面methods对象里面如果使用箭头函数会导致this指向不是vue实例,而是一个xxx.a的一个类,尽量不要在vue所定义的字段里面使用箭头函数。
1. vue-cli有一个static文件夹,存放静态文件,favicon图片放到该文件夹下。在index.html中添加。
<link rel="shortcut icon" href="static/刚刚生成.ico的地址" type="image/x-icon" /><!-- 必须 -->
刷新浏览器就会更新,如果没有效果,则查看build文件夹:build/webpack.dev.conf.js,如果不显示则配置下
new HtmlWebpackPlugin({
filename: ‘index.html‘,
template: ‘index.html‘,
inject: true,
favicon:‘../stastic/favicon.ico‘
}),
html-webpack-plugin插件需要配置两处,一处是在开发环境下配置,另一处是在打包后的环境下配置
2.服务器动态获取图片
Vue的兼容性解决方案Babel-polyfill
:ES6的转码。IE的兼容
答:分为errorCaptured与errorHandler。
errorCaptured是组件内部钩子,可捕捉本组件与子孙组件抛出的错误,接收error、vm、info三个参数,
return false后可以阻止错误继续向上抛出。
errorHandler为全局钩子,使用Vue.config.errorHandler配置,接收参数与errorCaptured一致,
2.6后可捕捉v-on与promise链的错误,可用于统一错误处理与错误兜底。
currentTarge 是事件绑定的元素而 target 是鼠标触发的元素
答:都不是必须的
如果是普通组件那么只能是一个静态html
如果是函数式组件, 那么可以直接使用props等函数式组件属性
1.使用this.$forceUpdate强制重新渲染
2.使用v-if指令
传递一个对象出去
存一份 defaultData 方便直接初始化,特别是带表单的弹窗也写在一起没有生命周期的时候。
https://www.cnblogs.com/zhouqy/p/10311802.html
加入.native修饰符
v-on:click.native="doTheThing"
报错 "Method ‘xxx‘ has already been defined as a data property"
键名优先级:props > data > methods
以 _
或 $
开头的属性 不会 被 Vue 实例代理,因为它们可能和 Vue 内置的属性、API 方法冲突。你可以使用例如 vm.$data._property
的方式访问这些属性。
在遍历对象时,会按 Object.keys() 的结果遍历,但是不能保证它的结果在不同的 JavaScript
引擎下都一致。
<div id="example">
<!--循环数字-->
<span v-for="count in 10">{{count}}</span>
<!--循环数组-->
<span v-for="(u,i) in user">--每个数组值--{{u}}--索引地址index--{{i}}</span>
<!--循环对象数组-->
<span v-for="(u,i) in object">---{{u.a}}---索引index--{{i}}</span>
<!--循环对象-->
<span v-for="(v,k,i) in app">---值value---{{v}}---键key---{{k}}----索引index----{{i}}</span>
</div>
extends选项允许声明扩展另一个组件
不对原组件进行更改的:
使用Vue.extend直接扩展
使用Vue.mixin全局混入
HOC封装
可以加slot扩展
组件传值,祖孙组件有跨度的传值。
1.检查nginx配置,是否正确设置了资源映射条件;
2.检查vue.config.js中是否配置了publicPath,若有则检查是否和项目资源文件在服务器摆放位置一致。
单次触发的场景
v-once这个指令不需要任何表达式,它的作用就是定义它的元素或组件只会渲染一次,包括元素或者组件的所有字节点。首次渲染后,不再随着数据的改变而重新渲染。也就是说使用v-once,那么该块都将被视为静态内容。
input标签v-model用lazy修饰之后,vue并不会立即监听input Value的改变,会在input失去焦点之后,
才会触发input Value的改变
lazy:使用了这个修饰符将会从“input事件”变成change事件进行同步
(另外补充number和trim)
<div id="example">
<input type="text" v-model.lazy="message">
<p>{{ message }}</p>
</div>
new Vue({
el:"#example",
data:{
message:""
}
})
number
首先谁明这个number并不是限制用户的输入,而是将用户输入的数据尝试绑定为 js 中的 number 类型
举个例子,如果用户输入300
,data 中绑定的其实是‘300‘
(string),添加 number 指令后可以得到 300
(number)的绑定结果。
而如果用户输入的不是数字,这个指令并不会产生任何效果。
<div id="example">
2 <input type="text" v-model.number="message">
3 <p>{{ message }}</p>
4 <button @click="assay()">获取当前的类型</button>
5 </div>
new Vue({
2 el:"#example",
3 data:{
4 message:""
5 },
6 methods:{
7 assay(){
8 alert(typeof this.message);
9 }
10 }
11 })
当不加number修饰符输入123456..数字的时候显示的类型为string
而加了number修饰符就变成了number类型
当你输入的不是数字就不起作用了
trim可以用来过滤前后的空格
当使用了trim修饰符后
因为"树"状数据结构,肯定要有个"根",一个遍历起始点吧,我是这么理解的。
在组件内的beforeRouteLeave中移除事件监听
webpack:output.path
vue-cli3: outputDir
1.app定义一个方法传给我们,根据方法调用
2.jsBridge,建立连接,然后相互调用
v-for循环list,根据索引值设置active的样式和显示内容
https://blog.csdn.net/badmoonc/article/details/80380557
当前注册一个vue组件定义 name 为 ‘node-tree‘ ,在组件 template 内部调用 实现递归。
通过this.$refs
通过this.$parent
通过this.$root
Object.defineProperty定义新属性或修改原有的属性;
vue的数据双向绑定的原理就是用的Object.defineProperty这个方法,里面定义了setter和getter方法,
通过观察者模式(发布订阅模式)来监听数据的变化,从而做相应的逻辑处理。
肯定要,一方面是绑定多次,另一方面是函数没释放会内存溢出
当生命周期销毁后,并没有将组件中的计时器销毁,虽然页面上看不出来,但是如果在控制台打印的话
,会发现计时器还在运行,所以要销毁计时器,避免代码一直执行
v-if=‘false‘
对应vue渲染大量数据时可以考虑下面几点:
1. 异步渲染组件:因为组件渲染太多,影响页面的渲染时间,所有可以延迟组件渲染,可以考虑v-if处理
2. 可以使用虚拟滚动的组件:参考使用这个插件
vue中使用匿名函数,会出现this指针改变。
解决方法
1.使用箭头函数
2.定义变量绑定this至vue对象
jsx不是一门新的语言,是一种新的语法糖。让我们在js中可以编写像html一样的代码。
允许XML语法直接加入到JavaScript代码中,让你能够高效的通过代码而不是模板来定义界面
官方样式指南里是这样写的:
“组件命名应当是多个单词的,但根目录下的App组件或Vue提供的如<transition>,
<component>内置组件除外”
这样做可以避免跟现有的以及未来的 HTML 元素相冲突,因为所有的 HTML 元素名称都是单个单词的。
配置ts-loader,tsconfig
增加类型扩展,让ts识别vue文件
vue文件中script里面换成ts写法, 需要增加几个ts扩展的package, 比如vue-property-decorator
当做一个不可见的包裹元素,减少不必要的DOM元素,整个结构会更加清晰
动态组件,当你多个组件需要通过 v-if 切换时,可以使用 is 来简化代码
vue中is的属性引入是为了解决dom结构中对放入html的元素有限制的问题
vue中is的属性引入是为了解决dom结构中对放入html的元素有限制的问题
:class 绑定变量 绑定对象 绑定一个数组 绑定三元表达式
:style 绑定变量 绑定对象 绑定函数返回值 绑定三元表达式
函数式组件:
需要提供一个render方法, 接受一个参数(createElement函数), 方法内根据业务逻辑,
通过createElement创建vnodes,最后return vnodes
createElement函数, 三个参数, 第一个参数是html标签或自定义组件,
第二个参数一个obj(包含props, on...等等), 第三个参数children(通过createElement构建,
或者字符串)
delimiters
项目使用keep-alive时,可搭配组件name进行缓存过滤
DOM做递归组件时需要调用自身name
vue-devtools调试工具里显示的组见名称是由vue中组件name决定的
通过在父组件中provide一些数据然后再所有子组件中都可以通过inject获取使用该参数,
主要是为了解决一些循环组件比如tree, menu, list等, 传参困难, 并且难以管理的问题,
主要用于组件封装, 常见于一些ui组件库
有,devtools确实是个好东西,大力协助vue项目开发,传参,数据展示,用于调试vue应用,
这可以极大地提高我们的调试效率
slot, 插槽, 在使用组件的时候, 在组建内部插入东西.
组件封装的时候最常使用到
component, vue的内置组件, 说实话, 如果不是特殊场景不要去使用, 容易使人混乱
Number, String, Boolean, Array, Function, Object
单个类型就用Number等基础类型,多个类型用数组,必填的话设置require为true,
默认值的话设置default,对象和数组设置默认用工厂函数,自定义验证函数validator。
可以在路由meta中加入参数, 对打开的路由进行keep-alive的判断, 通过钩子active等
第一: 容错处理, 这个要做好, 极端场景要考虑到, 不能我传错了一个参数你就原地爆炸
第二: 缺省值(默认值)要有, 一般把应用较多的设为缺省值
第三: 颗粒化, 把组件拆分出来.
第四: 一切皆可配置, 如有必要, 组件里面使用中文标点符号, 还是英文的标点符号, 都要考虑到
第五: 场景化, 如一个dialog弹出, 还需要根据不同的状态封装成success, waring, 等
第六: 有详细的文档/注释和变更历史, 能查到来龙去脉, 新版本加了什么功能是因为什么
第七: 组件名称, 参数prop, emit, 名称设计要通俗易懂, 最好能做到代码即注释这种程度
第八: 可拓展性, 前期可能不需要这个功能, 但是后期可能会用上, 要预留什么, 要注意什么, 心里要有逼数
第九: 规范化,我这个input组件, 叫on-change, 我另外一个select组件叫change, 信不信老子捶死你
第十: 分阶段: 不是什么都要一期开发完成看具体业务, 如果一个select, 我只是个简单的select功能,
、
如一个list中某一个数据发生变更时,
vue中会对整个list进行遍历, 判断使用到的某些属性是否发生变更, 从而更新发生变更的item
所以key属性才会显得很重要, 它会告诉你, 我那个item发生变更, 而不是去检测整个list
异步路由和异步加载
还有分屏加载, 按需加载, 延时加载图片等, cdn, 域名才分
vendor.js, app.js, app.css,
1.xxx.js
2.xxx.js
如果有设置到单独提取css的话
还有
1.xxx.css
......
ajax是概念 异步交换数据的概念
fetch是浏览器提供的webAPI 原理是基于xmlHttpRequest的封装
axios是第三方库 基于xmlHttpRequest的封装 使用更便捷
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
watch{
arr(val oval){
}
}
[@click](https://github.com/click)=‘handleClick($events)‘
在config文件夹中找到index.js打开把
assetsPublicPath: ‘/‘
改成
assetsPublicPath: ‘./‘
再次执行 npm run build 就可以了。
/开头表示根目录开始的路径
./开头表示当前目录开始的路径,可省略
绝对路径 相当路径
单向数据流:所有状态的改变可记录、可跟踪,源头易追溯;所有数据只有一份,组件数据只有唯一的入口和
出口,使得程序更直观更容易理解,有利于应用的可维护性;一旦数据变化,就去更新页面(data-页面),但是
没有(页面-data);如果用户在页面上做了变动,那么就手动收集起来(双向是自动),合并到原有的数据中。
双向数据流:无论数据改变,或是用户操作,都能带来互相的变动,自动更新。
vant,mint等等吧,各有各的坑,不过大部分都是可以查到解决方案的
1)所有同步任务都在主线程上执行,形成一个[执行栈](http://www.ruanyifeng.com/blog/2013/11/
stack.html)(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之
中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。
那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。
v-cloak指令只是在标签中加入一个v-cloak自定义属性,在HTML还编译完成之后该属性会被删除。
当网络较慢,网页还在加载 Vue.js ,而导致 Vue 来不及渲染,这时页面就会显示出 Vue 源代码。
我们可以使用 v-cloak 指令来解决这一问题
v-pre可以用来阻止预编译,有v-pre指令的标签内部的内容不会被编译,会原样输出。
事件修饰符.stop .prevent .capture .self .once .passive
.stop 阻止函数的传递
.prevent 阻止默认程序,比如form表单中的summit提交按钮,会自己提交
.capture事件修饰符的作用添加事件侦听器时使用事件捕获模式
.self修饰符只有在点击事件绑定的元素与当前被点击元素一致时才触发点击事件。
prevent 是拦截默认事件,passive是不拦截默认事件( 这里一般用在滚动监听,@scoll,@touchmove 。
因为滚动监听过程中,移动每个像素都会产生一次事件,每次都使用内核线程查询prevent会使滑动卡顿。
我们通过passive将内核线程查询跳过,可以大大提升滑动的流畅度。
)
表单修饰符.number .lazy .trim
目前只知道用来修改 属性的get set方法 vue3 来替换Object.defineProperty。一方面提高性能
另一方面可以免去给数组重写方法。
{{item.title}}
<dl v-if="item.list.length > 0">
<dd v-for="(item2,index2) in item.list" :index="index2" :key="item2.title">
<router-link :to="item2.route" exact>{{item2.title}}</router-link>
</dd>
</dl>
</li>
</ul>
这个……全局的theme属性然后做class判断或者加载不同的样式文件。一种是编译时换肤 一种是用户操作换肤。编译时换肤可以通过css in js相关技术修改css预处理器的变量 。用户操作换肤 只能内置一些styleb变量供用户选择了
1.在切换tab时 第二个tab的图表无法正常显示 切换tab时使用方法@tab-click="handleClick"加载图表的
render函数
2.vue 没用过echarts react到是用过 不过我想应该差不多 ,多注意dom的渲染时机
和chart的实例化时机 在相应的生命周期方法中做操作。结合强制刷新 应该就能解决大部分问题
把官网地址贴给他
SSR服务端渲染,解决SEO问题,用next吧,最佳实践
1.router 是不是hash 是否需要配置nginx , publicPath , 是不是要配置cdn
2.主要assetsPublicPath、publicPath 两个
一.使用vue的transition标签结合css样式完成动画
二.利用animate.css结合transition实现动画
三.利用 vue中的钩子函数实现动画
created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图。
mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。
其实两者比较好理解,通常created使用的次数多,而mounted通常是在一些插件的使用或者组件的使用中进
行操作,比如插件chart.js的使用: var ctx = document.getElementById(ID);通常会有这一步,
而如果你写入组件中,你会发现在created中无法对chart进行一些初始化配置,一定要等这个html渲染完后
才可以进行,那么mounted就是不二之选。
所有的 prop 都使得其父子 prop 之间形成了一个 单向下行绑定
父级 prop 的更新会向下流动到子组件中,但是反过来则不行
2.3.0+ 新增 .sync 修饰符
以 update:my-prop-name 的模式触发事件实现 上行绑定 最终实现 双向绑定
举个栗子
this.$emit(‘update:title‘, newTitle)
ref
所以我们可以通过process.env.npm_config_report获取它的值为true,
由于webpack.prod.conf.js调用config/index.js中的bundleAnalyzerReport
所以会调用webpack-bundle-analyzer插件
1、在webpack.base.conf.js新增externals配置,表示不需要打包的文件,
然后在index.html中通过CDN引入
externals: {
"vue": "Vue",
"vue-router": "VueRouter",
"vuex": "Vuex",
"element-ui": "ELEMENT",
"BMap": "BMap"
}
webpack 的devServer配置下代理
可以通过指令去做
Vue.directive(‘hasPermission‘, {
bind(el, binding, vnode) {
const permissions = vnode.context.$store.state.account.permissions
if (binding.value === ‘‘) return
const value = binding.value.split(‘,‘)
let flag = true
for (const v of value) {
if (!permissions.includes(v)) {
flag = false
}
}
if (!flag) {
if (!el.parentNode) {
el.style.display = ‘none‘
} else {
el.parentNode.removeChild(el)
}
}
}
}
新建page目录与components同级
components
---common //公共部分
---header
---footer
---content //内容部分
---组件1
---组件2
page //各页面入口
---home.vue
---content1
---content2
---content3
---content...
vue两大特点:响应式编程、组件化
vue的优势:轻量级框架、简单易学、双向数据绑定、组件化、视图、数据和结构的分离、虚拟DOM、运行速度快
element- ui
axios
less
https://www.cnblogs.com/zhangruiqi/p/9412948.html
不知道
配合相应的loader 想咋写就咋写
解析和转换 .vue 文件,提取出其中的逻辑代码 script、样式代码 style、以及 HTML 模版 template,
再分别把它们交给对应的 Loader 去处理。
async ,await
SPA应用就是一个web应用,可理解为:是一种只需要将单个页面加载到服务器之中的web应用程序。
当浏览器向服务器发出第一个请求时,服务器会返回一个index.html文件,它所需的js,css等会在显示时
统一加载,部分页面需要时加载。
优点:
1.良好的交互式体验。意思是:用户无需刷新页面,获取数据通过异步ajax获取,页面显示流畅
2.良好的前后端分离模式(MVVM),减轻服务端压力。服务器只需要输出数据就可以,不用管逻辑和页面
展示,吞吐能力会提高几倍
3.共用同一套后端程序代码,不用修改就可用于web界面,手机和平板等客户端设备
缺点:
1.不利于SEO优化
2.由于单页应用在一个页面中显示,所以不可以使用浏览器自带的前进后退功能,想要实现页面切换需要自己
进行管理
3.首屏加载过慢(初次加载耗时多),原因是:为了实现单页web应用功能及展示效果,在页面初始化的时候
就会将js,css等统一加载,部分页面在需要时加载。当然也有解决方法。
解决方法:①使用路由懒加载 ②开启Gzip压缩 ③使用webpack的externals属性把不需要的库文件分离出去,
减少打包后文件的大小 ④使用vue的服务端渲染(SSR)
1、绝对路径直接引入
在index.html中用script引入
<script src="./static/jquery-1.12.4.js"></script>
然后在webpack中配置external
externals: { ‘jquery‘: ‘jQuery‘ }
在组件中使用时import
import $ from ‘jquery‘
2 、在webpack中配置alias
resolve: { extensions: [‘.js‘, ‘.vue‘, ‘.json‘], alias: { ‘@‘: resolve(‘src‘), ‘jquery‘: resolve(‘static/jquery-1.12.4.js‘) } }
然后在组件中import
3、在webpack中配置plugins
plugins: [ new webpack.ProvidePlugin({ $: ‘jquery‘ }) ]
全局使用,但在使用eslint情况下会报错,需要在使用了 $ 的代码前添加 /* eslint-disable*/ 来去掉 ESLint 的检查。
{{600 | money}} //¥600.00
filters:{
money:val=>{
return `¥${val}.00`
}
}
v-if v-for v-bind v-model
一般在created 因为在这个生命周期我们常用到的都已经初始化好了
如果涉及dom 那就mounted
也是组件传值的一种方式(例如兄弟组件)
mounted生命周期
beforeCreate, created, beforeMount, mounted
Vue生命周期可以总共分为8个阶段:
beforeCreate(创建前),
created(创建后),
beforeMount(载入前),
mounted(载入后),
beforeUpdate(更新前),
updated(更新后),
beforeDestroy(销毁前),
destroyed(销毁后)
相当于一个事件,
cancelToken
组件化开发 复用性
可以
两部分 一部分 数据->虚拟dom->dom, 另一部分 响应式数据
这两部分大大节省了开发者对数据变动转换到页面显示的操作,可以让开发者聚焦业务,聚焦数据的处理。
1.通过Gzip压缩
2.使用路由懒加载
3.利用webpack中的externals这个属性把打包后不需要打包的库文件都分离出去,减小项目打包后的大小
4.使用SSR渲染
delete:只是被删除数组成员变为 empty / undefined,其他元素键值不变
Vue.delete:直接删了数组成员,并改变了数组的键值
(对象是响应式的,确保删除能触发更新视图,这个方法主要用于避开 Vue 不能检测到属性被删除的限制)
添加成功,但是视图未更新,$set()方法解决
Vue组件(component)用来构成你的App的业务模块,它的目标是App.vue。
Vue插件(plugin) 用来增强你的技术栈的功能模块, 它的目标是Vue本身。(插件是对Vue的功能的增强和补充)
el: 把当前实例挂载在元素上
template: 实例模版, 可以是.vue中的template, 也可以是template选项, 最终会编译成render函数
render: 不需要通过编译的可执行函数
template和render, 开发时各有优缺点, 不过在线上尽量不要有template
render, 没有则去编译
编译vdom
对实例进行watch
有个参数`immediate`
‘obj.xx‘: { handler: function(val) {}, deep:true }
npm 安装 然后再main.js 引入 最后 vue.use(插件名)
保留组件状态 避免重新渲染
<style scoped> </style>
对表单添加rules 和对应的prop
若是循环input的话,则需要index来确定是哪一行哪一个的input,然后在进行验证。
例子:在对应的el-form-item 中的prop="‘userList.‘+ index +‘.name‘"来进行判断。
在单个xx.vue文件最后多写一对<style>,即有两对style标签,一对有scoped,一对没有scoped。
若果写在有scoped属性的style标签里:覆盖的样式不会生效,需写在没有scoped属性的style标签内。
可以通过添加 !important 修饰符提高层级,例如 分页背景色全局修改
.el-pagination {
background: #29a88d !important;
}
如果多个文件用到了同一个element组件,但是要求组件样式不一样,解决办法:在选择器的前面添加一个ID选择器来限制作用范围
或浏览https://blog.csdn.net/bamboozjy/article/details/81629381
首先,通过接口请求需要显示的表头数据。
其次,要在显示的表格内对应要显示的内容。
处理数据,将type一一对应,确保数据的准确性。
返回数据类型:
处理之后的数据
代码展示
这样请求的动态表头以及数据就可以一一对应显示出来
表格下拉 唯一id tag显示区分 分级序号展示
例如:分页 多级表头数据展示 后台管理系统
Bootstrap Mint UI
标签:没有 task hello 最小化 splice 发布者 预编译 lag 属性
原文地址:https://www.cnblogs.com/liliandliangliang/p/13618569.html