Javascript - Vue - webpack中的组件、路由和动画

引入vue.js

1.cnpm i vue -Scss

2.在mian.js中引入vue文件html

import Vue from "vue"
//在main.js中使用这种方式引用vue文件时,webpack默认会到node_modules/vue/dist目录找到package.json文件里的配置,这个文件的mian属性指向了node_modules/vue/dist/vue.runtime.common.js
//这个路径指向的vue文件就是import Vue from "vue"中的"vue",它只是一个运行时加载的不完整的vue文件
//能够经过设置webpack.config.js中的resolve属性,让它正确指向完整的vue文件。若是不向对路径进行配置,你还能够直接使用import Vue from "../node_modules/vue/dist/vue.js"

3.在webpack.config.js中设置resolvevue

resolve{
    alias{
        'vue''vue/dist/vue.js'
    }
}

4.在html页面将bundle.js的引入放在html结尾处。node

……
</html>
<script src="/bundle.js"></script>

组件文件

组件不必定要写在js文件里,还有一种之后缀名为.vue的文件结合render渲染的方式也可使用组件。webpack

1.在src目录建立一个login.vue的组件文件git

打开文件输入如下代码,ue组件文件的代码提示工具:veturgithub

<template>
<div>
    <h5>这是经过xx.vue文件定义的组件</h5>
</div>
</template>

<script></script> 
<style></style> 

2.安装vue-loader,用它来解析vue组件文件web

2-1.cnpm info vue先查看vue的版本ajax

2-2.cnpm i vue-template-compiler@2.6.10 -D (安装vue-loader的依赖vue-template-compiler,compiler这个包必须和vue的版本保持一致,不然报错)vue-router

2-3.cnpm i vue-loader -D

3.在webpack.config.js中配置

const VueLoaderPlugin = require('vue-loader/lib/plugin');
//或    
const { VueLoaderPlugin } = require('vue-loader');


plugins[
    new VueLoaderPlugin()
],
{ test: /\.vue$/, use'vue-loader'}

4.在main.js中引入vue和login.vue,vue组件文件只能经过render来渲染,不能以注册为components组件进行使用。

import Vue from "vue"
import login from "./login.vue"

var vm = new Vue({
    el: "#box",   
 data:{msg:"hello"}
    // components:{
    //     login:login
    // }这种方式没法引入组件文件里的组件
    render:createHtml=>createHtml(login)

});

5.在index.html中调用vue

<body>
    <div id="box">
        <p>{{msg}}</p> //组件文件里的html会替换掉id为box的盒子及其内容      
    </div>
</body>

组件文件中组件的内部数据

在src目录下建立components目录,在该目录下建立app.vue

<template>
    <div>
        <p>{{msg}}</p>
        <button @click="show">OK</button>
    </div>
</template>

<script>
export default{
    data:function() {
        return {msg:"hello"}
    },
    methods:{
        show:function(){
            alert("OK");
        }
    }
}
</script>

<style></style>

在main.js中导入组件

import Vue from "vue"
import app from "./components/app.vue"

var vm=new Vue({
    el:"#box",
    render:createEls=>createEls(app)
})

组件文件的style标签

组件文件中能够写css样式,能够选择在当前<style>标签里写的样式是在当前组件的做用域(scoped)可用仍是在全局可用、是应用less样式仍是css或sass样式,加scoped的原理是它会自动为你的组件根元素增长一个css属性,而后经过属性选择器为这个组件应用你设置的css样式。若是是在当前做用域可用,则你的css样式只针对当前组件里的htm,其它诸如设置body等是无效的。

<template>
    <div>
        组件
    </div>
</template>
<style scoped lang="less">
div{
    background:rgb(67, 0, 252);
    color:#fff;
    p{
        color:blue;
    }
}
</style>

组件文件的导入

导入组件文件就是导入组件对象,默认状况下不须要使用export语法将组件文件里的组件导出到外部,外部只须要直接import引入.vue文件所在路径便可导入组件。只有在引入本身建立的js文件时则须要提供js文件的路径。

路由组件

1.cnpm i vue-router -S 安装处理路由的js包

2.导入路由组件,如今假设建立了两个组件(account.vue和productList.vue)

3.建立你的router.js文件,在文件中导入官方的vue-router.js和组件文件

import Vue from "vue"
import VueRouter from "vue-router"
import account from "./components/account.vue"
import productList from "./components/productList.vue"

