Vue重点知识总结—基础篇(一)

1.Vue 中怎么自定义过滤器

可以用全局方法 Vue.filter() 注册一个自定义过滤器,它接收两个参数:过滤器 ID 和过滤器函数。过滤器函数以值为参数,返回转换后的值

Vue.filter('reverse', function (value) { 
    return value.split('').reverse().join('') 
})
<!-- 'abc' => 'cba' --> 
<span v-text="message | reverse"></span>

2.Vue 中怎么自定义指令

全局注册

// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})

局部注册

directives: {
  focus: {
    // 指令的定义
    inserted: function (el) {
      el.focus()
    }
  }
}

3.$route和$router的区别

$router 为 VueRouter 实例,想要导航到不同 URL,则使用 $router.push 方法$route 为当前 router 跳转对象里面可以获取 name 、 path 、 query 、 params 等

4.vue-router 使用params与query传参有什么区别

vue-router 可以通过 params 与 query 进行传参

// 传递
this.$router.push({path: './xxx', params: {xx:xxx}})
this.$router.push({path: './xxx', query: {xx:xxx}})

// 接收
this.$route.params
this.$route.query

params 是路由的一部分,必须要有。query 是拼接在 url 后面的参数,没有也可以。
params 不设置的时候,刷新页面或者返回参数会丢,query 则不会有这个问题。

5.vm.$mount()作用,$mount 和 el的区别

$mount和实例化Vue的el参数作用相同,是用来手动执行挂载到相应的dom元素。底层用的是querySelector()方法。若$mount不传参,则模板将被渲染为文档之外的的元素,并且你必须使用原生DOM API把实例的$el插入文档中(注意:当前vue实例或组件实例必须有template模板,否则$el为空),这样也可以渲染模板中的数据。

若使用script引入vue这种方式进行开发,非组件化开发,一般每个页面都会实例化一个新的vue实例。这时就不需要在实例中添加template模板,因为针对的是整个DOM。这时实例化时必须有el标签或调用$mount("dom")方法,且$mount方法必须传参,此时Vue会通过 el选项或$mount指定的挂载元素中提取出innerHtml作为其template模板编译渲染函数。否则数据或方法将无法挂载(vue不知道挂载到哪个元素上,使用appendChild挂载将无效,因为没有template)。

el和$mount区别

两者在使用效果上没有任何区别,都是为了将实例化后的vue挂载到指定的dom元素中。

如果在实例化vue的时候指定el,则该vue将会渲染在此el对应的dom中,反之,若没有指定el,则vue实例会处于一种“未挂载”的状态,此时可以通过$mount手动执行挂载

// 扩展组件
var MyComponent = Vue.extend({
  template: '<div>Hello!</div>'
})

// 创建并挂载到 #app (会替换 #app)
new MyComponent().$mount('#app')

// 同上
new MyComponent({ el: '#app' })

// 实例化Vue
new Vue({ el: '#app' })

// 同上
new Vue({}).$mount('#app')

// 或者,在文档之外渲染并且随后挂载
// 注意:挂载必须使用appendChild方法,若使用innerHtml是无法挂载的,因为$el是一个dom对象,不是标签字符串
var component = new MyComponent().$mount()
document.getElementById('app').appendChild(component.$el)

6.实例化Vue中的render参数作用(render:h=>h(App))

若使用script引入vue这种方式进行开发,实例化时并不需要render参数。因为没有组件template,此时Vue会通过 el选项或$mount指定的挂载元素中提取出innerHtml作为其template模板编译渲染函数。

若使用组件化开发,实例化vue时实际上需要一个外层template(比如app.vue),vue需要把这个模板先放到页面的某个标签内,再将数据挂载到这个标签。所以render方法就相当于组件中的templatecompoments两个参数的组合。只不过在组件实例中templatecompoments方式比render优先级高一些。而在vue实例中render优先级更高。

import Vue from 'vue';
import VueRouter from "vue-router";
import App from './App';
const app=new Vue({
    el:'#app',
    router,
    render:h => h(App) //App实际上就是一个组件
});

// 上述代码作用等同于
const app=new Vue({
    el:'#app',
    router,
    compoments:{
        App
    },
    template:"<App/>"
});

// 组件
var A = Vue.component("A",{
	template:"<div>{{notice}}</div>",
	data(){
		return{
			notice:"21212112"
		}
	}
})
const app=new Vue({
    el:'#app',
    render:h => h(A)
});

