VUE 相关问题积累

VUE问题积累

1、组件三种挂载方式

  • 自动挂载
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实例,并挂载到一个元素上

2、路由传递参数的方式

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

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

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

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

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

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

new Vue({
  el: '#app', //  相当于 new Vue({}).$mount('#app');
  template: '<App/>', // 1、可以通过在 #app 内加入<app></app>替代 2、或者 通过 render: h => h(App) 渲染一个视图,然后提供给el挂载
  components: { // vue2中可以通过 render: h => h(App) 渲染一个视图,然后提供给el挂载
    App
  }
});

4、Vue.nextTick()的理解

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

  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触发的时机:

        

5、动态属性添加

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

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

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

// `vm.a` 是响应的

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

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

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

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

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

6、样式渗透到子组件

你可以在一个组件中同时使用有作用域和无作用域的样式:

深度作用选择器 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/ 操作符取而代之——这是一个 >>> 的别名,同样可以正常工作。


7、路由控制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;

8、嵌套路由及命名视图

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

9、页面路由进度条

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

10、静态资源路径

问题描述<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绝对路径,就可以访问这些静态文件了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值