引入vue.js

1.cnpm i vue -S

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

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中设置resolve

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

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

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

组件文件

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

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

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

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

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

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

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

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

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{ 
    opacity: 0;
    transform: translateX(100%);
}
.v-leave-to{
    opacity: 0;
    transform: translateX(-100%);
}

.v-enter-active,.v-leav-active{
    transition: all 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", component: index }
{ path: "/index/news", component: news }

路由子组件的注册

{
    path: "/index",
    component: index,
    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 - 学习总目录

最新文章

  1. 浅谈CPU和GPU的区别
  2. c# 利用动态库DllImport(&quot;kernel32&quot;)读写ini文件(提供Dmo下载)
  3. jQuery固定浮动侧边栏(jQuery fixed Sidebar)
  4. 重构第14天 分离职责(Break Responsibilities)
  5. [USACO]6.1.3 cow xor(二进制+Trie)
  6. [转]Android的Handler总结
  7. 如何修改配置以修复ThinkPad 小红帽滚轮失效?
  8. linux如何查进程、杀进程
  9. Apache Struts 多个开放重定向漏洞(CVE-2013-2248)
  10. IOS 在Xcode 4.x以上添加静态库
  11. js 之 Post发送请求
  12. 在用jQuery时遇到的小问题
  13. ORACLE数据库部分面试题目
  14. [Swift]LeetCode299. 猜数字游戏 | Bulls and Cows
  15. 【CentOS】PostgreSQL安装与设定
  16. macOS HomeBrew更换源 brew常用命令说明
  17. [svc]inotify+rsync解决nfs单点问题
  18. IntelliJ IDEA 创建Java Web项目
  19. [转]GAN论文集
  20. How do I learn mathematics for machine learning?

热门文章

  1. Long类型框架自动序列化成String失效问题排查
  2. .net core工具组件系列之Redis—— 第一篇:Windows环境配置Redis(5.x以上版本)以及部署为Windows服务
  3. MySQL触发器笔记
  4. hash表/哈希表
  5. 第十九篇 -- QTableWidget的使用
  6. 第十篇 -- 下拉列表框QComboBox
  7. python中进程详解
  8. (Opencv06)绘制轮廓函数
  9. jquery.autocomplete 使用解析
  10. 题解 P6892 [ICPC2014 WF]Baggage