Vue.use(VueRouter); //在webpack中使用vue路由时须要调用这个方法来获得vue-router.js包,注册路由包到vue对象上

var router=new VueRouter({
    routes:[
        {path:"/",redirect:"/account"},
        {path:"/account",component:account},
        {path:"/productList",component:productList}
    ]
});


而后将你编写路由文件导入到main.js中

import  Vue  from  "vue" ;
import  router  from  "./js/router"  //你编写的关于路由的js文件

var  vm  =  new  Vue ({
    el :  ".box" ,    
    router :  router
});

在html页面中引入router-view

<div id="box">
    <router-link to="/account">帐户</router-link>
    <router-link to="/productList">图书列表</router-link>
    <router-view></router-view> 
</div>

若是上面例子中的vue内部使用了render来渲染某个组件到页面,同时还使用了router-view,那么由于render渲染组件后会替换掉#box元素,因此router-view中的路由组件是不会显示的,解决办法是将router-link及其router-view放在render所渲染的那个组件里,好比render了一个叫作app的组件,代码以下

<template>
    <div>
        这是普通的app组件
        <router-link to="/account">帐户</router-link>
        <router-link to="/productList">图书列表</router-link>
        <router-view></router-view> 
    </div>
</template>

*还能够把建立路由对象的代码移植到单独的js文件中,经过导入路由对象来使用它。

*粗劣总结一下就是将普通组件注册到路由匹配里的组件就是路由组件

路由子组件

与没有使用webpack时的写法是同样的,将子组件的router-link和router-view放在父组件的template中

import account from "./components/account.vue"
import login from "./components/login.vue"
import register from "./components/register.vue"
import productList from "./components/productList.vue"

Vue.use(VueRouter);

var router = new VueRouter({
    routes: [
        { path: "/", redirect: "/account" }, //访问根目录时自动转到帐户组件的匹配上
        {
            path: "/account",
            redirect:"/account/login", //访问帐户组件时自动转到登陆子组件的匹配上
            component: account,
            children:[
                {path:"/account/login",component:login},
                {path:"/account/register",component:register}
            ]
        },
        { path: "/productList", component: productList }
    ]
});

var vm = new Vue({
    el: "#box",
    router: router   
});

组件切换的动画

<transition mode="out-in">
    <router-view></router-view>
</transition>
.v-enter
    opacity0;
    transformtranslateX(100%);
}
.v-leave-to{
    opacity0;
    transformtranslateX(-100%);
}

.v-enter-active,.v-leav-active{
    transitionall 0.3s ease;
}

总结一下就是:vue-router.js路由是指不向服务端发起请求,在路由对象中设置路由匹配规则,建立vue文件,将该文件导入到路由对象所在的那个js文件中,再将路由对象注册到vue对象上。当发起路由请求时由vue对象捕获请求,接着调用路由对象对路由请求进行匹配,匹配成功则展示对应的组件到router-view中

分清路由子组件和普通子组件

路由子组件是将普通组件注册到路由对象内部的某个路由匹配规则的children中,这样该组件才能成为路由子组件。而普通子组件是将一个普通的组件注册到vue对象或其余组件对象的内部的components中。二者的最大区别在于路由子组件一般都是大于1个,由于大于1个的子组件们须要在一个router-view中进行切换显示(同级别的组件之间的切换显示),而普通的子组件不存在同级别的切换显示,也即若是该子组件不须要同级别的切换显示,则只须要将它注册在vue对象或其余组件对象之中(经过属性components注册),若是它须要和与它同级别的组件之间进行切换显示,那么能够考虑将它们作成子路由组件。

下图是普通路由组件

点击首页中的新闻路由组件,显示新闻路由组件

 

下图是路由子组件

下图是普通子组件

这个页面是一个新闻路由组件,在这个组件内部有一个普通的子组件(评论区)

 

普通子组件的注册

var vm = new Vue({
    components: {
        mycom:com
    }
});
//或
export default {

    components: {
        mycom:com
    }
}

路由组件的注册

{ path"/index", componentindex }
{ path"/index/news", componentnews }

路由子组件的注册

{
    path"/index",
    componentindex,
    children[{ path: "news" }]
}

组件的正确使用方式

