VUE 相关问题积累

VUE问题积累

一、组件三种挂载方式

  • 自动挂载
var app3 = new Vue({
  el: '#app-3',
  data: {
    seen: true
  }
})
  • 手动挂载
// 能够实现延迟按需挂载
<div id="app"> {{name}} </div> 
<button onclick="test()">挂载</button> 
<script> 
 var obj= {name: '张三'} 
 var vm = new Vue({ 
  data: obj
 }) 
 function test() { 
  vm.$mount("#app"); 
 }
// Vue.extend()建立没有挂载的的子类,可使用该子累建立多个实例
var app= Vue.extend({ 
 template: '<p>{{message}}</p>', 
   data: function () { 
    return { 
        message: 'message'
     } 
    } 
   }) 
 new app().$mount('#app') // 建立 app实例,并挂载到一个元素上

二、路由传递参数的方式

<p>
    <!-- query要用path来引入,params要用name来引入,故不能写为 :to="{path:'/login',params: {isLogin: true}} -->
    <!-- 跳转路由时用this.$router: this.$router.push({name:"login",params:{isLogin:true}});this.$router.push({path: '/login', query: {isLogin : true}}); -->
    <!-- 接收参数时用this.$route: this.$route.query.isLogin 和 this.$route.params.isLogin; -->
    <router-link :to="{name:'login',params: {isLogin: true}}">亲,请登陆</router-link>
    <router-link :to="{name:'login',params: {isLogin: false}}">免费注册</router-link>
  </p>
  <!-- 路由出口, 路由匹配到的组件将渲染在这里 -->
  <router-view></router-view>

三、render:h=>h(App)的理解

render:h=>h(App)是ES6中的箭头函数写法,等价于render:function(h){return h(App);}.css

1.箭头函数中的this是 指向 包裹this所在函数外面的对象上。html

2.h是creatElement的别名,vue生态系统的通用管理vue

3.template:‘<app/>’,components:{App}配合使用与单独使用render:h=>h(App)会达到一样的效果
  前者识别<template>标签,后者直接解析template下的id为app的div(忽略template的存在)react

new Vue({
  el: '#app', //  至关于 new Vue({}).$mount('#app');
  template: '<App/>', // 一、能够经过在 #app 内加入<app></app>替代 二、或者 经过 render: h => h(App) 渲染一个视图,而后提供给el挂载
  components: { // vue2中能够经过 render: h => h(App) 渲染一个视图,而后提供给el挂载
    App
  }
});

四、Vue.nextTick()的理解

与DOM相关操做写在该函数回调中,确保DOM已渲染
nextTick的由来:
    因为VUE的数据驱动视图更新,是异步的,即修改数据的当下,视图不会马上更新,而是等同一事件循环中的全部数据变化完成以后,再统一进行视图更新。
    
nextTick的触发时机:
    在同一事件循环中的数据变化后,DOM完成更新,当即执行nextTick(callback)内的回调。
    
应用场景:
    须要在视图更新以后,基于新的视图进行操做。git

  1. 在Vue生命周期的created()钩子函数进行的DOM操做必定要放在Vue.nextTick()的回调函数中。缘由是什么呢,缘由是在created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操做无异于徒劳,因此此处必定要将DOM操做的js代码放进Vue.nextTick()的回调函数中。与之对应的就是mounted钩子函数,由于该钩子函数执行时全部的DOM挂载和渲染都已完成,此时在该钩子函数中进行任何DOM操做都不会有问题 。
  2. 在数据变化后要执行的某个操做,而这个操做须要使用随数据改变而改变的DOM结构的时候,这个操做都应该放进Vue.nextTick()的回调函数中。

简单总结事件循环:
    同步代码执行 -> 查找异步队列,推入执行栈,执行callback1[事件循环1] ->查找异步队列,推入执行栈,执行callback2[事件循环2]...即每一个异步callback,最终都会造成本身独立的一个事件循环。结合nextTick的由来,能够推出每一个事件循环中,nextTick触发的时机:github

        

五、动态属性添加

https://cn.vuejs.org/v2/guide...

受现代 JavaScript 的限制 (以及废弃 Object.observe),Vue 不能检测到对象属性的添加或删除。因为 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,因此属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。例如:vue-router

var vm = new Vue({
  data:{
  a:1
  }
})

// `vm.a` 是响应的

vm.b = 2
// `vm.b` 是非响应的

