(精华)2020年7月12日 vue 手搭脚手架vue-cli

Vue.js

一、 单文件组件

1. .vue文件

.vue文件,称为单文件组件,是Vue.js自定义的一种文件格式,一个.vue文件就是一个单独的组件,在文件内封装了组件相关的代码:html、css、js

.vue文件由三部分组成:<template>、<style>、<script>
    <template>
        html
    </template>

    <style>
        css
    </style>

    <script>
        js
    </script>

2. vue-loader

浏览器本身并不认为.vue文件,所以必须对.vue文件进行加载解析,此时需要vue-loader
类似的loader还有许多,如:html-loader、css-loader、style-loader、babel-loader等
需要注意的是vue-loader是基于webpack的     

3. webpack

webpack是一个前端资源模板化加载器和打包工具,它能够把各种资源都作为模块来使用和处理
实际上,webpack是通过不同的loader将这些资源加载后打包,然后输出打包后文件 
简单来说,webpack就是一个模块加载器,所有资源都可以作为模块来加载,最后打包输出

官网

webpack有一个核心配置文件:webpack.config.js,必须放在项目根目录下

4. 示例,步骤:

4.1 创建项目,目录结构 如下:

webpack-demo
|-index.html
|- src
---- |-main.js 入口文件
------|-App.vue vue文件
|-package.json 工程文件
|-webpack.config.js webpack配置文件
|-.babelrc Babel配置文件

mkdir webpack-demo
touch index.html webpack.config.js .babelrc
mkdir src
cd src
touch main.js App.vue

4.2 编写App.vue

   <template>
   <div id="app">
       <h1>{{msg}}</h1>
   </div>
   </template>

   <script>
   export default {
       name: 'app',
       data () {
           return {
           msg: 'Welcome to ruanmou'
           }
       }
   }
   </script>

4.3 安装相关模板

npm install vue -S

npm install webpack -D
npm install webpack-cli -D
cnpm install webpack-dev-server -D

npm install vue -D
npm install vue-loader -D
npm install css-loader -D
npm install vue-style-loader -D
npm install file-loader -D
npm install url-loader -D
npm install html-webpack-plugin -D

npm install babel-loader -D
npm install @babel/core -D
npm install @babel/preset-env -D  //根据配置的运行环境自动启用需要的babel插件
npm install vue-template-compiler -D //预编译模板

合并:npm install -D webpack webpack-cli webpack-dev-server vue vue-loader css-loader vue-style-loader file-loader url-loader babel-loader @babel/core @babel/preset-env vue-template-compiler

4.4 编写main.js

    /**
     * 使用ES6语法引入模板
     */
    import Vue from 'vue'
    import App from './App.vue'

    new Vue({
        el:'#app',
        render:function(h){ //使用render函数渲染组件
            return h(App);
        }
    });


-------------------------------------------------

   /**
     * 使用ES6语法引入模板
     */
    import Vue from 'vue'
    import App from './App.vue'
    import VueRouter from './router/index.js';

    // 第一种写法: index.html里的dom 为app作为模板
    // new Vue({
    //     el:'app',
    //     data:{
    //         hello:'hello',
    //         msg: 'Welcome to ruanmou'
    //     }
    // })

    //第二种写法:template 模式, 需要compiler去编译成render函数进行渲染页面,性能不是最优
    // new Vue({
    //     el:'app',
    //     data:{
    //         hello:'hello',
    //         msg: 'Welcome to ruanmou'
    //     },

    //     // template:`<div id="app1">
    //     //             <h1>{{msg}}</h1>
    //     //         </div>`,

    //     // 改成引用组件就是下面的模式
    //     components:{
    //         App //App:App 
    //     }, //注册全局组件
    //     template:'<App/>'
    // });
    
    //第三种写法:render模式,性能最优
     new Vue({
        el:'#app',
        router:VueRouter,
        data:{
            hello:'hello',
            msg: 'Welcome to ruanmou'
        },
        //创建虚拟Dom,不用组件
        // render(createElement){
        //     return createElement('div',{
        //         id: "app1",
        //         style:{
        //             color:'red'
        //         }
        //         },[
        //             createElement('h1',this.msg),
        //             createElement('span','world')
        //         ])
        // },
        //使用组件, 利用render函数渲染
        render:function(h){
                return h(App);
         },
        //  render:h => h(App)
        mounted(){
            console.log(this);
        }
    });