如下是一个展现图片的模块,点击导航栏的菜单能够切换不一样类型的图片。这个组件叫作shareImg.vue,导航栏下面的图片如何显示?此处并无把图片区域作成一个路由子组件(在这个组件页面使用router-link和router-view)。仅仅用了一个普通的ul列来呈现图片。若是你使用路由子组件来做为图片的容器,看起来彷佛很不错,由于当你切换导航栏菜单的同时就会切换router-view里的图片组件,可是这样作就须要导航栏所对应的组件文件,也即,7个菜单项就须要建立它们所对应的7个组件文件,若是你针对导航菜单的切换只使用一个组件去承载(由于每一个导航菜单获得的数据的html模板都是彻底同样的),那么当点击菜单发起请求后,只有第一次会成功,当你再点击其它菜单时,切换不会发生,由于第一次点击时已经把惟一的一个展现图片的组件渲染出来了,该组件对象已经存在,因此再次点击菜单不会再重复渲染。正确作法是只须要在这个组件的内部使用一个ul,当导航到这个组件页面的时发起两个不一样的ajax请求,分别请求各自的数据。这样就能够把数据分别装载到各自的html中(导航栏和图片容器),当点击菜单后,触发绑定在超连接上的click事件,click事件调用获取数据的方法便可再次发起请求得到不一样的图片数据。

*总结一下:在一个组件文件中,路由子组件只适合于点击不一样的按钮时会请求不一样的组件文件,若是点击不一样的按钮所切换的组件模板是彻底同样的,就不须要定义组件,而是直接使用html。

第三方组件

Mint-UI

mint-ui是基于vue开发的第三方移动端的js组件,具体参考:Mint-UI

使用cnpm install mint-ui -S能够安装此组件包,但若是只想引入这个包的部分组件,除了执行安装命令以外还须要安装babel-plugin-component插件。

1.cnpm i babel-plugin-component -D

2.在扩展名为.babelrc的文件中输入如下代码,下面的代码复制到babelrc中可能会提示语法格式错误,不用管它,复制完直接保存。

{  
    "plugins"[
        ["component",
            [
                {
                    "libraryName": "mint-ui",
                    "style": true
                }
            ]
        ]
    ]
}

3.在webpack.config.js中添加处理mint-ui所使用的ttf文件的loader

{ test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, use'url-loader' },

4.以上完成以后,在import的时候不须要完整引入mint-ui(import MintUI from 'mint-ui'),不须要把MintUI注册到Vue上(Vue.use(MintUI)),也不须要再引入mint-ui的css(import "../node_modules/mint-ui/lib/style.css")。只须要以下引入便可使用

import Vue from "vue" //mint-ui依赖于vue.js
import { Button } from 'mint-ui'
//有两种方式将mint-ui组件注册到vue上
//1.注册到全局上
Vue.component(Button.name, Button); //这种方式能够改Button的标签名字
//2.注册为私有组件
var vm=new Vue({
  el:"#box",
  components:{
  mtButton:Button
 }
})

<mt-button size="large" type="danger">OK</mt-button>

*若是你导入了mint-ui,那么注意在组件文件里的style标签不能使用scope,不然style标签里的css会失效。

*mint ui的组件中可能包含其余的组件,好比<mt-header>里可能包含<mt-button>,引入header组件后则还须要引入buttom

使用Mint ui的固定标题栏组件

在main.js中导入

import { Header } from 'mint-ui';
import { Button } from 'mint-ui';
import app from "./components/app.vue" //首页框架页面
Vue.component(Header.name, Header)
Vue.component(Button.name, Button)

var vm=new Vue({
    el:"#box",    
    render:c=>c(app),
    router:router
})

在app.vue中

<mt-header fixed title="hello vue!" class="fix-header">
    <span @click="goBack" slot="left" v-show="flag">
        <mt-button icon="back" class="fix-header-btn">返回</mt-button>
    </span>
    <mt-button icon="more" slot="right"></mt-button>
</mt-header>
export default {
    data: function () {
        return {
            flag: true
        };
    },
    methods: {
        goBack: function () {
            this.$router.go(-1);
        },
        setHaederShow: function () {
            //若是当前路由地址是主页,则不显示后退按钮
            this.flag = this.$route.path === "/index" ? false : true;
        }
    },
    created: function () {
        this.setHaederShow();
    },
    watch: {
        "$route.path": function (newVal) {
            this.setHaederShow();
        }
    }
};

Javascript - 学习总目录

相关文章
相关标签/搜索