双向绑定原理
使用Object.defineProperty(target, key, decription)
在description中设置get和set属性
同时运用观察者模式实现wather,用户数据和view视图的更新
VueRouter跳转和 location.href有什么区别?
vue路由hash模式,是通过监听hashChange事件实现页面对应渲染
location.href跳转并刷新页面
路由守卫
router.beforeResolve
router.beforeEach((to, from, next)=>{next()})
router.afterEach((to, from)=>{})
{path: '/foo',component: Foo,beforeEnter: (to, from, next) => {}}
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
}
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
}
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
vuex的使用
基础构成:
state:存储数据;
getters:派生数据,对state中的数据进行预处理;
mutations:更新数据的方法;
actions:调用mutations方法,更新state数据;
plugins:实现配置
持久化存储方案:
import VuexPersist from 'vuex-persist';
const vuexLocal = new VuexPersist({
storage: window.sessionStorage
});
plugins: [vuexLocal.plugin]
具体使用:
1.可以把$store挂载在main.js根下面;页面this.$store使用state和方法;
this.$store.phone;
this.$store.dispatch('setPhoneSync',{phone:'111'})
this.$store.commit('setPhone',{phone:'111'})
2.页面引入API解构使用
import {mapState,mapGetters,mapActions,mapMutations} from 'vuex';
computed:{
...mapState({
userInfo:'userInfo',
phone:'phone',
}),
},
methods:{
...mapActions({
getPhoneSync:'getPhoneSync',
}),
}
MVC和MVVM
Model View Controller
Model View viewModel
Vue生命周期
beforeCreate: 进行数据和方法的初始化;
created: 已经完成数据和方法的初始化;
beforeMount: 开始渲染dom
mounted:可以渲染dom
beforeUpdate: data中的数据即将被更新;
updated: data中的数据更新完毕;
beforeDestroy: 实例即将销毁;
destroyed:实例已被销毁;
data的值为什么是个函数
为了保证组件复用情况下data变量不被污染;每次都抛出一个全新的对象,隔离普通赋值
vue路由的几种模式
hash:
使用 URL hash 值来作路由。支持所有浏览器,包括不支持 HTML5 History Api 的浏览器;
监听hashChange事件,结合hashHistiry.push()和hashHistory.replace()
history :
依赖 HTML5 History API 和服务器配置。具体可以查看 HTML5 History 模式;
通过pushState和replaceState方法实现;
abstract :
支持所有 JavaScript 运行环境,如 Node.js 服务器端。
如果发现没有浏览器的 API,路由会自动强制进入这个模式.
vue中的事件修饰符
.prevent() 阻止默认事件;
.once() 只执行一次;
.stop() 阻止冒泡;
Vue中内置的组件
1. component组件
有两个属性---is inline-template 渲染一个‘元组件’为动态组件,按照'is'特性的值来渲染成那个组件
2. transition组件
为组件的载入和切换提供动画效果,具有非常强的可定制性,支持16个属性和12个事件
3. transition-group
作为多个元素/组件的过渡效果
4. keep-alive
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们
5. slot
作为组件模板之中的内容分发插槽,slot元素自身将被替换
SPA
单页面应用,只有一个入口html文件,解析/a/b渲染对应内容模块
vue和传统页面/jquery的区别
主张数据驱动视图,
不建议直接操作dom,
设置this.$refs满足某些场景,
实现了双向数据绑定;计算属性,监听属性等提升开发效率
单页面应用
虚拟dom和diff算法
易懂和利于维护的生命周期
很多地方去操作dom,不断造成页面的回流重绘
一般需要良好的代码习惯和规范才行,否则代码不利维护和阅读
computed & watch
寓意计算属性
内部需要return语句
只有依赖的值改变才会重新计算
寓意监听属性
可以监听data的值和路由
类似监听+事件回调
何时需要使用beforeDestroy
1. 在当前页面中使用了 $on 方法,那需要在组件销毁前解绑。
2. 清除自己定义的定时器
3. 解除事件的绑定 scroll mousemove
v-if & v-show
如果条件不成立不会渲染当前指令所在节点的 dom 元素
会正常渲染,只是切换当前节点的CSS属性为display:none;
组件通讯
父子组件:
父传子:通过v-bind传递props
子传父:自定义事件,子通过$emit(EventName,data)触发
兄弟组件:
1.可以先子传父然后再父传子。
无关系组件/兄弟组件:
1.注册EventBus事件总线,监听一方使用EventBus.$on,传值一方使用EventBus.$emit
2.使用vuex
v-model
实则是个语法糖,如input的v-model , 可以解析为:value和@input的结合
active-class是哪个组件属性
Vue-router模块中的router-link组件,设置激活时的样式。
vue-loader是什么?用途有哪些
解释:
解析和转换.vue文件。提取出其中的逻辑代码 script,样式代码style,以及HTML 模板template,
再分别把他们交给对应的loader去处理
用途:
使得js可以写es6,style样式可以写scss或less
说明vue项目里的每个目录和文件
node_modules
src/assets
src/components
src/router
src/view
src/app.vue
src/main.js
.gitignore
.babelrc
vue-router的动态路由
创建:path: '/details/:id'
取值:this.$route.params.id
vue路由跳转传参
参数不会显示在地址栏
刷新页面参数会丢失
参数会显示在路径上
刷新不会被清空
Vuex中actions和mutations的区别
更改是同步更改
参数:(state,payload)
用于用户执行直接数据更改
页面使用store.commit('名')触发
更改是异步操作
参数:(context,payload)
一般此类函数内用于发起接口请求或其他含副作用操作
页面使用store.dispath('名')触发
axios的常用设置
axios.defaults.baseURL = domain;
axios.defaults.timeout = 60000;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
axios.post
axios.get
axios.interceptors.request.use((config)=>{
return config;
},(error)=>{
return Promise.reject(error);
});
axios.interceptors.response.use((response)=>{
return response;
},(error)=>{
return Promise.reject(error);
})
vue自定义指令
Vue.directive('custom-hasbtn', {
inserted: function (el, binding) {
el.parentNode.removeChild(el);
}
})
keeep-alive的使用
一. 标签属性配置
标签作用:
缓存包裹的组件
标签属性:
include="ucenter,booklist" 表示当组件是ucenter,booklist才会被缓存
exclude="ucenter,booklist" 表示当组件除了ucenter,booklist才会被缓存
二. 路由meta配置
meta:{
keepAlive:false // 不需要被缓存的组件
}
组件的注册
Vue.component('my-component-name', { /* ... */ })
import table from '../table/table';
components:{
mytable:table
}
使用scss依赖模块
node-sass 和 sass-loader
dom循环绑定:key的作用
为了高效更新虚拟dom,节约计算时间
Vue的属性名称与method的方法名称一样时会发生什么问题
最好不要重复,重复会报错:<方法“xxx”已定义为数据属性>
vue为什么要求组件模板只能有一个根元素
整个项目只有一个index.html入口
vue需要生成虚拟domTree,根当然只能有一个
v-if和v-for为什么避免一起用
因为v-for优先级大于v-if,这样循环中会造成不必要的计算浪费
vue的过滤器
作用:处理数据
常用:时间格式化、千分符、数据过滤
<!-- 全局过滤器 -->
Vue.filter('formatTime', function (value) {
const date = new Date(val);
const hour = date.getHours();
const minutes = date.getMinutes();
const seconds = date.getSeconds();
return `${hour} : ${minutes} : ${seconds}`;
})
<!-- 组件内过滤器 -->
export default{
name:'home',
filters:{
formatTime(val){
const date = new Date(val);
const hour = date.getHours();
const minutes = date.getMinutes();
const seconds = date.getSeconds();
return `${hour} : ${minutes} : ${seconds}`;
}
}
}
Vue表单修饰符
lazy:
使用了这个修饰符将会从“input事件”变成change事件进行同步
number:
这个number并不是限制用户的输入,而是将用户输入的数据尝试绑定为js中的number类型
而如果用户输入的不是数字,这个指令并不会产生任何效果。
trim:
可以用来过滤前后的空格
vue路由懒加载
1. vue异步组件技术
{
path: '/home',
name: 'home',
component: resolve => require(['@/components/home'],resolve)
}
2. es提案的import()
{
path: '/home',
name: 'home',
component: () => import("@/components/HelloWorld")
}
3. webpack的require,ensure()
{
path: '/about',
name: 'about',
component: r => require.ensure([], () => r(require('@/components/about')), 'demo-01')
}
配置项目中404页面
path: '/*'
Vue配置跨域代理
proxyTable: {
'/api': {
target: 'http://localhost:8081',
changeOrigin: true,
pathRewrite: {
'^/api': '/apiABC'
}
}
}
vue切换页面的动画效果
结合transition标签实现
vue2和vue3的区别
1. proxy数据劫持代替object.defineProperty(优势:可以监听数组变化,可以直接修改对象属性等
2. Composition API,更好的逻辑复用和代码组织
3. 优化VirtualDom,使其编译更快,体积更小;
4. 更好的TypeScript支持,不再需要借助装饰器;
nexttick
定义:
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM
代码:
this.box.height='200'
Vue.nextTick(function () {
// box已经渲染为 height=200 了,此事做些什么
})
子组件可以修改props吗
答案:
1. 不建议修改props,但是可以修改
如何修改:
1. 如果props是字符串直接JS逻辑赋值修改会报错
2. 如果props是对象可以使用【propsName】.【属性名】=【赋值】的JS语法修改
3. 如果props用于表单,可以用 v-model 语法双向绑定,修改即生效