Vue 在创建 Vue 实例时,通过调用 render 方法来渲染实例的 DOM 树。Vue 在调用 render 方法时,会传入一个 createElement 函数作为参数,也就是这里的 h 的实参是 createElement 函数,然后 createElement 以App为参数进行调用,生成一个 VNode节点。render 函数得到这个VNode节点之后,返回给 Vue.jsmount 函数,渲染成真实 DOM 节点,并挂载到根节点上。

vue将createElement简化为h,因为它来自单词 hyperscript,这个单词通常用在虚拟dom的实现中。Hyperscript 本身是指生成HTML 结构的 script 脚本。

render:function(createElement){
    return creatElemnt(App);
}

7.Ajax请求放在哪个生命周期?

Ajax可以放到created及其之后的生命周期。

  1. created时候,DOM未挂载,这里请求的数据可以存到data中。但是无法操作dom,没办法将数据渲染到页面。
  2. mounted时DOM已挂载完成,这里可以操作DOM节点。一般情况下都放到mounted中。
  3. 生命周期时同步进行的,Ajax是异步进行的。为保证逻辑统一性,尽量将Ajax都放到同一个生命周期中。
  4. 服务端渲染时(SSR)不支持mounted(无DOM),所以放到created中。

8.何时需要使用beforeDestroy?

实例销毁之前钩子。在这里实例仍然可用。

  1. 可以解绑$on方法。使用$off方法。(在非父子组件通信时会借助中间Vue实例,然后使用vm.$emit()vm.$on()方法进行通信)
  2. 可以清除定时器。
  3. 可以移除绑定的事件监听。使用removeEventListener

9.Vue父子组件的生命周期调用顺序

渲染调用顺序:先父后子;渲染完成顺序:先子后父

父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 若还有嵌套子组件,则将子mounted缓存,继续下级子组件渲染 -> 父mounted

更新操作:先父后子;更新完成顺序:先子后父

父beforeUpdate -> 子beforeUpdate -> 子updated -> 父updated

销毁操作:先父后子;销毁完成顺序:先子后父

父beforeDestroy -> 子beforeDestroy -> 子destroyed -> 父destroyed

10.vue组件如何通信

父子通信:子组件通过 props 属性,绑定父组件数据,实现双方通信

子父通信:由于Vue数据传递是单向数据流(儿子不能直接改父亲)

  1. 事件监听方法:父组件通过$on监听,子组件 $emit 触发。(简易的发布-订阅)
  2. 父组件通过props给子组件传递一个方法,子组件调用这个方法。

其他通信方式:

  1. 通过$children $parent获取父子组件的实例来拿到父子相应的数据。
  2. 通过provideinject在父组件中提供数据,子组件进行注入(写插件使用,把provide挂到$options上,内部会挂到实例上vm._provided,子组件会直接将其挂到数据中,而且是响应式的)。
  3. 通过ref获取组件的实例,从而拿到组件的数据。(普通标签获取的事dom元素,组件标签获取的是组件实例)

非兄弟组件通信:

  1. 在组件结构相对简单情况下,可以通过兄弟组件中的父组件, 子组件先把数据传递给父组件,  父组件再传递给另外的子组件。
  2. Event Bus 实现跨组件通信(公共的vue实例进行通信),如 Vue.prototype.$bus = new Vue()
  3. 使用状态管理插件vuex
//使用中间vue实例实现子-子通信

//mid
Vue.prototype.$bus = new Vue()

//某子组件发消息
//....
methods: {
    tellname () {
       // 发出事件,传递数据,givename自定义事件
     this.$bus.$emit('givename', this.mybfname) 
  } 
}

//某子组件收消息

// 组件一加载就进行兄弟组件所发出的事件的监听
created () {
    // vm.$on(vue自定义的事件, 处理函数)
    // 处理函数有一个默认参数,就是其它组件所传递的数据
    this.$bus.$on('givename', (data) => {
      console.log(data);
      this.mysbfname = data
    })
}

11.Vue相同逻辑如何抽离

Vue.mixin方法。可以给组件每个生命周期和函数混入一些公共逻辑。

12. Vue中如何实现⼦组件内的css样式名在项⽬中绝对唯⼀性

style标签上加上scoped属性

13. 说出⾄少4种Vue当中的指令和它的⽤法?

  1. v-if(判断是否隐藏,⽤来判断元素是否创建)
  2. v-show(元素的显⽰隐藏,类似css中的display的block和hidden)
  3. v-for(把数据遍历出来)
  4. v-bind(绑定属性、响应式数据)
  5. v-model(实现双向绑定、语法糖)
加载中...
加载中...