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()
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

posted on 2017-06-13 11:03  cag2050  阅读(818)  评论(0编辑  收藏  举报

导航