vue一些问题记录

vue常见问题记录

1.不同路由共用同一组件

导致组件数据不刷新,created和destroy不会再次触发,组件被复用

方法1、监听路由
watch:{
    $route(){
        
    }
}
方法2、绑定唯一key
<router-view :key="key"></router-view>
方法3、或者声明不同的view 但view引入同一个组件
2.点击重复菜单页面数据不刷新
方法1、路由参数加时间戳
<router-view :key="key"></router-view>
this.$router.replace({
        path: router,
        query: {
          t: +new Date() // 保证每次点击路由的query项都是不一样的,确保会重新刷新view
        }
      })
方法2、重定向
const { fullPath } = this.$route
this.$router.replace({
  path: '/redirect' + fullPath
})
//redirect.vue
export default {
  beforeCreate() {
    const { params, query } = this.$route
    const { path } = params
    this.$router.replace({ path: '/' + path, query })
  },
  render: function(h) {
    return h() // avoid warning message
  }
}
3.解决开发环境热加载编译慢

VUE_CLI_BABEL_TRANSPILE_MODULES用来控制是否使用babel-plugin-dynamic-import-node(在vue-cli代码已实现)

.env.development
VUE_CLI_BABEL_TRANSPILE_MODULES = true
4.热重载和热替换
  • hmr (热替换)代码更新,不刷新整个页面,只更新部分修改内容
  • hot-reload(热重载) 监测代码,刷新整个页面
//开启热更新
chainWebpack: (config) => {
    config.resolve.symlinks(true) // 修复热更新失效
  }
5.利用postcss pxtorem自动将px转为rem
第一步:设置根节点的font-size 随窗口大小改变而自适应
//utils/rem.js
const baseSize = 19.2
function setRem() {
  // 当前页面宽度相对于 1920 宽的缩放比例,可根据自己需要修改。
  const scale = document.documentElement.clientWidth / 1920
  // 设置页面根节点字体大小
  document.documentElement.style.fontSize = baseSize * Math.min(scale, 2) + "px"
}
setRem()
window.onresize = () => {
  setRem()
}
//main.js
import "@/utils/rem" //根据屏幕宽动态更改尺寸
第二步:利用posrcss-pxtorem 使得px自动转为rem
module.exports = {
  //vue-cli3自动生成postcss.config.js若未生成则写在vue.config.js
  css: {
    loaderOptions: {
      postcss: {
        plugins: [
          require("postcss-pxtorem")({
            rootValue: 19.2, // 换算的基数 页面尺寸/19.2 1920px=100rem
            "selectorBlackList": ['el-']//不转换element
          }),
        ],
      },
    },
  },
}
//main.js
import "postcss-pxtorem" //px-rem
最后:代码使用px即可
6.解决跨域
解决开发环境跨域
本地开发环境解决跨域请求

利用vue-cli3的proxy代理转发

本地模拟服务器,代理转发
//vue.config.js
devServer:{
    proxy:{
        "/api":{
            target:"http://xx";//目标服务器地址
            changeOrigin:true;//允许跨域
            ws:true;//开启websocket
        }
    }
}
//axios.js
//请求的地址
VUE_BASE_APP_URL="/api/"
axios.get("/api/xx")
本地开模拟服务器,负责发送和请求目标服务器
7.优雅使用svg
7.1 vue中加载svg图片,svg-sprite-loader

多个svg图片拼接成雪碧图,拼接内容放到body下面,其他地方利用use复用

//1.文件存放如下 src/icons/svg/xx.svg
//2.vue.config.js配置
const path = require("path");
function resolve(dir) {
  return path.join(__dirname, dir);
} 
  chainWebpack: config => {
    // use svg
    config.module
      .rule("svg")
      .exclude.add(resolve("src/icons/svg"))
      .end();//先删除默认配置中处理svg
    config.module
      .rule("icon")
      .test(/\.svg$/)
      .include.add(resolve("src/icons/svg"))
      .end();
      .use("svg-sprite-loader")
      .loader("svg-sprite-loader")
      .options({
        symbolId: "icon-[name]" //name为svg名字
      })
      .end();
}
//使用 
import "@/icons/svg/add.svg";
<svg aria-hidden="true" width="200px" height="200px">
   <use xlink:href="#icon-xx" /> //xx为name名
