vue

176 阅读6分钟

1.vue组件开发

每用一次组件,就会有一个它的新实例被创建。 组件是可复用的 Vue 实例,且带有一个名字

// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
  data: function () {
    return {
      count: 0
    }
  },
  template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})

当一个组件被定义,data 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。如果 data 仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!通过提供 data 函数,每次创建一个新实例后,我们能够调用 data 函数,从而返回初始数据的一个全新副本数据对象。

组件间通信

1 prop方式

单向数据流 所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。

额外的,每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。

注意在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变变更这个对象或数组本身将会影响到父组件的状态。

2.自定义事件

3.slot

2.vue指令:全局 局部指令 调用的时候v-xxx 也就是vue的指令都是v- 开头的

例如页面上使用指令

那么vue底层回去解析叫upper-text/lower-text的指令,所以使用指定之前必须定义,否则报错啊

// 注册一个全局指令
  // el: 指令所在的标签对象
  // binding: 包含指令相关数据的容器对象
  Vue.directive('upper-text', function (el, binding) {
    console.log(el, binding)
    el.textContent = binding.value.toUpperCase()
  })

3.vue插件

插件开发 暴露出来一个对象 这样才能使用Vue.use安装这个插件,就是把这个对象和vue建立联系

(function (window) {
  const MyPlugin = {}
  MyPlugin.install = function (Vue, options) {
    // 1. 添加全局方法或属性
    Vue.myGlobalMethod = function () {
      console.log('Vue函数对象的myGlobalMethod()')
    }

    // 2. 添加全局资源
    Vue.directive('my-directive',function (el, binding) {
      el.textContent = 'my-directive----'+binding.value
    })

    // 4. 添加实例方法 放到原型上就自动放到实例上
    Vue.prototype.$myMethod = function () {
      console.log('vm $myMethod()')
    }
  }
  window.MyPlugin = MyPlugin
})(window)

插件的使用

混入

vue插槽slot

vue计算属性

vuex状态管理 vue的插件

路由

路由的配置项

path:访问的路径

redirect:重定向到指定的路径下

name:给路由命名

component:访问对应的路径 指定哪个组件进行渲染

meta: 路由原信息 children: 嵌套路由的配置 prop: 将路由的参数映射到组件的props属性上 三种方式 booelean,对象方式,函数方式 components: 用于命名视图 有可能一个组件上 会有多个router-view标签,那么对应的由什么组件来渲染需要用名字的方式来控制

命名视图

三个视图  不同名称
<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>

一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。
确保正确使用 components 配置(带上 s):

const router = new VueRouter({
  routes: [
    {
      path: '/',
      components: {
        default: Foo,
        a: Bar,
        b: Baz
      }
    }
  ]
})


mode: 配置路由的模式 默认是#hash模式 可以修改为history模式

base:为所有的请求路径加上一个统一的基路径,但是base不是强制性的,也就是路径中不输入base前缀也能访问 linkActiveClass: 路由激活时,加指定样式 linkExactActiveClass: 路由完全匹配的时候才会 增加样式 scollBehavior:滚动行为相关配置 parseQuery stringifyQuery fallback:

动态路由配置

例如我们有一个 User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在 vue-router 的路由路径中使用『动态路径参数』(dynamic segment)来达到这个效果:

const User = {
  template: '<div>User</div>'
}

const router = new VueRouter({
  routes: [
   动态路径参数 以冒号开头
    { path: '/user/:id', component: User }
  ]
})

现在呢,像 /user/foo 和 /user/bar 都将映射到相同的路由。

一个『路径参数』使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到 this.$route.params,可以在每个组件内使用。 于是,我们可以更新 User 的模板,输出当前用户的 ID:

const User = {
  template: '<div>User {{ $route.params.id }}</div>'
}

当使用路由参数时,两个路由都复用同个组件,比起销毁再创建,复用则显得更加高效。也意味着组件的生命周期钩子不会再被调用。想对路由参数的变化作出响应的话,你可以简单地 watch(监测变化) $route 对象:

const User = {
  template: '...',
  watch: {
    '$route' (to, from) {
      // 对路由变化作出响应...
    }
  }
}

 或者使用 2.2 中引入的 beforeRouteUpdate 守卫:

const User = {
  template: '...',
  beforeRouteUpdate (to, from, next) {
    // react to route changes...
    // don't forget to call next()
  }
}

路由query参数

通过url中?拼接的路由参数会直接进入到query对象中,不需要额外的配置,

导航守卫

vue-router共有三种守卫,分别是全局守卫、路由独享守卫、组件内的守卫

NProgress

进度条控制:参考 segmentfault.com/a/119000001…

import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style  //这个样式必须引入

NProgress.configure({ showSpinner: false }) // NProgress Configuration
NProgress.start() // start progress bar   ngprogress是进度条控制 进度条控制开始
NProgress.done() // finish progress bar   ngprogress是进度条控制 进度条控制结束  因为路由跳转完毕

vue-ls

参考: www.jianshu.com/p/ab7f67878…

NPM
npm install vue-ls --save

YARN
yarn add vue-ls

import Storage from 'vue-ls';
 
options = {
  namespace: 'vuejs__', // key键前缀
  name: 'ls', // 命名Vue变量.[ls]或this.[$ls],
  storage: 'local', // 存储名称: session, local, memory
};
 
Vue.use(Storage, options);
// 或 Vue.use(Storage);

new Vue({
    el: '#app',
    mounted: function() {
        Vue.ls.set('foo', 'boo');
        // 设置有效期
        Vue.ls.set('foo', 'boo', 60 * 60 * 1000); //有效1小时
        Vue.ls.get('foo');
        Vue.ls.get('boo', 10); // 如果没有设置boo返回默认值10 
        
        let callback = (val, oldVal, uri) => {
          console.log('localStorage change', val);
        } 
        
        Vue.ls.on('foo', callback) //侦查改变foo键并触发回调 
        Vue.ls.off('foo', callback) //不侦查
        
        Vue.ls.remove('foo'); // 移除
    }
});


vue异步组件

魔法注释:

参考:www.cnblogs.com/lvdabao/p/5…

vue 基礎知识

不指定el配置项的时候可以手动挂载

data属性和配置项中的data指向同一个地方 也就是说可以通过data.xxx 修改数据 xxx是属性名

可以获取到顶级root vue实例

vue实例中可以获取到slots和scopedSlots

vm.$watch 返回一个取消观察函数,用来停止触发回调:

可以通过代码的嘛事$set 为当期vue实例增加数据 这种方式设置属性vue认为这个属性是reactive响应式的

$nextTick

nextTick(),是将回调函数延迟在下一次dom更新数据后调用,简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数,

所以在created 和beforeCreated这两个生命周期是无法进行dom操作的

watch:如果不加immediate 不会立即执行,等到下次监听的值有变化的时候才会触发,加了之后会立即触发,即初始化的时候先触发一次

深度监视 obj的所有属性的变化都能监视到,开销性能比较大,因为要给所有属性加监听

用字符串的形式,只会监听a属性的变化

v-pre

全局和局部注册组件

组件的prop不要去修改 vue会警告 但是不去阻止

extend

extend 方式二

provide和inject