4.5 编写webpack.config.js

    //入口文件
    var path = require('path'); 
    var SRC_PATH = path.resolve(__dirname,'./src');
    var DIST_PATH = path.resolve(__dirname,'./dist');
    const VueLoaderPlugin = require('vue-loader/lib/plugin');
    
    module.exports={
        //配置入口文件
        entry:SRC_PATH +'/main.js',
        //配置入口文件输出位置
        output:{
            path:DIST_PATH, //项目根路径
            filename:'[name].js'
        },
        resolve: {
            //别名
            alias: {
            'vue$': 'vue/dist/vue.esm.js'
            },
            extensions: ['*', '.js', '.vue', '.json']
        },
        //配置模块加载器
        module:{
            rules:[
                {
                    test: /\.css$/,
                    use: [
                    'vue-style-loader',
                    'css-loader'
                    ]
                }, 
                {
                    test:/\.vue$/, //所有以.vue结尾的文件都由vue-loader加载
                    use:'vue-loader'
                },
                {
                    test:/\.js$/, //所有以.js结尾的文件都由babel-loader加载,除了node_modules以外
                    use:'babel-loader',
                    exclude:/node_modules/
                }
            ]
        },
        // 开发服务器 
        devServer: { 
            hot: true, // 热更新,无需手动刷新 
            contentBase: path.resolve(__dirname, './dist/'),  //热启动文件所指向的文件路径
            host: '0.0.0.0', // host地址 
            port: 8082, // 服务器端口 
            historyApiFallback: true, // 该选项的作用所用404都连接到index.html 
            publicPath:'/', //默认设置
            proxy: { 
            "/api": "http://localhost:3000" 
            // 代理到后端的服务地址,会拦截所有以api开头的请求地址
             } ,
            useLocalIp: true ,
            // open:true,
            // noInfo:true
        },
        // 插件
        plugins: [
            new VueLoaderPlugin()
        ]

    }

4.6 编写.babelrc

{
    "presets":[
          [ 
            "@babel/preset-env", { 
                "useBuiltIns": "usage", //按需注入
                "corejs": "2", // 声明corejs版本
                "targets": { 
                    "browsers": [ "> 1%", "last 5 versions", "ie >= 8" ] 
                } 
            }
         ]
    ]
}

4.7 编写package.json

    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "dev": "webpack-dev-server --config webpack.config.js",
        "build": "webpack --config webpack.config.js"
    }

4.8 运行测试

npm run dev    
npm run build

4.9 理顺8个版本vue的区别(小结)

vue.js : vue.js则是直接用在<script>标签中的,完整版本,直接就可以通过script引用。
vue.common.js :预编译调试时,CommonJS规范的格式,可以使用require("")引用的NODEJS格式。
vue.esm.js:预编译调试时, EcmaScript Module(ES MODULE),支持import from 最新标准的。

//----------------------------------------------------------------------
Runtime-only
vue.runtime.js :生产的运行时,需要预编译,比完整版小30%左右,UMD
vue.runtime.common.js:生产运行时,commonJS标准。 CommonJS
vue.runtime.esm.js:生产运行时,esm标准。  ES Module 


https://www.jb51.net/article/147538.htm

4.10 配置路由

安装

npm install vue-router -D

配置

新建router/index.js

import Vue from "vue";
import VueRouter from "vue-router";

Vue.use(VueRouter);

import home from '../pages/home.vue';
import news from '../pages/news.vue';

var allRoutes = [{
    path:'/home',
    name:'home',
    component:home
},{
    path:'/news',
    name:'news',
    component:news
}]
export default new VueRouter({
    routes:allRoutes,
    mode:'hash',
    base:'/',
    //   vue-router 认为只有路由真正匹配时,才会加上 exact-active-link 这个 class,
    //   如果只有一部分重合,就会加上 active-menu。
    // fallback
    // 不是所有浏览器都支持前端路由的方式,如果不支持,设置 fallback: true,
    // vue 会自动 fallback 到 hash 模式。
    fallback: true,
    linkActiveClass: "active-menu",
    linkExactActiveClass: "exact-active-menu",
})

// 在main.js中把router 实例注入到 vue 根实例中,就可以使用路由了

在main.js里注入

import VueRouter from './router/index.js';
new Vue({
        el:'#app',
        router:VueRouter
        ....
})

在App.vue 里添加链接 ,以及路由导航链接

<template>
  <div id="app">
    <h1>{{msg}}</h1>
    <div >
      <!-- <router-link to="/home" tag='li'>主页</router-link>
		   <router-link to="/news" tag='li'>新闻</router-link> 
           -->
      <ul @click="gotoPage($event)">
        <li tag='home'>主页</li>
        <li tag='news'>新闻</li>
      </ul>   
    </div>
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'app',
  data () {
    return {
      msg: 'Welcome to ruanmou'
    }
  },
  methods:{
    gotoPage(ev){
      var target = ev.target,
          tag = target.getAttribute('tag');
      switch(tag){
        case 'home':
          this.$router.push({
            path:'/home',
            query:{
              name:'laney'
            }
          })
          break;
        case 'news':
        this.$router.push({
          path:'/news',
          query:{
            age:'10'
          }
        })
        break;
      }
    }
  }
}
</script>
©️2020 CSDN 皮肤主题: 猿与汪的秘密 设计师:上身试试 返回首页