</svg>
8.解决core.js报错

报类似npm install --save core-js/modules/es.array.find错误

原因:core.js已更新至版本3,删除了“ core-js / modules / es.array.find
但@babel/preset-env 仍导入这个包

//babel.config.js
module.exports={
     presets: [["@vue/app", { useBuiltIns: "entry" }]]
}
9.解决ie兼容问题

babel将高级语法转为浏览器识别的语法(不包括promise,symbol等函数),babel-polyfill 解决这个问题

注意:babel/polyfill 7.4后被遗弃,用core-js和regenerator-runtime替代

@bable/preset-env 根据配置的目标环境自动采用需要的babel插件

//vue-cli3中
vue add @vue/babel
10.computed、getters传参
computed:{
    getDate(){
        return function(params){
            return 'xx'
        }
    }
}
getters:{
    getData:state=>params=>{
        return params+state.xx
    }
}
11.mixins相关问题
11.1 A,B共用一个mixins ,A修改mixins会影响B吗?
  • 不会影响,相当于A融合了一份mixins东西,B融合了一份
11.2 mixins里可以使用A或B的属性,方法?
  • 可以使用和修改,此时A里的属性就变为mixins里修改过的
11.3 A引用多个mixins ,多个mixins能互相使用对方的数据吗?

能获取到,且mixins1里的数据mixins2也能获取和操作。

11.4 父组件引用A,B,mixins,A里面可以打印出mixins里东西吗?
  • 不可以
12.父组件利用v-model传递数据到子组件
//parent
<child v-model="text"></child>
//child
<input :value='text'></input>
this.$emit('input',xx);//更改值
13.父组件传递数据给子组件,子组件v-model接收
//parent 
<child :text.sync="text" ></child>
//child
<input v-model="newText" @change="changeInput"/>
props:['text'],
data(){
    return{
        newText:this.text
    }
},
method(){
    changeInput(){
        this.$emit("update:text","")
    }
}
14.computed计算属性无法根据state依赖值更新,vue无法监听

当state为对象 设置新字段时会遇到无法更新问题

//store中
  setAddTopic2HashList(state, topic) {
     //动态新增属性
     #error
     let hash = state.topicHashList; 
     hash[topic.uid] = topic;
     #success
     第一种
     state.topicHashList = Object.assign({}, state.topicHashList, {
      [topic.uid]: topic
    });
    第二种
    Vue.set(state.topicHashList,[topic.uid], topic)
  },
15.组件间循环调用

组件A中有多个子组件比如C、D,C里引用了A,会提示A组件未注册
原因是组件必须在实例化之前引入

方法1
全局注册A组件、在vue实例化之前
方法2
webpack异步组件,import方式引入
 components: {
    PosterTemplate: () => import('./Template.vue')
  }
方法3
 beforeCreate () {
  //beforeCreate () {
    // 官方文档给出的是require
    // this.$options.components.PosterTemplate = require('./Template.vue')
    // 在基于vue-cli@2.8.1按照上面的写法还是会报错
    // Failed to mount component: template or render function not defined.
    // 所以我们应该改为基于es6的写法异步加载一个组件如下
    this.$options.components.PosterTemplate = () => import('./Template.vue')
  }
16.Vue.observable(obj)

使obj可响应,返回的对象直接用于渲染函数和计算属性内 ,发生改变时触发相应更新

  • 实现跨组件数据状态共享,类似最简化的vuex
17.eval()

方法名中拼接变量时

let drawFunction=eval("_draw"+drawType);
drawFunction()
18 v-if 和v-show组件的生命周期
//v-show时
默认值true,false 均执行created,mounted
切换时,生命周期不执行
//v-if时
默认值 false,生命周期不执行
默认值 true, 执行created,mounted
false-->true 执行created,mounted
true--false 执行destory
19. v-model的用处
  • 利用v-model控制自身组件显隐

