• Vue&webpack入门实践


    1. 下载安装Vue

    1. 先安装好Node.js,因为接下来要使用其中的NPM安装Vue。
    2. 建议使用Vscode作为编辑器:创建一个文件夹,用Vscode打开。
    3. 打开Vscode的命令行窗口,输入命令npm init -y对文件夹进行初始化,完成后多了个package.json文件。
    4. 输入命令npm install vue --save命令安装Vue。

    安装完后多了一个文件夹node_modules和package-lock.json,node_modules是NPM安装的模块的默认存放位置,打开发现其中有个Vue文件夹。

    2. Vue

    2.1 Vue要素

    先看一个例子

    <!DOCTYPE html>
    <html>
    <head>
        <!-- 注意路径-->
        <script src="../node_modules/vue/dist/vue.js"></script>
    </head>
    
    <body>
        <div id="app">
            数量为:<input type="text" v-model="num"><br>
            <button v-on:click="increase">点我+1</button>
        </div>
        <script type="text/javascript">
            var app = new Vue({
                el: "#app", 
                data: {
                    num: 1
                },
                methods: {
                    increase: function() {
                        this.num++;
                    }
                }
            })
        </script>
    </body>
    </html>
    

    效果: 设置文本框中的数字,点击+1后在原来的基础上增加1。

    2.1.1 创建Vue实例

    创建方式如下,

    el表示要关联的HTML模版的id,

    data表示模版中数据的初始值,

    methods定义了模板中出现的函数。

    var app = new Vue({
         el: "#app", 
         data: {num: 1},
         methods: {
             increase: function() {
                 this.num++;
             }
         }
    })
    

    注意:这段代码必须写在html模版下面,否则不生效。

    2.1.2 Html模版

    要渲染的html模版,其id为app对应于Vue构造函数中el的值#app

    Vue只能渲染这个div内部的变量,方法等元素。

    <div id="app">
            数量为:<input type="text" v-model="num"><br>
            <button v-on:click="increase">点我+1</button>
    </div>
    

    2.1.3 数据和视图

    这是Vue的特性:双向绑定

    上面的例子中,点击+1按钮,触发increase方法,Vue实例中的num+1,文本框中显示的数字+1;

    改变文本框中的数字,再点+1按钮,数字就会在原来基础上+1,说明修改显示内容也能修改对应的Vue实例中的变量。

    这就是视图和数据的双向绑定,修改视图,数据就变;修改数据,视图也变。

    2.1.4 方法

    按钮通过v-on:click指令绑定了increase方法,方法的定义在Vue对象的methods属性里面。

    html

    <button v-on:click="increase">点我+1</button>
    

    js

    var app = new Vue({
         ...
         methods: {
             increase: function() {
                 this.num++;
             }
         }
    })
    

    2.1.5 生命周期

    每个Vue实例在被创建时都要经过一系列的初始化过程,比如创建实例,装载模板等等。Vue为生命周期的每个状态都设置了监听函数。此处应该有个图片,但这个图片太长了,给个地址自己看去吧

    图片地址

    使用方式如下

    var vm = new Vue({
        el:"#app",
        data:{...},
        //监听函数
        created(){
            ...
        }
    })
    

    2.2 指令

    2.2.1 插值表达式

    像jsp中的EL表达式一样,显示变量或者一个表达式的结果,有{{}}v-textv-html三种指令

    v-html指令输出html文本后会自动渲染。

    代码

    <div id="test1">
            “花括号表达式的值:”{{1+1}}<br>
            “v-text”标签输出表达式的值:<span v-text="1+1"></span> <br>
            “v-html”标签输出表达式的值:<span v-html="1+1"></span> <br>
            “花括号输出文本内容:”{{hello}}<br>
            “v-text”标签输出普通文本:<span v-text="hello"></span> <br>
            “v-html”标签渲染html文本:<span v-html="hello"></span>
        </div>
        <script type="text/javascript">
            var app = new Vue({
                el: "#test1",
                data: {
                    hello: "<h1>大家好,我是小明</h1>"
                }
            })
        </script>
    

    结果

    2.2.2 v-model

    插值表达式只能通过改变变量来改变显示的内容,而v-model指令可以让数据和视图相互影响。

    由于视图可操作,因此限制了对应的html标签的种类。v-model指令支持的标签有

    • input
    • select
    • textarea
    • checkbox
    • radio
    • components(Vue中的自定义组件)

    代码

    	<div id="test2">
            <input type="checkbox" v-model="language" value="Java" />Java<br />
            <input type="checkbox" v-model="language" value="PHP" />PHP<br />
            <input type="checkbox" v-model="language" value="Swift" />Swift<br />
            <h1>
                你选择了:{{language.join(',')}}
            </h1>
        </div>
        <script type="text/javascript">
            var vm = new Vue({
                el: "#test2",
                data: {
                    language: []
                }
            })
        </script>
    

    结果

    选择复选框后显示的内容会对应变化;后台修改数据,显示的选择项也会变化。

    2.2.3 v-on

    为元素绑定事件。比如绑定点击事件的语法是v-on:click,可以简写为@click

    <!-- 给页面元素绑定事件 -->
        <div id="test3">
            <!--事件中直接写js片段-->
            <button v-on:click="num++">增加</button><br />
            <!--事件指定一个回调函数,必须是Vue实例中定义的函数-->
            <button v-on:click="decrement">减少</button><br />
            <!-- 简写方式 -->
            <button @click="decrement">减少</button><br />
            <!--键盘事件-->
            <button @keyup.enter="num++">先使我获得焦点,然后按下enter键增加</button><br />
            <h1>num: {{num}}</h1>
        </div>
    
        <script type="text/javascript">
            var app = new Vue({
                el: "#test3",
                data: {
                    num: 1
                },
                methods: {
                    decrement() {
                        this.num--;
                    }
                }
            })
        </script>
    

    2.2.4 v-for

    用于循环遍历数据

    遍历数组

    <!-- 遍历数组 -->
        <div id="test4">
            <ul>
                <li v-for="(user,index) in users">
                    {{index}} - {{user.name}} : {{user.gender}} : {{user.age}}
                </li>
            </ul>
        </div>
        <script type="text/javascript">
            var vm = new Vue({
                el: "#test4",
                data: {
                    users: [{
                            name: '小红',
                            gender: '女',
                            age: 11
                        },
                        {
                            name: '小明',
                            gender: '男',
                            age: 10
                        }
                    ]
                }
            })
        </script>
    

    遍历对象

        <div id="test5">
            <ul>
                <li v-for="(value,key,index) in user">
                    {{index}} - {{key}} : {{value}}
                </li>
            </ul>
        </div>
        <script type="text/javascript">
            var vm = new Vue({
                el: "#test5",
                data: {
                    user: {
                        name: '小明',
                        gender: '男',
                        age: 10
                    }
                }
            })
        </script>
    

    2.2.5 v-if和v-show

    v-if用于条件判断

    	<div id="test6">
            <!--事件中直接写js片段-->
            <button v-on:click="show = !show">点击切换</button><br />
            <h1 v-if="show">
                你好
            </h1>
        </div>
        <script type="text/javascript">
            var app = new Vue({
                el: "#test6",
                data: {
                    show: true
                }
            })
        </script>
    

    点击按钮,文本内容会隐藏。

    v-if也可以和v-for结合使用

    <div id="test7">
            <ul>
                <li v-for="(user,index) in users" v-if="user.gender === '女'">
                    {{index}} - {{user.name}} : {{user.gender}} : {{user.age}}
                </li>
            </ul>
        </div>
        <script type="text/javascript">
            var vm = new Vue({
                el: "#test7",
                data: {
                    users: [{
                            name: '小红',
                            gender: '女',
                            age: 10
                        },
                        {
                            name: '小明',
                            gender: '男',
                            age: 10
                        }
                    ]
                }
            })
        </script>
    
    

    结果只显示一个小红

    有if当然也有else和elseif

    <div v-if="type === 'A'">
      A
    </div>
    <div v-else-if="type === 'B'">
      B
    </div>
    <div v-else-if="type === 'C'">
      C
    </div>
    <div v-else>
      Not A/B/C
    </div>
    

    v-show控制元素的显示,如果元素隐藏了,并不是从dom中移除,而是设置display为none

    <div id="test6">
            <!--事件中直接写js片段-->
            <button v-on:click="show = !show">点击切换</button><br />
            <h1 v-show="show">
                你好
            </h1>
        </div>
        <script type="text/javascript">
            var app = new Vue({
                el: "#test6",
                data: {
                    show: true
                }
            })
    </script>
    

    2.2.6 v-bind

    假如我们想改变class属性,这样写是错误的

    <div class="{{isAcctive}}"></div>
    

    因为插值表达式不能用于属性的值中

    我们可以借助v-bind:class指令,可以简写为:class

        <div id="test8">
            <div :class="isActive">注意class的值</div>
        </div>
        <script type="text/javascript">
            var app = new Vue({
                el: "#test8",
                data: {
                    isActive: ['active', 'hasError']
                }
            })
        </script>
    

    结果

    2.2.7 计算属性

    在插值表达式中写一长串代码很难看,可以用“计算属性”来替代,这个属性实际上是个方法,将方法名以变量形式绑定到插值表达式中了:

    	<div id="test9">
            <h1>您的生日是:{{birth}} </h1>
        </div>
        <script type="text/javascript">
            var app = new Vue({
                el: "#test9",
                data: {
                    birthday: 1429032123201 // 毫秒值
                },
                computed: {
                    birth() { // 计算属性本质是一个方法,但是必须返回结果
                        const d = new Date(this.birthday);
                        return d.getFullYear() + "-" + d.getMonth() + "-" + d.getDay();
                    }
                }
            })
        </script>
    

    结果

    2.2.8 watch

    假如我们要监控用户输入了什么内容,可以用监控属性来实现

        <!-- 监控属性变化 -->
        <div id="test10">
            <input type="text" v-model="message">
        </div>
        <script type="text/javascript">
            var vm = new Vue({
                el: "#test10",
                data: {
                    message: ""
                },
                watch: {
                    message(newVal, oldVal) {
                        console.log(newVal, oldVal);
                    }
                }
            })
        </script>
    

    结果

    在文本框输入good,控制台记录了每个按键按下的动作


    2.3 组件化

    一个页面中总有相同的部分可以抽取出来做为组件使用,Vue提供了定义组件的方法。

    2.3.1 全局组件

    代码

    	<div id="test1">
            <counter></counter>
        </div>
    
        <script type="text/javascript">
            // 定义全局组件,参数1,组件名称;参数2,组件参数。
            // 用html模板替换掉了counter标签,注意数据传递的方式,是data()而不是data
            Vue.component("counter", {
                template: '<button v-on:click="count++">你点了我 {{ count }} 次</button>',
                data() {
                    return {
                        count: 0
                    }
                }
            })
    
            var app = new Vue({
                el: "#test1"
            });
        </script>
    

    页面表现


    • 组件也是一个Vue实例,因此它在定义时也会接收:data、methods、生命周期函数等
    • 不同的是组件不会与页面的元素绑定,否则就无法复用了,因此没有el属性。
    • 但是组件渲染需要html模板,所以增加了template属性,值就是HTML模板
    • 全局组件定义完毕,任何vue实例都可以直接在HTML中通过组件名称来使用组件了。
    • data的定义方式比较特殊,必须是一个函数。

    定义全局组件后,可以在其他地方使用。

    值得注意的一点:使用者必须也是一个Vue实例

        <div id="test2">
            <counter></counter>
            <counter></counter>
            <counter></counter>
        </div>
    
        <script type="text/javascript">
            var app = new Vue({
                el: "#test2"
            });
        </script>
    

    现象

    可以看出:每个组件都维护自己的一份变量

    2.3.2 局部组件

    就像定义变量一样定义了一个局部组件localCounter,将其注册到我们自定义的<test-component></test-component>标签中。

    注意:此处用了驼峰命名法来对应标签:testComponent对应于test-component

        <div id="test3">
            <test-component></test-component>
        </div>
    
        <script type="text/javascript">
            const localCounter = {
                template: 
                	'<button v-on:click="count++">我是局部组件:你点了我 {{ count }} 次</button>',
                data() {
                    return {
                        count: 0
                    }
                }
            };
            var app = new Vue({
                el: "#test3",
                components: {
                    testComponent: localCounter
                }
            });
        </script>
    

    2.3.3 组件通信

    2.3.3.1 父向子通信

    下面的例子展示了:父组件得到lessons的数据后传递到子组件中,以子组件的模板显示

    	<div id="test4">
            <parent :items="lessons" />
        </div>
        <script type="text/javascript">
            //子组件,通过props来接收父组件传过来的数据
            //这个子组件是一个局部组件
            const son = {
                template: 
                '<ul>
                    <li v-for="item in items" :key="item.id">{{item.id}} : {{item.name}}</li>
                </ul>',
                props: {
                    items: {
                        type: Array,
                        default: []
                    }
                }
            }
    
            var app = new Vue({
                el: "#test4",
                components: {
                    parent: son
                },
                data: {
                    lessons: [
                        {id: 1,name: 'java'},
                        {id: 2,name: 'php'},
                        {id: 3,name: 'ios'},
                    ]
                }
            })
        </script>
    
    

    现象

    2.3.3.2 子向父通信

    代码

    <div id="test5">
            <h2>num: {{num}}</h2>
            <my-component @inc="increment" @dec="decrement"></my-component>
        </div>
    
        <script type="text/javascript">
            Vue.component("myComponent", {
                template: '
                    <div>
                        <button @click="plus">加</button>  
                        <button @click="reduce">减</button>  
                    </div>',
                methods: {
                    plus() {
                        this.$emit("inc");
                    },
                    reduce() {
                        this.$emit("dec");
                    }
                }
            })
            var app = new Vue({
                el: "#test5",
                data: {
                    num: 0
                },
                methods: {
                    increment() {
                        this.num++;
                    },
                    decrement() {
                        this.num--;
                    }
                }
            });
        </script>
    

    现象

    点击加按钮,数值增加;点击减按钮,数量减少。

    解释

    父组件是

    <my-component @inc="increment" @dec="decrement"></my-component>
    

    子组件是

    Vue.component("myComponent", {
                template: '
                    <div>
                        <button @click="plus">加</button>  
                        <button @click="reduce">减</button>  
                    </div>',
                methods: {
                    plus() {
                        this.$emit("inc");
                    },
                    reduce() {
                        this.$emit("dec");
                    }
                }
    })
    

    想要通过子组件中的加和减按钮实现num的加和减,就要调用父组件的函数。

    $emit()方法是Vue提供的用于调取父组件绑定函数的函数。

    最后流程就是:点击加按钮,调用子组件的plus方法,plus方法调取父组件的increment方法实现num的增加操作。

    2.4 vue-router

    2.4.1 安装vue-router

    安装命令npm install vue-router --save

    引入依赖

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

    2.4.2 实现功能

    利用vue-router实现登录注册菜单的切换:

    点击登录后显示登录页

    点击注册后显示注册页

    将登录、注册和路由分成三个组件,由index.html引入并使用。目录结构如下

    login.js

    const loginForm = {
        template:'
        <div>
        <h2>登录页</h2> 
        用户名:<input type="text"><br/>
        密码:<input type="password"><br/>
        </div>
        '
    }
    

    register.js

    const registerForm = {
        template:'
        <div>
        <h2>注册页</h2> 
        用户名:<input type="text"><br/>
        密码:<input type="password"><br/>
        确认密码:<input type="password"><br/>
        </div>
        '
    }
    

    router.js

    // 根据路径渲染对应的组件
    const indexRouter = new VueRouter({
        routes:[
            {
                path:"/login",
                component: loginForm
            },
            {
                path: "/register",
                component: registerForm
            }
        ]
    })
    

    index.html

    <!DOCTYPE html>
    <html>
    <head>
        <script src="../node_modules/vue/dist/vue.js"></script>
        <script src="../node_modules/vue-router/dist/vue-router.js"></script>
    </head>
    
    <body>
        <div id="app">
            <!-- 跳转链接,点击后将地址传送给router  -->
            <span><router-link to="/login">登录</router-link></span>
            <span><router-link to="/register">注册</router-link></span>
            <hr/>
            <div>
                 <!-- 路由锚点,点击跳转链接后router会在此渲染对应组件的html模板-->
                <router-view></router-view>  
            </div>
        </div>
        <script src="js/login.js"></script>
        <script src="js/register.js"></script>
        <script src="js/router.js"></script>
    
        <script type="text/javascript">
            var vm = new Vue({
                el: "#app",
                router: indexRouter  //使用路由
            })
        </script>
    </body>
    </html>
    

    3. webpack

    3.1 webpack简介

    Webpack 是一个前端资源的打包工具,它可以将js、image、css等资源打包成一个整体,压缩混淆提高性能和安全性,将高级语法转义,提高兼容性。

    3.2 四个核心概念

    • 入口(entry)

      webpack打包的启点,可以有一个或多个,一般是js文件。webpack会从启点文件开始,寻找启点直接或间接依赖的其它所有的依赖,包括JS、CSS、图片资源等,作为将来打包的原始数据。

    • 输出(output)

      出口一般包含两个属性:path和filename。用来告诉webpack打包的目标文件夹,以及文件的名称。目的地也可以有多个。

    • 加载器(loader)

      webpack本身只识别Js文件,如果要加载非JS文件,必须指定一些额外的加载器(loader),例如css-loader。然后将这些文件转为webpack能处理的有效模块,最后利用webpack的打包能力去处理。

    • 插件(plugins)

      插件可以扩展webpack的功能,让webpack不仅仅是完成打包,甚至各种更复杂的功能,或者是对打包功能进行优化、压缩,提高效率。

    3.3 安装

    执行命令npm install webpack webpack-cli --save-dev

    在package.json里多了几行配置,分别是运行时依赖和开发依赖

    3.4 配置

    先在package.json同级的目录下新建webpack.config.js文件。

    接下来以vue-router的demo为例演示webpack的用法。

    3.4.1 配置入口

    入口一般是一个或多个js文件,通过这些js文件找出相关的所有依赖树,最后打包输出。

    在vue-router的demo里面,index.html引用了相关的js,但它是html文件,不适合作为启点。

    因此我们需要一个额外的main.js引入其他所有的js。

    main.js

    //ES6语法导入js模块,注意:不带.js后缀
    import Vue from '../node_modules/vue/dist/vue'
    import VueRouter from '../node_modules/vue-router/dist/vue-router'
    import loginForm from './js/login'
    import registerForm from './js/register'
    
    //VueRouter使用模块加载,必须加上这一句
    Vue.use(VueRouter)
    
    const indexRouter = new VueRouter({
        routes:[
            {
                path:"/login",
                component: loginForm
            },
            {
                path: "/register",
                component: registerForm
            }
        ]
    })
    
    var vm = new Vue({
        el: "#app",
        router: indexRouter
    })
    

    loginForm和registerForm都是做为js模块导入的,他们自己也要分别追加导出语句。

    在login.js中追加一句

    export default loginForm;
    

    在register.js中追加一句

    export default registerForm;
    

    最后配置入口:在webpack.config.js中指定入口文件

    module.exports={
        entry:'./src/main.js',  //指定打包的入口文件
    }
    

    3.4.2 配置出口

    在webpack.config.js中指定出口路径和最终输出的文件名,最终的js如下

    module.exports={
        entry:'./src/main.js',  //指定打包的入口文件
        output:{
            // path: 输出的目录,__dirname是相对于webpack.config.js配置文件的绝对路径
            path : __dirname+'/dist',  
            filename:'build.js'	 //输出的js文件名
        }
    }
    

    3.5 执行打包并测试运行

    执行命令npx webpack --config webpack.config.js

    去掉index.html中的js引用标签,只引用打包好的build.js

    <script src="../dist/build.js"></script>
    

    测试运行,结果与打包之前一样。

    3.6 打包CSS

    webpack的四个核心概念,我们目前只使用了两个:入口和出口。

    接下来使用加载器,加载非js资源,比如CSS。

    3.6.1 安装加载器

    执行命令:npm install style-loader css-loader --save-dev

    3.6.2 编写css

    新建一个和js目录同级的css文件夹,里面新建main.css

    #app a{
        display: inline-block;
         150px;
        line-height: 30px;
        background-color: dodgerblue;
        color: white;
        font-size: 16px;
        text-decoration: none;
    }
    #app a:hover{
        background-color: whitesmoke;
        color: dodgerblue;
    }
    #app div{
         300px;
        height: 150px;
    }
    #app{
         400px;
        border: 1px solid dodgerblue;
    }
    

    3.6.3 引入css模块

    在main.js中添加import语句

    import './css/main.css'
    

    3.6.4 配置加载器

    在webpack.config.js里配置,最终如下所示

    module.exports={
        entry:'./src/main.js',  //指定打包的入口文件
        output:{
            // path: 输出的目录,__dirname是相对于webpack.config.js配置文件的绝对路径
            path : __dirname+'/dist',  
            filename:'build.js'	 //输出的js文件名
        },
        module: {
            rules: [
                {
                    test: /.css$/, // 通过正则表达式匹配所有以.css后缀的文件
                    use: [ // 要使用的加载器,这两个顺序一定不要乱
                        'style-loader',
                        'css-loader'
                    ]
                }
            ]
        }
    }
    

    3.6.5 重新打包并运行

    依然是执行npx webpack --config webpack.config.js

    最终的CSS效果能够展示出来(不贴图片了)。

    注意:所有的js、css最终都被放到了build.js里面。

    3.7 快速执行打包命令

    package.json里面可以配置脚本,在scripts标签里面添加"build": "webpack"

    {
      "name": "vue-test",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo "Error: no test specified" && exit 1",
        "build": "webpack"
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
      "dependencies": {
        "vue": "^2.6.10",
        "vue-router": "^3.0.6"
      },
      "devDependencies": {
        "css-loader": "^2.1.1",
        "style-loader": "^0.23.1",
        "webpack": "^4.33.0",
        "webpack-cli": "^3.3.3"
      }
    }
    
    

    这样就可以执行npm run build命令进行打包,代替原先的npx webpack --config webpack.config.js命令。

    3.8 打包html

    之前都是将js、css等相关文件打包好,最后手动引入到index.html中。

    而webpack的html打包插件,可以把html和js、css等一起打包直接生成可用的页面。

    3.8.1 安装并配置插件

    执行npm install --save-dev html-webpack-plugin命令安装

    配置webpack.config.js,最终如下

    const HtmlWebpackPlugin = require('html-webpack-plugin');
    
    module.exports={
        entry:'./src/main.js',  //指定打包的入口文件
        output:{
            // path: 输出的目录,__dirname是相对于webpack.config.js配置文件的绝对路径
            path : __dirname+'/dist',  
            filename:'build.js'	 //输出的js文件名
        },
        module: {
            rules: [
                {
                    test: /.css$/, // 通过正则表达式匹配所有以.css后缀的文件
                    use: [ // 要使用的加载器,这两个顺序一定不要乱
                        'style-loader',
                        'css-loader'
                    ]
                }
            ]
        },
        plugins:[
            new HtmlWebpackPlugin({
                title: '首页',  //生成的页面标题<head><title>首页</title></head>
                filename: 'index.html', // dist目录下生成的文件名
                template: './src/index.html' // 我们原来的index.html,作为模板
            })
        ]
    }
    

    3.8.2 打包查看效果

    去掉原先index.html里面的引用build.js的标签

    执行打包命令npm run build

    发现dist文件夹下多了个index.html,运行发现效果与之前一致。

    3.9 热更新

    每次修改js或css都要重新打包,麻烦,webpack提供了一个热更新插件,这个插件搞了一个服务器,

    我们修改代码后,可以自动检测修改并更新。

    安装命令是:npm install webpack-dev-server --save-dev

    之后在package.json中的scripts标签下添加

    "dev": "webpack-dev-server --inline --hot --open --port 8081 --host 127.0.0.1"
    

    注意端口号。

    执行命令npm run dev注意:是dev,不是build。

    4. Vue-cli

    使用webpack打包vue项目时需要我们手动安装插件、配置等,很麻烦。Vue提供了一个脚手架,Vue-cli,能够快速搭建一个web项目模板。

    4.1 安装

    执行命令npm install -g vue-cli

    初始化webpackvue init webpack,接下来这样选择

    4.2 文件结构分析

    • src/main.js

    项目的入口文件

    • src/App.vue

    文件内容如下

    <template>
      <div id="app">
        <img src="./assets/logo.png">
        <router-view/>
      </div>
    </template>
    
    <script>
    export default {
      name: 'App'
    }
    </script>
    
    <style>
    #app {
      font-family: 'Avenir', Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    </style>
    

    *.vue文件叫做单文件组件,每一个.vue文件都是一个独立的vue组件。

    里面包含三部分内容

    • template:模板,支持html语法高亮和提示

    • script:js脚本,这里编写的就是vue的组件对象,看到上面的data(){}了吧

    • style:样式,支持CSS语法高亮和提示

    每个组件都有自己独立的html、JS、CSS,互不干扰,真正做到可独立复用。

    • package.json
    {
      "name": "vue-cli-test",
      "version": "1.0.0",
      "description": "",
      "author": "",
      "private": true,
      "scripts": {
        "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
        "start": "npm run dev",
        "build": "node build/build.js"
      },
      "dependencies": {
        "vue": "^2.5.2",
        "vue-router": "^3.0.1"
      },
      "devDependencies": {
        "autoprefixer": "^7.1.2",
        "babel-core": "^6.22.1",
        "babel-helper-vue-jsx-merge-props": "^2.0.3",
        "babel-loader": "^7.1.1",
        "babel-plugin-syntax-jsx": "^6.18.0",
        "babel-plugin-transform-runtime": "^6.22.0",
        "babel-plugin-transform-vue-jsx": "^3.5.0",
        "babel-preset-env": "^1.3.2",
        "babel-preset-stage-2": "^6.22.0",
        "chalk": "^2.0.1",
        "copy-webpack-plugin": "^4.0.1",
        "css-loader": "^0.28.0",
        "extract-text-webpack-plugin": "^3.0.0",
        "file-loader": "^1.1.4",
        "friendly-errors-webpack-plugin": "^1.6.1",
        "html-webpack-plugin": "^2.30.1",
        "node-notifier": "^5.1.2",
        "optimize-css-assets-webpack-plugin": "^3.2.0",
        "ora": "^1.2.0",
        "portfinder": "^1.0.13",
        "postcss-import": "^11.0.0",
        "postcss-loader": "^2.0.8",
        "postcss-url": "^7.2.1",
        "rimraf": "^2.6.0",
        "semver": "^5.3.0",
        "shelljs": "^0.7.6",
        "uglifyjs-webpack-plugin": "^1.1.1",
        "url-loader": "^0.5.8",
        "vue-loader": "^13.3.0",
        "vue-style-loader": "^3.0.1",
        "vue-template-compiler": "^2.5.2",
        "webpack": "^3.6.0",
        "webpack-bundle-analyzer": "^2.9.0",
        "webpack-dev-server": "^2.9.1",
        "webpack-merge": "^4.1.0"
      },
      "engines": {
        "node": ">= 6.0.0",
        "npm": ">= 3.0.0"
      },
      "browserslist": [
        "> 1%",
        "last 2 versions",
        "not ie <= 8"
      ]
    }
    
    • 可以看到这引入了非常多的依赖,绝大多数都是开发期依赖,比如大量的加载器。
    • 运行时依赖只有vue和vue-router
    • 脚本有三个:
      • dev:使用了webpack-dev-server命令,开发时热部署使用
      • start:使用了npm run dev命令,与上面的dev效果完全一样
      • build:等同于webpack的打包功能,会打包到dist目录下。

    执行npm run dev或者 npm start 都可以启动项目。

  • 相关阅读:
    respons——文件下载
    李珊珊(为奥运冠军名字作诗)
    林跃/火亮(为奥运冠军名字作诗)
    张湘祥(为奥运冠军名字作诗)
    何可欣(为奥运冠军名字作诗)
    李小鹏(为奥运冠军名字作诗)
    王鑫(为奥运冠军名字作诗)
    杨伊琳(为奥运冠军名字作诗)
    江钰源(为奥运冠军名字作诗)
    黄旭(为奥运冠军名字作诗)
  • 原文地址:https://www.cnblogs.com/qianbixin/p/10990274.html
Copyright © 2020-2023  润新知