用Vue中遇到的问题和处理方法(一)

用Vue开发项目有一段时间,在实际项目中遇到一些问题,在里把问题记录下来,并附上解决方案,给遇到同样的问题的码友提供一个解决思路吧:

  • 测试部抛出问题一:在Vue1.0路由vue-router中,当点击菜单一个组件加载出来表格列表,输入查询条件查询,当在单击这个菜单后表格的数据没有重置查询条件和查询结果.

原因分析:Vue路由在页面渲染一个组件后加载后,再加载这个组件,组件不会摧毁后在重新生成这个组件,不会重新触发组件的生命周期中的方法.代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">

    <title>learning vue</title>
</head>
<body>

<div id="app-container">
    <ul>
        <li v-for="item in $root.list">
            <a v-link="{ path: ‘/lang/‘ + item.id }">{{ item.name }}{{para}}{{params}}</a>
        </li>
    </ul>
    <router-view :params="params"></router-view>
</div>

<script src="js/vue.js"></script>
<script src="js/vue-router.js"></script>

<script>
    Vue.config.debug = true;
    Vue.use(VueRouter);
    var AppComponent = Vue.extend({
        data: function(){
            return {
                params:111,
                list: [
                    { id: ‘10001‘, name: ‘C#‘, message: ‘Hello C#‘ },
                    { id: ‘10002‘, name: ‘Java‘, message: ‘Hello Java.‘ },
                    { id: ‘10003‘, name: ‘C++‘, message: ‘Hello C++‘ },
                    { id: ‘10004‘, name: ‘JavaScript‘, message: ‘Hello JavaScript‘ }
                ]
            };
        }
    });
    var LangDetailComponent = Vue.extend({
        template: `<div><h1>{{ model.name }}</h1><p>{{ model.message }}</p></div>`,
        computed: {
            model: function(){
                var list = this.$root.list;
                var id = this.$route.params.id;
                for(var i = 0; i < list.length; i++){
                    if(list[i].id === id){
                        return list[i];
                    }
                }
            }
        },
        init:function () {
            alert("init");
        },
        created:function () {
            alert("created");
        },
        beforeCompile:function () {
            alert("beforeCompile");
        },
        compiled:function () {
            alert("compiled");
        },
        ready:function () {
            alert("ready");
        },
        attached:function () {
            alert("attached")
        },
        detached:function () {
            alert("detached")
        },
        beforeDestroy:function () {
            alert("beforeDestroy")
        },
        destroyed:function () {
            alert("destroyed")
        }

    });

    var router = new VueRouter();
    router.map({
        ‘/lang/:id‘: { component: LangDetailComponent }

    });
    router.start(AppComponent, ‘#app-container‘);
</script>

</body>
</html>

执行效果:

着三个路由都是同一个组件,但点击其他的时候组件中的所有生命周期的方法都没有调用,去vue-router的api上看没有找到重新加载路由的配置配置项.

在实际开发中这个问题在两个菜单共用一个组件,设置传参来判断加载不同的数据的情况下,会出现另一个ready方法不走导致数据显示不真确.解决思路可以加监听路由地址触发ready事件.

而上面的解决方法是用v-if来重新加载组件,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">

    <title>learning vue</title>
</head>
<body>

<div id="app-container">
    <ul>
        <li v-for="item in $root.list">
            <a  href="javascript:void(0)" @click="click(item.path)">{{ item.name }}</a>
        </li>
    </ul>
    <router-view v-if="show"></router-view>
</div>

<script src="js/vue.js"></script>
<script src="js/vue-router.js"></script>

<script>
    Vue.config.debug = true;
    Vue.use(VueRouter);
    var AppComponent = Vue.extend({
        data: function(){
            return {
                show:true,
                list: [
                    { id: ‘10001‘, name: ‘C#‘, message: ‘Hello C#‘,path:"/lan"},
                    { id: ‘10002‘, name: ‘Java‘, message: ‘Hello Java.‘,path:"/lan1"},
                    { id: ‘10003‘, name: ‘C++‘, message: ‘Hello C++‘ ,path:"/lan2"},
                    { id: ‘10004‘, name: ‘JavaScript‘, message: ‘Hello JavaScript‘,path:"/lan3" }
                ]
            };
        },
        methods:{
            click:function (path) {
                debugger;
                if(window.location.hash.replace("#!","")==path){
                    this.show=false;
                    Vue.nextTick(function () {
                        this.show=true;
                    }.bind(this))
                }else{
                    this.$router.go({path:path});
                }
            }
        }
    });
    var LangDetailComponent = Vue.extend({
        template: `<div><h1>C#</h1><p>232323</p></div>`,
        computed: {
            model: function(){
                var list = this.$root.list;
                var id = this.$route.params.id;
                for(var i = 0; i < list.length; i++){
                    if(list[i].id === id){
                        return list[i];
                    }
                }
            }
        },
        init:function () {
            alert("init");
        },
        created:function () {
            alert("created");
        },
        beforeCompile:function () {
            alert("beforeCompile");
        },
        compiled:function () {
            alert("compiled");
        },
        ready:function () {
            alert("ready");
        },
        attached:function () {
            alert("attached")
        },
        detached:function () {
            alert("detached")
        },
        beforeDestroy:function () {
            alert("beforeDestroy")
        },
        destroyed:function () {
            alert("destroyed")
        }

    });
    var LangDetailComponent1 = Vue.extend({
        template: `<div><h1>Java</h1><p>Hello Java.</p></div>`,
        computed: {
            model: function(){
                var list = this.$root.list;
                var id = this.$route.params.id;
                for(var i = 0; i < list.length; i++){
                    if(list[i].id === id){
                        return list[i];
                    }
                }
            }
        },
        init:function () {
            alert("init");
        },
        created:function () {
            alert("created");
        },
        beforeCompile:function () {
            alert("beforeCompile");
        },
        compiled:function () {
            alert("compiled");
        },
        ready:function () {
            alert("ready");
        },
        attached:function () {
            alert("attached")
        },
        detached:function () {
            alert("detached")
        },
        beforeDestroy:function () {
            alert("beforeDestroy")
        },
        destroyed:function () {
            alert("destroyed")
        }

    });
    var LangDetailComponent2 = Vue.extend({
        template: `<div><h1>C++</h1><p>Hello C++</p></div>`,
        computed: {
            model: function(){
                var list = this.$root.list;
                var id = this.$route.params.id;
                for(var i = 0; i < list.length; i++){
                    if(list[i].id === id){
                        return list[i];
                    }
                }
            }
        },
        init:function () {
            alert("init");
        },
        created:function () {
            alert("created");
        },
        beforeCompile:function () {
            alert("beforeCompile");
        },
        compiled:function () {
            alert("compiled");
        },
        ready:function () {
            alert("ready");
        },
        attached:function () {
            alert("attached")
        },
        detached:function () {
            alert("detached")
        },
        beforeDestroy:function () {
            alert("beforeDestroy")
        },
        destroyed:function () {
            alert("destroyed")
        }

    });
    var LangDetailComponent3 = Vue.extend({
        template: `<div><h1>JavaScript</h1><p>Hello JavaScript</p></div>`,
        computed: {
            model: function(){
                var list = this.$root.list;
                var id = this.$route.params.id;
                for(var i = 0; i < list.length; i++){
                    if(list[i].id === id){
                        return list[i];
                    }
                }
            }
        },
        init:function () {
            alert("init");
        },
        created:function () {
            alert("created");
        },
        beforeCompile:function () {
            alert("beforeCompile");
        },
        compiled:function () {
            alert("compiled");
        },
        ready:function () {
            alert("ready");
        },
        attached:function () {
            alert("attached")
        },
        detached:function () {
            alert("detached")
        },
        beforeDestroy:function () {
            alert("beforeDestroy")
        },
        destroyed:function () {
            alert("destroyed")
        }

    });

    var router = new VueRouter();
    router.map({
        ‘/lan‘: { component: LangDetailComponent },
        ‘/lan1‘: { component: LangDetailComponent1 },
        ‘/lan2‘: { component: LangDetailComponent2 },
        ‘/lan3‘: { component: LangDetailComponent3 }
    });
    router.start(AppComponent, ‘#app-container‘);
</script>

</body>
</html>

效果是:

这样在点相同的菜单,组件就重新加载,后面想优化每个菜单都加click,菜单很多话对页面是性能消耗,下篇想用vue能不能用事件委托绑定单击事件.暂时先写到这里.

这里在多说一句,Vue的路由是hash路由,所以要回去路由地址可以用 window.location.hash.replace("#!","")来获取.不知道hash路由的可以百度下,这里就不多说了

时间: 2024-08-28 05:27:25

用Vue中遇到的问题和处理方法(一)的相关文章

在vue中使用sass的配置的方法

1.创建一个基于 webpack 模板的新项目 vue init webpack myvue 2.在当前目录下,安装依赖 cd myvue npm install 3.安装sass的依赖包 npm install --save-dev sass-loader //sass-loader依赖于node-sass npm install --save-dev node-sass 4.在build文件夹下的webpack.base.conf.js的rules里面添加配置 { test: /\.sass

vue 中使用 AJAX获取数据的方法

在VUE开发时,数据可以使用jquery和vue-resource来获取数据.在获取数据时,一定需要给一个数据初始值. 看下例: <script type="text/javascript"> new Vue({ el:'#app', data:{data:""}, created:function(){ var url="json.jsp"; var _self=this; $.get(url,function(data){ _se

vue中moudles的作用及使用方法

1.作用:vuex允许把store分割为模块,每一个模块都有自己的state,actions,getters,mutations甚至是嵌套一些子模块,从上到下进行同样方式的分割 在文件src中创建一个文件夹store,包含index.js就是store.js ,然后再创建文件夹modules文件夹,此文件夹中放的就是模块, import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) import menu from './modules

vue中数据请求的三种方法

注意请求可能存在跨域问题,需要去配置好 这三种建议使用axios 1.resource Vue 要实现异步加载需要使用到 vue-resource 库. Vue.js 2.0 版本推荐使用 axios 来完成 ajax 请求. 先导入一个线上cdn的地址,当然还可以去npm安装,但个人觉得这种方便 <script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></scri

vue中动态添加class类名的方法

<template> <div> <h2>动态添加类名</h2> <!-- 第一种方式:对象的形式 --> <!-- 第一个参数 类名, 第二个参数:boolean值 --> <!-- 对象的形式: 用花括号包裹起来,类名用引号, --> <!-- 优点: 以对象的形式可以写多个,用逗号分开 --> <p :class="{'p1' : true}">对象的形式(文字的颜色)&l

vue 中 ajax请求封装以及使用方法

async/await 1)async/await场景 这是一个用同步的思维来解决异步问题的方案,当前端接口调用需要等到接口返回值以后渲染页面时. 2)名词解释 >async  async的用法,它作为一个关键字放到函数前面,用于表示函数是一个异步函数,因为async就是异步的意思, 异步函数也就意味着该函数的执行不会阻塞后面代码的执行,             async 函数返回的是一个promise 对象. >await await的含义为等待.意思就是代码需要等待await后面的函数运

vue项目中使用less或者sass的方法

半年木有更新博客了... 前段时间一直在学习vue,开始记录一下遇到的问题吧 这篇文章主要是总结一下vue中使用less或者sass的方法,以less为例(style.less) 主要是两种 1.对于写在vue文件中的less: 所有vue文件的<style lang="less"></style>,会被vue-loader处理编译到一个css文件中,最终自动通过link标签写入index.html(在vue-loader.conf.js中配置) <sty

理解Vue中的Render渲染函数

VUE一般使用template来创建HTML,然后在有的时候,我们需要使用javascript来创建html,这时候我们需要使用render函数.比如如下我想要实现如下html: <div id="container"> <h1> <a href="#"> Hello world! </a> </h1> </div> 我们会如下使用: <!DOCTYPE html> <html

vue中自定义指令

在vue中自定义标签,首先要调用vue中一个directive的方法,具体方法:Vue.direction('指令名称',function(){ }); 例如我们要写一个关于颜色的指令,叫v-colorred: 1 Vue.directive('colorred',function(){ 2 3 this.el.style.color='red'; 4 }); 在html中,我直接用v-colorred指令就可以了,例如: 1 <p v-colorred>1234567890</p>