Vue 不容许在已经建立的实例上动态添加新的根级响应式属性 (root-level reactive property)。然而它可使用 Vue.set(object, key, value) 方法将响应属性添加到嵌套的对象上:vuex

Vue.set(vm.someObject, 'b', 2)

您还可使用 vm.$set 实例方法,这也是全局 Vue.set 方法的别名:npm

this.$set(this.someObject,'b',2)

有时你想向已有对象上添加一些属性,例如使用 Object.assign() 或 _.extend() 方法来添加属性。可是,添加到对象上的新属性不会触发更新。在这种状况下能够建立一个新的对象,让它包含原对象的属性和新的属性:缓存

// 代替 `Object.assign(this.someObject, { a: 1, b: 2 })`
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })

六、样式渗透到子组件

你能够在一个组件中同时使用有做用域和无做用域的样式:

深度做用选择器 https://vue-loader.vuejs.org/...
<style>
/* 全局样式 */
</style>

<style scoped>
/* 本地样式 */
</style>

子组件的根元素:使用 scoped 后,父组件的样式将不会渗透到子组件中。不过一个子组件的根节点会同时受其父组件有做用域的 CSS 和子组件有做用域的 CSS 的影响。这样设计是为了让父组件能够从布局的角度出发,调整其子组件根元素的样式。

深度做用选择器:若是你但愿 scoped 样式中的一个选择器可以做用得“更深”,例如影响子组件,你可使用 >>> 操做符:

<style scoped>
.a >>> .b { /* ... */ }
</style>
// 上述代码将会编译成:
.a[data-v-f3f3eg9] .b { /* ... */ }

有些像 Sass 之类的预处理器没法正确解析 >>>。这种状况下你可使用 /deep/ 操做符取而代之——这是一个 >>> 的别名,一样能够正常工做。


七、路由控制title及权限

import Vue from 'vue';
import Router from 'vue-router';
import store from 'src/vuex/store.js';
Vue.use(Router);

const router = new Router({
  routes: [
    {
      path: '/login', /* 登陆界面 */
      name: 'login',
      component: login/* ,hidden: true, // 自定义属性,在组件中能够经过 this.$route.hidden 获取值 */
    },
    {
      path: '/sysSetting', /* 首页 */
      component: sysSetting,
      name: 'sysSetting', /* this.$route.matched.filter(item => item.name) */
      meta: {
        keepAlive: false, /* 用于在 <keep-alive> 中使用,判断是否须要进行缓存 */
        auth: true, /* 自定义属性,用于判断是否进行校验,在router.beforeEach中使用 */
        title: '系统设置' /* 能够经过$route.meta.title 后取当前的描述信息、菜单信息 */
      }
    },
    {
      path: '*', /* 默认跳转到登陆界面 */
      redirect: {path: '/sysSetting'}
    }
  ]
});

router.beforeEach((to, from, next) => {// 注册一个全局前置守卫
  if (to.meta.title) { // 路由发生变化修改页面title
    document.title = to.meta.title;
  }
  
  if (to.matched.some(m => m.meta.auth)) {// 判断是否须要校验
    if (store.state.isLogin) {// 获取
      next();// 校验经过,正常跳转到你设置好的页面
    } else {
      next({// 校验失败,跳转至登陆界面
        path: '/login',
        query: {
          redirect: to.fullPath
        }// 将跳转的路由path做为参数,用于在登陆成功后获取并跳转到该路径
      });
    }
  } else {
    next();// 不须要校验,直接跳转
  }
});

export default router;

八、嵌套路由及命名视图

https://router.vuejs.org/zh-c...

九、页面路由进度条

http://hilongjw.github.io/vue...

十、静态资源路径

问题描述<img v-bind:src="imgUrl"/> 绑定的资源请求失败

<template>
 <div class="content"
   <!-- 界面中引入 -->
   <img v-bind:src="imgUrl"/>
</div>
</template>

// js中设置的路径
<script type="text/ecmascript-6">
  export default {
    data () {
      return {
        imgUrl : './logo.png' // 此处路径引入错误
      };
    }
 }

缘由分析:在上面代码中文件的路径是相对于项目文件目录的,而网页把根域名做为相对路径的根目录(npm run build 生成),而且全部的文件名后都被添加上了一个随机字符串。结构目录以下以下:

图片描述

解决办法:图片一类的静态文件,应该放在这个static文件夹下,这个文件夹下的文件(夹)会按照本来的结构放在网站根目录下。这时咱们再去使用/static绝对路径,就能够访问这些静态文件了。

相关文章
相关标签/搜索