zoukankan      html  css  js  c++  java
  • vue进阶知识点

    一、listeners

    2.4.0 新增

    这两个是不常用属性,但是高级用法很常见;

    1.场景如果父传子有很多值那么在子组件需要定义多个解决attrs获取子传父中未在 props 定义的值

    // 父组件
    <home title="这是标题" width="80" height="80" imgUrl="imgUrl"/>

    // 子组件
    mounted() {
    console.log(this.$attrs) //{title: "这是标题", "80", height: "80", imgUrl: "imgUrl"}
    },
    相对应的如果子组件定义了 props,打印的值就是剔除定义的属性

    props: {
    {
    type: String,
    default: ''
    }
    },
    mounted() {
    console.log(this.$attrs) //{title: "这是标题", height: "80", imgUrl: "imgUrl"}
    }
    2.场景子组件需要调用父组件的方法解决父组件的方法可以通过listeners" 传入内部组件——在创建更高层次的组件时非常有用

    // 父组件
    <home @change="change"/>

    // 子组件
    mounted() {
    console.log(this.$listeners) //即可拿到 change 事件
    }
    如果是孙组件要访问父组件的属性和调用方法,直接一级一级传下去就可以

    3.inheritAttrs

    // 父组件
    <home title="这是标题" width="80" height="80" imgUrl="imgUrl"/>

    // 子组件
    mounted() {
    console.log(this.$attrs) //{title: "这是标题", "80", height: "80", imgUrl: "imgUrl"}
    },

    inheritAttrs默认值为true,true的意思是将父组件中除了props外的属性添加到子组件的根节点上(说明,即使设置为true,子组件仍然可以通过$attr获取到props意外的属性)
    将inheritAttrs:false后,属性就不会显示在根节点上了
    二、provide和inject

    2.2.0 新增

    描述:

    provide和inject主要为高阶插件/组件库提供用例。并不推荐直接用于应用程序代码中;并且这对选项需要一起使用;

    以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。

    //父组件:
    provide: { //provide 是一个对象,提供一个属性或方法
    foo: '这是 foo',
    fooMethod:()=>{
    console.log('父组件 fooMethod 被调用')
    }
    },

    // 子或者孙子组件
    inject: ['foo','fooMethod'], //数组或者对象,注入到子组件
    mounted() {
    this.fooMethod()
    console.log(this.foo)
    }
    //在父组件下面所有的子组件都可以利用inject
    provide 和 inject 绑定并不是可响应的。这是官方刻意为之的。
    然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的,对象是因为是引用类型 

    //父组件:
    provide: {
    foo: '这是 foo'
    },
    mounted(){
    this.foo='这是新的 foo'
    }

    // 子或者孙子组件
    inject: ['foo'],
    mounted() {
    console.log(this.foo) //子组件打印的还是'这是 foo'
    }
    三、children

    父实例children:子实例

    //父组件
    mounted(){
    console.log(this.$children)
    //可以拿到 一级子组件的属性和方法
    //所以就可以直接改变 data,或者调用 methods 方法
    }

    //子组件
    mounted(){
    console.log(this.$parent) //可以拿到 parent 的属性和方法
    }
    和parent 并不保证顺序,也不是响应式的,只能拿到一级父组件和子组件。

    四、$refs

    // 父组件
    <home ref="home"/>

    mounted(){
    console.log(this.$refs.home) //即可拿到子组件的实例,就可以直接操作 data 和 methods
    }
    五、$root

    // 父组件
    mounted(){
    console.log(this.$root) //获取根实例,最后所有组件都是挂载到根实例上
    console.log(this.$root.$children[0]) //获取根实例的一级子组件
    console.log(this.$root.$children[0].$children[0]) //获取根实例的二级子组件
    }
    六、.sync
    在 vue@1.x 的时候曾作为双向绑定功能存在,即子组件可以修改父组件中的值;
    在 vue@2.0 的由于违背单项数据流的设计被干掉了;
    在 vue@2.3.0+ 以上版本又重新引入了这个 .sync 修饰符;

    // 父组件
    <home :title.sync="title" />
    //编译时会被扩展为
    <home :title="title" @update:title="val => title = val"/>

    // 子组件
    // 所以子组件可以通过$emit 触发 update 方法改变
    mounted(){
    this.$emit("update:title", '这是新的title')
    }

    七、v-slot
    2.6.0 新增
    1.slot,slot-cope,scope 在 2.6.0 中都被废弃,但未被移除
    2.作用就是将父组件的 template 传入子组件
    3.插槽分类:
    A.匿名插槽(也叫默认插槽): 没有命名,有且只有一个;
    // 父组件
    <todo-list>
    <template v-slot:default>
    任意内容
    <p>我是匿名插槽 </p>
    </template>
    </todo-list>

    // 子组件
    <slot>我是默认值</slot>
    //v-slot:default写上感觉和具名写法比较统一,容易理解,也可以不用写

    B.具名插槽: 相对匿名插槽组件slot标签带name命名的;
    // 父组件
    <todo-list>
    <template v-slot:todo>
    任意内容
    <p>我是匿名插槽 </p>
    </template>
    </todo-list>

    //子组件
    <slot name="todo">我是默认值</slot>

    C.作用域插槽: 子组件内数据可以被父页面拿到(解决了数据只能从父页面传递给子组件)
    // 父组件
    <todo-list>
    <template v-slot:todo="slotProps" >
    {{slotProps.user.firstName}}
    </template>
    </todo-list>
    //slotProps 可以随意命名
    //slotProps 接取的是子组件标签slot上属性数据的集合所有v-bind:user="user"

    // 子组件
    <slot name="todo" :user="user" :test="test">
    {{ user.lastName }}
    </slot>
    data() {
    return {
    user:{
    lastName:"Zhang",
    firstName:"yue"
    },
    test:[1,2,3,4]
    }
    },
    // {{ user.lastName }}是默认数据 v-slot:todo 当父页面没有(="slotProps")

    八、EventBus
    1.就是声明一个全局Vue实例变量 EventBus , 把所有的通信数据,事件监听都存储到这个变量上;
    2.类似于 Vuex。但这种方式只适用于极小的项目
    3.原理就是利用和emit 并实例化一个全局 vue 实现数据共享
    // 在 main.js
    Vue.prototype.$eventBus=new Vue()

    // 传值组件
    this.$eventBus.$emit('eventTarget','这是eventTarget传过来的值')

    // 接收组件
    this.$eventBus.$on("eventTarget",v=>{
    console.log('eventTarget',v);//这是eventTarget传过来的值
    })
    4.可以实现平级,嵌套组件传值,但是对应的事件名eventTarget必须是全局唯一的

    九、broadcast和dispatch
    vue1.x有这两个方法,事件广播和派发,但是vue2.x删除了
    下面是对两个方法进行的封装
    function broadcast(componentName, eventName, params) {
    this.$children.forEach(child => {
    var name = child.$options.componentName;

    if (name === componentName) {
    child.$emit.apply(child, [eventName].concat(params));
    } else {
    broadcast.apply(child, [componentName, eventName].concat(params));
    }
    });
    }
    export default {
    methods: {
    dispatch(componentName, eventName, params) {
    var parent = this.$parent;
    var name = parent.$options.componentName;
    while (parent && (!name || name !== componentName)) {
    parent = parent.$parent;

    if (parent) {
    name = parent.$options.componentName;
    }
    }
    if (parent) {
    parent.$emit.apply(parent, [eventName].concat(params));
    }
    },
    broadcast(componentName, eventName, params) {
    broadcast.call(this, componentName, eventName, params);
    }
    }
    }
    十、路由传参
    1、方案一
    // 路由定义
    {
    path: '/describe/:id',
    name: 'Describe',
    component: Describe
    }
    // 页面传参
    this.$router.push({
    path: `/describe/${id}`,
    })
    // 页面获取
    this.$route.params.id
    2.方案二
    // 路由定义
    {
    path: '/describe',
    name: 'Describe',
    omponent: Describe
    }
    // 页面传参
    this.$router.push({
    name: 'Describe',
    params: {
    id: id
    }
    })
    // 页面获取
    this.$route.params.id
    3.方案三
    // 路由定义
    {
    path: '/describe',
    name: 'Describe',
    component: Describe
    }
    // 页面传参
    this.$router.push({
    path: '/describe',
    query: {
    id: id

    )
    // 页面获取
    this.$route.query.id
    4.三种方案对比
    方案二参数不会拼接在路由后面,页面刷新参数会丢失
    方案一和三参数拼接在后面,丑,而且暴露了信息

    十一、异步组件
    路由的按需加载
    webpack> 2.4 时
    {
    path:'/',
    name:'home',
    components:()=>import('@/components/home')
    }
    十二、动态组件
    场景:做一个tab切换时就会涉及到组件动态加载
    <component v-bind:is="currentTabComponent"></component>
    但是这样每次组件都会重新加载,会消耗大量性能,所以<keep-alive> 就起到了作用
    <keep-alive>
    <component v-bind:is="currentTabComponent"></component>
    </keep-alive>
    这样切换效果没有动画效果,这个也不用着急,可以利用内置的<transition>
    <transition>
    <keep-alive>
    <component v-bind:is="currentTabComponent"></component>
    </keep-alive>
    </transition>
    十三、components和 Vue.component
    components:局部注册组件
    export default{
    components:{home}
    }
    Vue.component:全局注册组件
    Vue.component('home',home)
    十四、mixins
    场景:有些组件有些重复的 js 逻辑,如校验手机验证码,解析时间等,mixins 就可以实现这种混入
    mixins 值是一个数组
    const mixin={
    created(){
    this.dealTime()
    },
    methods:{
    dealTime(){
    console.log('这是mixin的dealTime里面的方法');
    }
    }
    }

    export default{
    mixins:[mixin]
    }
    十五、Vue.nextTick
    2.1.0 新增
    场景:页面加载时需要让文本框获取焦点
    用法:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM
    mounted(){ //因为 mounted 阶段 dom 并未渲染完毕,所以需要$nextTick
    this.$nextTick(() => {
    this.$refs.inputs.focus() //通过 $refs 获取dom 并绑定 focus 方法
    })
    }
    十六、Vue.directive
    场景:官方给我们提供了很多指令,但是我们如果想将文字变成指定的颜色定义成指令使用,这个时候就需要用到Vue.directive
    // 全局定义
    Vue.directive("change-color",function(el,binding,vnode){
    el.style["color"]= binding.value;
    })

    // 使用
    <template>
    <div v-change-color=“color”>{{message}}</div>
    </template>
    <script>
    export default{
    data(){
    return{
    color:'green'
    }
    }
    }
    </script>

    十七:生命周期
    1.bind 只调用一次,指令第一次绑定到元素时候调用,用这个钩子可以定义一个绑定时执行一次的初始化动作。
    2.inserted:被绑定的元素插入父节点的时候调用(父节点存在即可调用,不必存在document中)
    3.update: 被绑定与元素所在模板更新时调用,而且无论绑定值是否有变化,通过比较更新前后的绑定值,忽略不必要的模板更新
    4.componentUpdate :被绑定的元素所在模板完成一次更新更新周期的时候调用
    5.unbind: 只调用一次,指令月元素解绑的时候调用

    十八:Vue.filter
    场景:时间戳转化成年月日这是一个公共方法,所以可以抽离成过滤器使用
    // 使用
    // 在双花括号中
    {{ message | capitalize }}

    // 在 `v-bind` 中
    <div v-bind:id="rawId | formatId"></div>

    // 全局注册
    Vue.filter('stampToYYMMDD', (value) =>{
    // 处理逻辑
    })

    // 局部注册
    filters: {
    stampToYYMMDD: (value)=> {
    // 处理逻辑
    }
    }

    // 多个过滤器全局注册
    // /src/common/filters.js
    let dateServer = value => value.replace(/(d{4})(d{2})(d{2})/g, '$1-$2-$3')
    export { dateServer }
    // /src/main.js
    import * as custom from './common/filters/custom'
    Object.keys(custom).forEach(key => Vue.filter(key, custom[key]))

    十九、Vue.set()
    场景:当你利用索引直接设置一个数组项时或你修改数组的长度时,由于 Object.defineprototype()方法限制,数据不响应式更新
    解决方案:
    // 利用 set
    this.$set(arr,index,item)

    // 利用数组 push(),splice()
    二十:Vue.config.keyCodes
    场景:自定义按键修饰符别名
    // 将键码为 113 定义为 f2
    Vue.config.keyCodes.f2 = 113;
    <input type="text" @keyup.f2="add"/>

  • 相关阅读:
    eclipse如何与git 配合工作。
    git托管代码(二)
    PPC2003 安装 CFNET 3.5成功
    我的Window Mobile WCF 項目 第三篇 WM窗体设计
    我的Window Mobile WCF 項目 第一篇Mobile开发和WinForm开发的区别
    我的Window Mobile WCF 項目 第七天
    我的Window Mobile WCF 項目 第二篇 WindowsMobile访问WCF
    WCF 用vs2010 和 vs2008的简单对比测试
    vs2010beta1 和 搜狗输入法 冲突,按下 Ctrl 键就报错,重装搜狗解决
    我的Window Mobile WCF 項目 第六天 (二)
  • 原文地址:https://www.cnblogs.com/wenshaochang123/p/13278511.html
Copyright © 2011-2022 走看看