允许自定义组件在使用v-model时自定义prop和event,默认是v-model把value作为prop,input当做event

#父组件
<child v-model='isShow' value="value值"></dhild>
#子组件
model:{
    prop:'checked',
    event:'change'
},
props:['checked']
等价于
<child :checked='foo' @change='val=>{foo=val}' value="value值"></child>
20. vue-cli3中dart-sass替代node-sass
2. npm i sass sass-loader -D
3. module.exports = {
  css: {
    loaderOptions: {
      sass: {
        implementation: require('sass'), // This line must in sass option
      },
    },
  }
//other code
};
  • dart-sass不支持/deep/ 可更换为::v-deep
  • ::v-deep只支持一级嵌套
// error
op {
    ::v-deep d{
        
    }
}
//success
::v-deep op {
    d{
        
    }
}
21.源数据为被排序过得数组 运行爆红

报错提示 You may have an infinite update loop in a component render function

//error
computed:{
    sortTags() {
      return function(tags) {
        return tags.sort(this.compare("indicators"));
      };
    }
}

原因是array.sort()改变数组本身,导致过滤器又被触发 导致无限循环,所以因在副本上排序

//success 
return value.slice().sort(...)
// arr.slice(start,end) 浅复制返回新数组
22.this.$route.matched
  • 返回一路由数组、可做面包屑
例如/a/a1
路由分别匹配到/,/a,/a1
23.data里如何获取其他data,建议使用methods获取其他data
  • 不建议data里数据之间依赖 可利用computed
data(){
    return {
        temp:"测试",
        formLogin:()=>{
            console.log(this.temp);//利用箭头函数可实现
        },
        temp1:this.temp;//error 获取不到
    }
}
  • 使用methods
data(){
    return{
        temp:this.getData(),
        otherData:2
    }
}
methods:{
    getData(){
        console.log(this.otherData)
    }
}
24.如何使用public里的图片

HTML和静态资源

  1. public文件不经过webpack处理 当你通过绝对路径引用它时,留意应用将会部署到哪里
  2. 如果你的应用没有部署在域名的根部,那么你需要为你的 URL 配置 publicPath 前缀

index.html中

<link rel="icon" href="<%= BASE_URL %>favicon.ico">

在template中

<img :src="`${publicPath}my-image.png`">
data () {
  return {
    publicPath: process.env.BASE_URL
  }
}

在背景图片中使用

<div :style='imgStyle'></div>

data() {
    return {
      publicPath: process.env.BASE_URL
    };
  },
  computed: {
    imgStyle() {
      return {
        background: `url(${
          this.publicPath
        }static/mockpng/images/login.png) no-repeat center/cover`
      };
    }
  }
25.@import ~

css文件导入其他css文件有@import

他是遇到@import 才http请求文件

scss里的@import

为生成文件时即导入其他文件,无需额外http请求

@import "~@/xxx"
~xx 表示后面跟的是别名
26.获取元素时 r e f s 和 refs 和 refsrefs.$el的区别
  • 若ref绑定在组件上

则this. r e f s . x x 获取的是组件实例 V u e . refs.xx 获取的是组件实例 Vue. refs.xx获取的是组件实例Vue.el获取实例关联的dom元素

-若ref绑定在普通元素上

则this.$refs.xx获取的是dom元素 (offsetWidth ,style,……)

27.父子组件调用顺序
父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted
28.自定义指令

8个自定义

29.watch监听对象排除部分属性监听
mounted() {
    Object.keys(this.params)
      .filter((_) => !["c", "d"].includes(_)) // 排除对c,d属性的监听
      .forEach((_) => {
        this.$watch((vm) => vm.params[_], handler, {
          deep: true,
        });
      });
  },
data() {
    return {
      params: {
        a: 1,
        b: 2,
        c: 3,
        d: 4
      },
    };
  },
watch: {
    params: {
      deep: true,
      handler() {
        this.getList;
      },
    },
  }
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值