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

    • Vue 中的 slot:
      概念:槽/slot是组件在模板中为调用者预留的位置,使用<slot>元素声明一个 槽。在最终的视图中,调用者模板中被调用组件的内容,将填充<slot>元素 占据的位置,形成最终的模板。
      一篇比较好的介绍文章:
      深入理解vue中的slot与slot-scope:https://segmentfault.com/a/1190000012996217

    • Vue 中的 slot:

    1. 在Vue中,slot是一个很有用的特性,可以用来向组件内部插入一些内容。slot就是“插槽”的意思,用大白话说就是:定义组件的时候留几个口子,由用户来决定插入的内容。
    2. 假如我们有一个程序实例,使用相同的组件 <app-child> 两次。在每个子组件内部,我们需要一些相同的内容以及不同的内容。对于要保持一致的内容,我们使用一个标准的 p 标签,而对于要切换的内容,我们放在空的 <slot></slot> 标签中。
    <script type="text/x-template" id="childarea">
      <div class="child">
        <slot></slot>
        <p>It's a veritable slot machine!<br> 
        Ha ha aw</p>
      </div>
    </script>
    

    然后在程序实例中,我们可以在在 <app-child> 组件标签中传递内容,它会自动填充到 slots 中:

    <div id="app">
      <h2>We can use slots to populate content</h2>
      <app-child>
        <h3>This is slot number one</h3>
      </app-child>
      <app-child>
        <h3>This is slot number two</h3>
        <small>I can put more info in, too!</small>
      </app-child>
    </div>
    
    1. slots 中也可以有默认内容。如果要在 slot 中写内容,而不是写 <slot></slot>,你可以这样填充:
    <slot>I am some default text</slot>
    

    如果你没有在 slot 中填充其它内容,就会显示默认文本。

    1. 你也可以使用具名 slot 。如果一个组件中有两个 slot, 可以通过添加 name 属性区分它们 <slot name="headerinfo"></slot>,并且通过特定的名称访问 slot <h1 slot="headerinfo">I will populate the headerinfo slot!</h1> 。这非常有用。如果有多个命名的 slot 而有一个没有命名,Vue 命名的内容填充到命名的 slot 中,而剩余的内容将填充到未命名的 slots 中。
    • vue 中 slot 的一个简单例子:
      比如你自己做了个一个button组件,在根组件里注册为vButton,从而复用。
      那么各个button上的文字肯定是不同的,但是这些文字大部分情况下也是不需要动态更新的,那么就不必用props之类的方法从根组件向子组件传递文字,直接用slot即可。
      button组件假如是这样:
    <template>
      <button>
        <slot></slot>
      </button>
    </template>
    

    根组件就可以这样用它:

    <v-button>按钮文字</v-button>
    
    // 正常的 HTML 特性
    attrs: {
      id: 'foo'
    },
    // 组件 props
    props: {
      myProp: 'bar'
    }
    
    • vue子组件里类型为Function的props,父组件使用时要写在methods里
      该用法例子(子组件):https://github.com/cag2050/vue_tables_xlsx_demo/blob/master/src/components/DataTablesExportExcel.vue

    • vue项目中,不用写CSS的兼容性代码。
      因为vue-loader在编译.vue文件的时候,使用了Postcss的工具,它会给有兼容性问题的属性添加兼容性代码。
      它是根据can i use官网写的代码。
      写在内才会生效。在html中添加style属性是不会添加兼容性代码的。

    • 计算属性(computed)不能直接设置值;
      如果直接设置值,报错:

    Computed property "xxx" was assigned to but it has no setter.
    
    • 一、仅仅是想通知某个对象去更改状态,建议使用事件的方式
      1.父子组件之间的事件通讯,通过在父组件监听对应的事件名,子组件触发的方式。
      2.非父子组件采用Event Bus的方式
      二、数据在组件之间的共享
      1.中大型应用使用vuex
      2.应用场景比较少的情况,父子组件采用props,非父子组件Event Bus传递数据

    • 编写全局插件的方式:

    方式 写法
    Vue.mixin Vue.mixin({})
    Vue.prototype Vue.prototype.<func_name> =function() { return xxx}
    Vue.filter Vue.filter(<func_name>,function(){})
    Vue.directive Vue.directive('myfocus', {})
    • vue开发插件:
    1. 定义全局插件:helper.js
    import Clickoutside from 'element-ui/lib/utils/clickoutside'
    export default {
        install (Vue, options) {
            Vue.mixin({
                directives: {
                    Clickoutside
                },
                data () {
                    return {
                        someValue: 'some value'
                    }
                }
            })
            Vue.prototype.getDate = function () {
                let end = new Date()
                let start = new Date()
                start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
                return [start, end]
            }
            Vue.filter('vcntFormat', function (cnt) {
                return cnt >= 100000 ? Math.floor(cnt / 10000) + '万' : cnt
            })
        }
    }
    
    1. main.js里引入并使用:
    import Helpers from './helpers'
    Vue.use(Helpers)
    
    • 全局注册混合对象:Vue.mixin({Object})
      全局注册混合对象后,会影响到 所有 之后创建的 Vue 实例。

    • vue组件使用中,PascalCase 是最通用的 声明约定 而 kebab-case 是最通用的 使用约定。
      在 HTML 模板中,组件名请使用 kebab-case 形式:

    <my-component></my-component>
    
    • 定义 transition-group 的过渡效果。
      stylus 语法:
    // 一定时间内,针对opacity的transition完成
    .fade-enter-active
    .fade-leave-active
      transition opacity 1s ease
    // 开始enter的时候,透明度为0,变化为1;开始leave的时候,透明度为1,变化为0
    // 此处只需要写进入元素的开始enter:v-enter、离开元素的leave结束:v-leave-to(v-是这些过渡类名的前缀)
    .fade-enter
    .fade-leave-to
      opacity 0
    

    https://cn.vuejs.org/v2/guide/transitions.html#过渡的类名

    • 当插入或删除包含在 transition 组件中的元素时,Vue 将会做以下处理:
    1. 自动嗅探目标元素是否应用了 CSS 过渡或动画,如果是,在恰当的时机添加/删除 CSS 类名。
    2. 如果过渡组件提供了 JavaScript 钩子函数,这些钩子函数将在恰当的时机被调用。
    3. 如果没有找到 JavaScript 钩子并且也没有检测到 CSS 过渡/动画,DOM 操作 (插入/删除) 在下一帧中立即执行。(注意:此指浏览器逐帧动画机制,和 Vue 的 nextTick 概念不同)
    • on和emit的事件必须是在一个公共的实例上,才能触发。
      我的解决方案是:
      新建bus.js
    import Vue from 'vue'
    export var bus = new Vue()
    

    App.vue里created方法里定义事件

    import { bus } from 'bus.js'
    // ...
    created () {
      bus.$on('tip', (text) => {
        alert(text)
      })
    }
    

    Test.vue组件内调用

    import { bus } from 'bus.js'
     // ...
    bus.$emit('tip', '123')
    
    • 每个 <transition-group> 的子节点必须有 独立的 key ,动画才能正常工作
      https://cn.vuejs.org/v2/api/#transition-group
      <transition-group> 渲染一个真实的 DOM 元素。默认渲染 <span>,可以通过 tag 属性配置哪个元素应该被渲染。
      下面这个例子渲染的是<ul>元素
    <transition-group name='fade' mode='out-in' tag='ul'></transition-group>
    
    • vue绑定类和样式:
    :style="this.type === '1' ? 'margin-top:565px' : ''"
    :class="this.type === '1' ? '[class-name]' : ''"
    
    • v-model 绑定的值一定要能访问,可以是data中的值或mapstate里的值

    • vue调试
      改store里的接口返回值,来制作模拟数据,不用改页面代码,这样方便调试。

    • vue编写思路:
      mapstate里值为null时,外层元素显示loading;state里值不为null时,各内层元素v-show绑定computed里某函数,该函数设置各内层元素的值,最后返回true

    • 问:vue ajax初始化数据是应该在created()里面还是放在mounted()里面?
      答:根据情况,一般放到created里面就可以了,这样可以及早发请求获取数据;
      如果有依赖dom必须存在的情况,就放到 mounted(){this.$nextTick(() => { /* code */ })} 里面

    • css 添加 scoped 属性作用:
      不要过度依赖scoped,scoped 不好维护,良好的css层级和嵌套规则完全够用。
      父组件的有作用域的CSS和子组件的有作用域的CSS将同时影响子组件。
      有作用域的样式对其他部分没有影响。
      Vue 文件格式可以支持局部 CSS,只要在 style 标签上加上一个 scoped 属性,样式只会影响当前组件及子组件。

    • 问:vue 能自动识别组件的名字?比如:组件文件名是 ClipList,在 html 中写 clip-list、c-liplist、cli-plist 都可以?
      答:

    • vue 获取元素,全部定义 ref 属性来获取。

    <div ref="div1"></div>
    

    通过 this.$refs.div1 来得到这个元素。

    import scene1 from '../assets/scene1.jpg'
    
    • 在子组件中,props里定义的属性,比如:
        props: {
            list: Array
        }
    

    在子组件中,可以直接这样访问父组件传到子组件的这个值:this.list

    • 问:在 Vue.js 中使用第三方库有哪些方法?
      答:4种方法。
    1. 在项目中添加第三方库的最简单方式是将其作为一个全局变量, 挂载到 window 对象上
    2. 一个简单的方式是在每一个需要该库的文件中导入
    3. 在 Vuejs 项目中使用 JavaScript 库的一个优雅方式是将其代理到 Vue 的原型对象上去
    4. 如果你想在多个项目中使用同一个库, 或者想将其分享给其他人, 可以将其写成一个插件
    • 子组件props中声明的值,可以使用 this.[key] 访问。

    • 问:为什么Vue组件中的data是一个函数,而Vue构造器var vm = new Vue({})里的data是一个对象?
      答:组件中的data之所以是函数,而不是对象,是因为每个组件都是相互独立的,如果它们共用一个对象,在更改一个组件数据的时候,会影响其他组件。如果是函数的话,每个组件都有自己独立的数据。相互之间不会影响。
      官方解释:https://cn.vuejs.org/v2/guide/components.html#data-必须是函数

    • 通过Vue构造器传入的各种选项大多数都可以在组件里用。 data 是一个例外,它必须是函数。

    • 通过为每个组件返回全新的 data 对象来避免组件共享同一个 data。

    • watch可以监控组件data中的属性,或vuex中...mapState中的内容。

    • computed里的函数名,随便写,只要函数中有值(值可以是:data中的属性,或vuex中...mapState中的内容)变化,就会计算。

    • 计算属性:函数中,只要有值变化,就会计算

    • Vue生命周期图示:

    • 插值:
      文本:{{ message }};
      纯html:v-html="xxx";
      属性:v-bind:id="xxx";
      使用 JavaScript 表达式:{{ ok ? 'YES' : 'NO' }}
      过滤器:{{ message | capitalize }}

    • 指令:
      参数:v-bind:href="xxx"; v-on:click="xxx";
      修饰符:v-on:submit.prevent="xxx"

    • 缩写:
      v-bind 缩写,使用:(冒号)

    <a v-bind:href="url"></a>
    <a :href="url"></a>
    

    v-on 缩写,使用@

    <a v-on:click="doSomething"></a>
    <a      @click="doSomething"></a>
    
    • computed和method:优先考虑使用computed
      计算属性computed是基于它的依赖缓存。计算属性只有在它的相关依赖发生改变时才会重新取值。
      每当重新渲染的时候,method 调用总会执行函数。

    • 访问vue组件的data:

    this.$data
    

    访问data里的数据:

    this.$data.[key] 或直接 this.[key]
    
    • vue实例export default { }写法:
        name: 'profile',
        data () {
            return {
            }
        },
        created () {
            this.$nextTick(function () {
            })
        },
        filters: {
            nullFilter: (value) => {
                return value === '' ? '暂无信息' : value
            }
        },
        computed: {
            show: function () {
                return this.$store.state.user !== null && this.$store.state.user.auth !== null
            }
        },
        methods: {
        }
    
    • computed、methods、watch不能用es6的箭头函数,filters可以用es6的箭头函数。

    • computed函数名,跟template里的值,是一一对应的。

    • vue监控(watch)对象。watch可以监控组件data中的属性,或vuex中...mapState中的内容(举例:下面第二段代码的user)

        watch: {
            user (user) {
                this.form.nick = user.nick === '' ? '暂无信息' : user.nick
            },
            form: {   // form是对象,使用这种写法
                handler (form) {
                    console.log(form.nick)
                },
                deep: true
            }
        },
            ...mapState({
                user: state => state.user.auth
            })
    
    • 一个页面中有多个组件的数据初始化,判断方法:
      1.所有组件都初始化好之后,再显示;
      三个条件:获取数据的方法写在created里;dom最外层写v-if="show";show方法写在computed里,判断所有数据都有;
      2.部分组件有数据后,就显示,局部刷新的数据写在computed里。

    • new Vue的多种方法:

    new Vue({
      el: '#app',
      render: h => h(App)
    })
    

    render: h => h(App) 含义:
    => 是ES6的箭头语法

    // ES5  
    render: function(h) {
      return h(App); 
    }
    
    // ES6  
    render: h => h(App); 
    

    render是Vue 2.0新增的函数,可以直接给绑定节点渲染一个vue组件,如果在Vue 1.x下,就应该使用

    new Vue({
        el: '#app',
        components: { App }
    });
    

    然后在页面中写入标记:

    <div id="app">
    </div>
    
    • vue实例四种写法

    • vue组件间传递数值:
      初学者常犯的一个错误是使用字面量语法传递数值:

    <!-- 传递了一个字符串"1" -->
    <Parent some-prop="1"></Parent>
    

    因为它是一个字面 prop ,它的值以字符串 "1" 而不是以实际的数字传下去。
    如果想传递一个实际的 JavaScript 数字,需要使用 v-bind ,从而让它的值被当作 JavaScript 表达式计算:

    <!-- 传递实际的数字 -->
    <Parent v-bind:some-prop="1"></Parent>
    
    • 使用子组件的方式:
      1)父组件内components引入;
      2)通过在路由中配置children
  • 相关阅读:
    Oracle 导入导出 dmp 文件
    zTree树
    下拉复选框
    jQuery Pagination分页插件
    下载java生成PDF
    Activiti 流程实例、任务、执行对象及相关的表
    Activiti 删除key值相同的所有不同版本的流程定义
    Activiti 查询最新版本的流程定义
    Activiti 查看流程图
    Activiti 删除流程定义
  • 原文地址:https://www.cnblogs.com/cag2050/p/7000055.html
Copyright © 2011-2022 走看看