头部背景图片
小畅童鞋的学习笔记 |
小畅童鞋的学习笔记 |

Vue.js学习笔记Day5-5.08

Vue.js学习笔记Day5-5.08

今日主要学习内容:

  • 复习父子组件传值问题;
  • watch、computed和methods之间的对比;
  • nrm的安装使用;
  • Webpack的概念;
  • 使用vue实例的render方法渲染组件;
  • 在普通页面中使用render函数渲染组件;
  • export default 和 export 使用方式;
  • 在vue组件页面中,集成vue-router路由模块;
  • 组件中css作用域问题(scoped属性)

开始Vue框架的学习吧~

一、复习父子组件传值问题

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
    <div id="app">
        <com1 v-bind:parentmsg="msg" @func="getMsgFromSon"></com1>
    </div>
    <template id="tmp1">
        <div>
            <h1>这是子元素---{{parentmsg}}</h1>
            <input type="button" value="向父组件传递消息" @click="sendMsg">
        </div>
    </template>
<script>
    var com1 = {
        template: '#tmp1',
        data(){
            return {
                msg:'孝顺的孩子'
            }
        },
        props: ['parentmsg'],
        methods:{
            sendMsg(){
                this.$emit('func',this.msg)
            }
        }
    }
    //创建Vue实例,得到ViewModel
    var vm = new Vue({
        el: '#app',
        data:{
            msg: '父组件中的数据',
            msgFromSon: ''
        },
        methods:{
            getMsgFromSon(data){
                this.msgFromSon = data
                console.log(this.msgFromSon)
            }
        },
        components:{
            com1
        }
    })
</script>
</body>
</html>

二、名称案例

2.1使用keyup事件实现

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
    <div id="app">
    <!-- 分析 -->
    <!-- 1.我们要监听到文本框数据的改变,这样才知道什么时候去拼接出一个fullname -->
    <!-- 2.如何监听到文本框的数据改变 -->
        <input type="text" v-model="firstname" @keyup="getFullName"> +
        <input type="text" v-model="lastname" @keyup="getFullName"> =
        <input type="text" v-model="fullname">
    </div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            firstname:'',
            lastname:'',
            fullname:''
        },
        methods: {
            getFullName(){
                this.fullname = this.firstname + '-' + this.lastname
            }
        }
    })
</script>
</body>
</html>

2.2、watch属性的使用

考虑一个问题:想要实现 名 和 姓 两个文本框的内容改变,则全名的文本框中的值也跟着改变;(用以前的知识如何实现???)

  1. 监听data中属性的改变:
<div id="app">
    <input type="text" v-model="firstname"> +
    <input type="text" v-model="lastname"> =
    <input type="text" v-model="fullname">
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            firstname:'',
            lastname:'',
            fullname:''
        },
        methods: {},
        watch: { // 使用这个属性,可以监视data中指定数据的变化,然后触发这个watch中对应的function处理函数
            'firstname':function(newVal,oldVal){
                this.fullname = newVal + '-' + this.lastname
            },
            'lastname':function(newVal,oldVal){
                this.fullname = this.firstname + '-' + newVal
            }
        },
    });
</script>
  1. 监听路由对象的改变:
<div id="app">
    <router-link to="/login">登陆</router-link>
    <router-link to="/register">注册</router-link>
    <router-view></router-view>
</div>
<script>
    // 2.创建子组件
    var login = {
        template:'<h3>登陆子组件</h3>'
    }
    var register = {
        template:'<h3>注册子组件</h3>'
    }
    // 3.创建一个路由对象
    var router = new VueRouter({
        routes:[ //路由规则数组
        {path:'/',redirect:'/login'},
        {path:'/login',component: login},
        {path:'/register',component: register},
        ],
        linkActiveClass:'myactive' // 激活相关的类
    })
    var vm = new Vue({
        el:'#app',
        data:{},
        methods:{},
        // router: router
        router,
        watch:{
            '$route.path':function(newVal,oldVal){
                console.log(newVal + '---' + oldVal)
                if (newVal === '/login') {
                    console.log('欢迎进入登陆界面');
                } else if (newVal === '/register') {
                    console.log('欢迎进入注册界面');
                }
            }
        }
    })
</script>

2.3、computed计算属性的使用

  1. 默认只有getter的计算属性:
<div id="app">
    <input type="text" v-model="firstname"> +
    <input type="text" v-model="lastname"> =
    <input type="text" v-model="fullname">
    <p>{{ fullname }}</p>
    <p>{{ fullname }}</p>
    <p>{{ fullname }}</p>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            firstname:'',
            lastname:''
        },
        methods: {},
        computed: { 
            'fullname':function(){
                console.log('ok');
                return this.firstname + '-' + this.lastname
            }
        }
    });
</script>
  • 注意:在computed中可以定义一些计算属性,计算属性的本质就是一个方法,只不过我们在使用这些计算属性的时候,是把他们的名称直接当作属性来使用的,并不会把计算属性当作方法来调用
    • 计算属性再引用的时候,不要加()去调用,直接把它当普通属性去调用
    • 只要计算属性function内部所用到的任何data中的数据发生变化,就会重新计算这个计算属性的值
    • 计算属性的求职结果,会被缓存起来,方便下次直接使用,如果计算属性方法中,所有来的任何数据,都没有发生过变化,则不会对计算属性求值,如上例,虽然引用了三次fullname,但只输出一次‘ok’
  1. 定义有getter和setter的计算属性:
<div id="app">
  <input type="text" v-model="firstName">
  <input type="text" v-model="lastName">
  <!-- 点击按钮重新为 计算属性 fullName 赋值 -->
  <input type="button" value="修改fullName" @click="changeName">
  <span>{{fullName}}</span>
</div>
<script>
  // 创建 Vue 实例,得到 ViewModel
  var vm = new Vue({
    el: '#app',
    data: {
      firstName: 'jack',
      lastName: 'chen'
    },
    methods: {
      changeName() {
        this.fullName = 'TOM - chen2';
      }
    },
    computed: {
      fullName: {
        get: function () {
          return this.firstName + ' - ' + this.lastName;
        },
        set: function (newVal) {
          var parts = newVal.split(' - ');
          this.firstName = parts[0];
          this.lastName = parts[1];
        }
      }
    }
  });
</script>

2.4、watch、computed和methods之间的对比

  • computed属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。主要当作属性来使用;
  • methods方法表示一个具体的操作,主要书写业务逻辑;
  • watch一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作;可以看作是computed和methods的结合体;

三、nrm的安装使用

  • 作用:提供了一些最常用的NPM包镜像地址,能够让我们快速的切换安装包时候的服务器地址;
  • 什么是镜像:原来包刚一开始是只存在于国外的NPM服务器,但是由于网络原因,经常访问不到,这时候,我们可以在国内,创建一个和官网完全一样的NPM服务器,只不过,数据都是从人家那里拿过来的,除此之外,使用方式完全一样;
  1. 运行npm i nrm -g全局安装nrm包;
  2. 使用nrm ls查看当前所有可用的镜像源地址以及当前所使用的镜像源地址;
  3. 使用nrm use npm或nrm use taobao切换不同的镜像源地址;
  4. 注意:nrm只是提供了几个常用的下载包的URL,并能够让我们在这几个地址间很方便地进行切换,但是我们每次装包的时候,使用的工具都是npm

四、Webpack的概念

4.1 Webpack引入原因

1. 在网页中会引用哪些常见的静态资源?

  • JS
    .js .jsx .coffee .ts(TypeScript 类 C# 语言)
  • CSS
    .css .less .sass .scss
  • Images
    .jpg .png .gif .bmp .svg
  • 字体文件(Fonts)
    .svg .ttf .eot .woff .woff2
  • 模板文件
    .ejs .jade .vue【这是在webpack中定义组件的方式,推荐这么用】

2. 网页中引入的静态资源多了以后有什么问题???

  • 网页加载速度慢, 因为 我们要发起很多的二次请求;
  • 要处理错综复杂的依赖关系(比如bootstrap依赖于jQuery)

3. 如何解决上述两个问题
合并、压缩、精灵图、图片的Base64编码
可以使用之前学过的requireJS、也可以使用webpack可以解决各个包之间的复杂依赖关系;

4.2 什么是webpack?

webpack 是前端的一个项目构建工具,它是基于 Node.js 开发出来的一个前端工具;
如何完美实现上述的2种解决方案

  • 使用Gulp, 是基于 task 任务的;
  • 使用Webpack, 是基于整个项目进行构建的;
  • 借助于webpack这个前端自动化构建工具,可以完美实现资源的合并、打包、压缩、混淆等诸多功能。
  • 根据官网的图片介绍webpack打包的过程
    webpack官网
    Image1.png

webpack安装的两种方式

  • 运行cnpm i webpack -g全局安装webpack,这样就能在全局使用webpack的命令
  • 在项目根目录中运行cnpm i webpack --save-dev安装到项目依赖中

4.3 初步使用webpack打包构建列表隔行变色案例

  1. 创建项目基本的目录结构
  2. 运行cnpm init初始化项目,使用npm管理项目中的依赖包
  3. 使用cnpm i jquery --save安装jquery类库
  4. 创建main.js并书写各行变色的代码逻辑:
// 1.导入Jquery
import $ from 'jquery'
const $ = require('jquery')
$(function(){
    $('li:odd').css('backgroundColor','lightblue')
    $('li:even').css('backgroundColor',function(){
        return'#' + 'FF6900'
    })
})

直接在页面上引用main.js会报错,因为浏览器不认识import这种高级的JS语法,需要使用webpack进行处理,webpack默认会把这种高级的语法转换为低级的浏览器能识别的语法;
运行webpack 入口文件路径 输出文件路径对main.js进行处理:

webpack .\src\main.js .\dist\bundle.js

问题处理:
Image2.png

  1. 警告
警告:WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/

原因是:没有设置webpack的模式,是生产还是开发(production or development)

  • 执行命令:webpack –mode=production 或者 webpack –mode=development
  • 也可以在package.json中进行修改
"scripts": {
"dev": "webpack –mode development",
"build": "webpack –mode production"
}
  1. 错误
错误:ERROR in multi ./src/main.js ./dist/bundle.js
Module not found: Error: Can't resolve '.\dist\bundle.js' in 'D:\lichang\Vue_CLI\Vue\Day5\webpack-study'
@ multi ./src/main.js ./dist/bundle.js main[1]

原因:目前使用的的webpack版本过高,原来的命令已经不适用了,换成指令

webpack .\src\main.js -o .\dist\bundle.js --mode development

Image3.png

总结:经过演示,webpack可以做哪些事情

  • webpack能够处理js间互相依赖关系
  • webpack能够处理js兼容问题,把高级的浏览器不识别的语法转为低级的浏览器能识别的语法
  • 刚才运行的命令格式:webpack 要打包的文件路径 打包好要输出的文件路径

4.4 使用webpack的配置文件简化打包时候的命令

  1. 在项目根目录中创建webpack.config.js
  2. 由于运行webpack命令的时候,webpack需要指定入口文件和输出文件的路径,所以,我们需要在webpack.config.js中配置这两个路径:
  3. 经过配置文件设置、直接使用命令webpack即可进行打包
// 导入处理路径的模块
const path = require('path')
// 导出一个配置对象,将来webpack在启动的时候,会默认来查找webpack.config.js,并读取这个文件中导出的配置对象,来进行打包处理
module.exports = {
    entry: path.join(__dirname, './src/main.js'), // 项目入口文件
    output: { // 配置输出选项
        path: path.join(__dirname, './dist'), // 配置输出的路径
        filename: 'bundle.js' // 配置输出的文件名
    }
}

总结:当我们在控制台执行webpack命令时,webpack做了以下几步:

  • 首先,我们并没有通过命令的形式,给它指定入口和出口
  • webpack就回去项目的根目录中,查找一个叫做webpack.config.js的配置文件
  • 当找到配置文件后,webpack会去执行解析这个配置文件,当解析完这个配置文件后,就得到了配置文件中导出的配置对象
  • 当webpack拿到配置对象后,就拿到了配置对象中指定的入口和出口,然后进行打包构建

4.5 使用webpack-dev-serve实时打包构建

  1. 由于每次重新修改代码之后,都需要手动运行webpack打包的命令,比较麻烦,所以使用webpack-dev-server来实现代码实时打包编译,当修改代码之后,会自动进行打包构建。
  2. 运行cnpm i webpack-dev-server -D安装到开发依赖
  3. 安装完成之后,在命令行直接运行webpack-dev-server来进行打包,发现报错
    Image4.png
    此时需要借助于package.json文件中的指令,来进行运行webpack-dev-server命令,在package.json文件的scripts节点下新增"dev": "webpack-dev-server"指令
    Image5.png

  4. 接下来运行npm run dev即可进行实时打包,但是dist目录下并没有生成bundle.js文件,这是因为webpack-dev-server将打包好的文件放在了内存中
    Image6.png

4.6 webpack-dev-serve常用命令参数

方式1:
  • 修改package.json的script节点如下,其中
  • –open表示自动打开浏览器
  • –port 4321表示打开的端口号为4321
  • –hot表示启用浏览器热更新
  • –contentBase src指定启动的根目录
"dev": "webpack-dev-server --contentBase src --hot --port 4321 --open"

注意:热更新用来进行减少不必要的代码更新,每次重新编译只会更新修改过的文件(相当于打补丁)热更新在JS中表现的不明显,可以从一会儿要讲到的CSS身上进行介绍说明
Image8.png

方式2:
  1. 修改webpack.config.js文件,新增devServer节点如下:
devServer:{  //相对来说方法2麻烦一些,了解即可
    hot:true,   //启用热更新第一步
    open:true,
    port:4321,
    contentBase:'src'
}
  1. 在头部引入webpack模块:
var webpack = require('webpack');   // 启用热更新第二步
  1. 在plugins节点下新增:
plugins:[   //配置插件的节点
    new webpack.HotModuleReplacementPlugin() //启用热更新第三步
]

4.7使用html-webpack-plugin插件配置启动页面

由于使用–contentBase指令的过程比较繁琐,需要指定启动的目录,同时还需要修改index.html中script标签的src属性,所以推荐大家使用html-webpack-plugin插件配置启动页面.

  1. 运行cnpm i html-webpack-plugin -D安装到开发依赖
  2. 修改webpack.config.js配置文件如下:
// 导入处理路径的模块
var path = require('path');
// 导入自动生成HTMl文件的插件
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    entry: path.resolve(__dirname, 'src/js/main.js'), // 项目入口文件
    output: { // 配置输出选项
        path: path.resolve(__dirname, 'dist'), // 配置输出的路径
        filename: 'bundle.js' // 配置输出的文件名
    },
    plugins:[ // 添加plugins节点配置插件
        new htmlWebpackPlugin({
            template:path.resolve(__dirname, 'src/index.html'),//模板路径
            filename:'index.html'//自动生成的HTML文件的名称
        })
    ]
}
  1. 修改package.json中script节点中的dev指令如下:
"dev": "webpack-dev-server"
html-webpack-plugin插件两个作用:
  • 自动在内存中根据指定页面生成一个内存的页面
  • 自动把打包好的bundle.js文件追加到页面中去,我们不再需要手动处理bundle.js的引用路径了,所以可以将index.html中script标签注释掉!

4.8使用webpack处理第三方类型

webpack默认只能处理js类型的文件,无法处理其他的非js类型的文件,如果需要非JS类型的文件,我们需要手动安装一些合适的第三方loader加载器

webpack处理第三方文件类型的过程:
  1. 发现这个要处理的文件不是js文件,然后就去配置文件中,查找有没有对应的第三方loader规则
  2. 如果能找到对应的规则,就会调用相应的loader处理这种文件类型
  3. 在调用loader的时候,是从后往前调用的
  4. 当最后一个loader调用完毕,会把处理结果,交给webpack进行打包合并,最终输出到bundle.js中去
4.8.1使用webpack打包css文件
  1. 新建index.css文件
  2. 在main.js引入index.css
import './css/index.css'
  1. 如果要打包处理css文件,需要安装cnpm i style-loader css-loader -D
  2. 打开webpack.config.js这个配置文件,在里面新增一个配置节点叫module,它是一个对象,在这个module对象上有一个rules属性,是个数组,这个数组中存放了所有第三方文件的匹配和处理规则
module: { // 用来配置第三方loader模块的
    rules: [ // 文件的匹配规则
    { test: /\.css$/, use: ['style-loader', 'css-loader'] }//处理css文件的规则
    ]
}

注意:use表示使用哪些模块来处理test所匹配到的文件;use中相关loader模块的调用顺序是从后向前调用的

4.8.2使用webpack打包less文件
  1. 新建index.less文件
  2. 在main.js引入index.less
import './css/index.less'
  1. 运行cnpm i less-loader less -D
  2. 修改webpack.config.js这个配置文件的module节点:
{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
4.8.3使用webpack打包sass文件
  1. 新建index.scss文件
  2. 在main.js引入index.scss
import './css/index.scss'
  1. 运行cnpm i sass-loader node-sass -D
  2. 在webpack.config.js中添加处理sass文件的loader模块:
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }
4.8.4使用webpack处理css中的路径
  1. 运行cnpm i url-loader file-loader -D
  2. 在webpack.config.js中添加处理url路径的loader模块:
{ test: /\.(png|jpg|gif|bmp|jpeg)$/, use: 'url-loader' }
  • 可以通过limit指定进行base64编码的图片大小;只有小于指定字节(byte)的图片才会进行base64编码;通过[hash:8]来设置留八位hash编码,[name]用来保留原来的照片名,[ext]用来保留原来的后缀名
{ test: /\.(png|jpg|gif|bmp|jpeg)$/, use: 'url-loader?limit=43960&name=[hash:8]-[name].[ext]' },
4.8.5使用webpack处理字体文件
  1. 在main.js引入bootstrap.css
import 'bootstrap/dist/css/bootstrap.css'
  1. 运行安装cnpm i bootstrap -S
  2. 在webpack.config.js中添加处理字体文件的loader模块:
{ test: /\.(svg|ttf|eot|woff|woff2)$/, use: 'url-loader' } 

注意:遇到安装完bootstrap无法显示字体的现象,原因是版本问题,默认安装最新版本4.3.1,手动改为3.4.1版本即可 cnpm i bootstrap@3.4.1-D

4.8.6使用babel处理高级JS语法
  • 在 webpack 中,默认只能处理 一部分 ES6 的新语法,一些更高级的ES6语法或者 ES7 语法,webpack 是处理不了的;这时候,就需要 借助于第三方的 loader,来帮助webpack 处理这些高级的语法,当第三方loader 把 高级语法转为 低级的语法之后,会把结果交给 webpack 去打包到 bundle.js 中,通过 Babel ,可以帮我们将 高级的语法转换为低级的语法
  • 运行cnpm i babel-core babel-loader babel-plugin-transform-runtime -D安装babel的相关loader包
  • 运行cnpm i babel-preset-env babel-preset-stage-0 -D安装babel转换的语法
  • 在webpack.config.js中添加相关loader模块,其中需要注意的是,一定要把node_modules文件夹添加到排除项:
{ test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ }
  • 注意: 在配置 babel 的 loader规则的时候,必须 把 node_modules 目录,通过 exclude 选项排除掉:原因有俩:
  1. 如果 不排除 node_modules, 则Babel 会把 node_modules 中所有的 第三方 JS 文件,都打包编译,这样,会非常消耗CPU,同时,打包速度非常慢;
  2. 哪怕,最终,Babel 把 所有 node_modules 中的JS转换完毕了,但是,项目也无法正常运行!
  • 在项目根目录中添加.babelrc文件,并修改这个配置文件如下:
{
    "presets":["env", "stage-0"],
    "plugins":["transform-runtime"]
}
  • 了解: 目前,我们安装的 babel-preset-env, 是比较新的ES语法, 之前, 我们安装的是 babel-preset-es2015, 现在,出了一个更新的 语法插件,叫做 babel-preset-env ,它包含了 所有的 和 es***相关的语法

问题描述:

Error: Cannot find module '@babel/core'  babel-loader@8 requires Babel 7.x (the package '@babel/core'). If you'd like to use Babel 6.x ('babel-core'), you should install 'babel-loader@7'.

最初以为是babel-core没有安装上。重装了好几遍babel-core还是不行。对照以前的项目,发现babel-loader的版本不一样,之前的是@7.1.5版本,而现在是@8.0.0版本。

cnpm install babel-loader@7.1.5 -D

五、使用vue实例的render方法渲染组件

  1. 在页面中渲染基本的组件
<body>
    <div id="app">
        <p>33333</p>
        <login></login>
    </div>
    <script>
        var login = {
            template: '<h1>这是登录组件</h1>'
        }
        // 创建 Vue 实例,得到 ViewModel
        var vm = new Vue({
            el: '#app',
            data: {},
            methods: {},
            components: {
                login
            }
        });
    </script>
</body>
  1. 在页面中使用render函数渲染组件
<body>
    <div id="app">
        <p>444444</p>
    </div>
    <script>
        var login = {
            template: '<h1>这是登录组件</h1>'
        }
        // 创建 Vue 实例,得到 ViewModel
        var vm = new Vue({
            el: '#app',
            data: {},
            methods: {},
            render: function (createElements) { // createElements 是一个 方法,调用它,能够把 指定的 组件模板,渲染为 html 结构
                return createElements(login)
                // 注意:这里 return 的结果,会 替换页面中 el 指定的那个 容器
            }
        });
    </script>
</body>

两者区别:使用render函数渲染的组件直接替换整个div模块,所以不会再显示p标签444444,而在页面中直接导入组件则不会替换掉div整个模块的内容,两者区别相当于v-text和差值表达式的区别

六、在普通页面中使用render函数渲染组件

在webpack中配置.vue组件页面的解析

  • 运行cnpm i vue -S将vue安装为运行依赖;
  • 注意: 在 webpack 中, 使用 import Vue from 'vue'导入的 Vue 构造函数,功能不完整,只提供了 runtime-only 的方式,并没有提供 像网页中那样的使用方式;
  • 在使用webpack构建的Vue项目中使用模板对象解决方法:
  1. 在main.js中引入import Vue from 'vue',查看node_modules-vue-package.json文件,可以看到我们目前引入的是vue.runtime.common.js,把这个路径换成指向vue.js文件(不提倡)

Image9.png

  1. 直接在main.js引入import Vue from ‘../node_modules/vue/dist/vue.js’(不提倡)
  2. 在main.js中引入import Vue from ‘vue’,在webpack.config.js中添加resolve属性

Image10.png

  • 默认,webpack 无法打包 .vue 文件,需要安装 相关的loader,运行cnpm i vue-loader vue-template-compiler -D将解析转换vue的包安装为开发依赖;
  • 运行cnpm i style-loader css-loader -D将解析转换CSS的包安装为开发依赖,因为.vue文件中会写CSS样式;
  • 在webpack.config.js配置文件中,添加如下module规则:
module: {
    rules: [
        { test: /\.css$/, use: ['style-loader', 'css-loader'] },
        { test: /\.vue$/, use: 'vue-loader' }
    ]
}
  • 创建App.js组件页面:
<template>
<!-- 注意:在 .vue 的组件中,template 中必须有且只有唯一的根元素进行包裹,一般都用 div 当作唯一的根元素 -->
    <div>
        <h1>这是APP组件 - {{msg}}</h1>
        <h3>我是h3</h3>
    </div>
</template>
<script>
// 注意:在 .vue 的组件中,通过 script 标签来定义组件的行为,需要使用 ES6 中提供的 export default 方式,导出一个vue实例对象
export default {
    data() {
        return {
            msg: 'OK'
        }
    }
}
</script>
<style scoped>
h1 {
    color: red;
}
</style>
  • 创建main.js入口文件:
// 导入 Vue 组件
import Vue from 'vue'
// 导入 App组件
import App from './components/App.vue'
// 创建一个 Vue 实例,使用 render 函数,渲染指定的组件
var vm = new Vue({
    el: '#app',
    render: c => c(App)
});

注意:render: c => c(App)是下式的缩写

render: function (createElements) {
    return createElements(App)
}
复习 在普通网页中如何使用vue:
1. 使用 script 标签 ,引入 vue 的包
2. 在 index 页面中,创建 一个 id 为 app div 容器
3. 通过 new Vue 得到一个 vm 的实例
回顾 包的查找规则:
1. 找 项目根目录中有没有 node_modules 的文件夹
2. 在 node_modules 中 根据包名,找对应的 vue 文件夹
3. 在 vue 文件夹中,找 一个叫做 package.json 的包配置文件
4. 在 package.json 文件中,查找 一个 main 属性【main属性指定了这个包在被加载时候,的入口文件】

七、export default 和 export 使用方式

  • ES6中导入模块,使用 import 模块名称 from ‘模块标识符’ import ‘表示路径’,使用 export default 和 export 向外暴露成员;在Node中 使用 var 名称 = require(‘模块标识符’),module.exports 和 exports 来暴露成员,两套方法不可混用
  • export default 和 export的区别
var info = {
    name: 'zs',
    age: 20
}
export default info
/* export default {
    address: '北京'
} */
// 注意: export default 向外暴露的成员,可以使用任意的变量来接收
// 注意: 在一个模块中,export default 只允许向外暴露1次
// 注意: 在一个模块中,可以同时使用 export default 和 export 向外暴露成员
  • export的引用方式:
export var title = '小星星'
export var content = '哈哈哈'
// 注意: 使用 export 向外暴露的成员,只能使用 { } 的形式来接收,这种形式,叫做 【按需导出】
// 注意: export 可以向外暴露多个成员, 同时,如果某些成员,我们在 import 的时候,不需要,则可以 不在 {} 中定义
// 注意: 使用 export 导出的成员,必须严格按照 导出时候的名称,来使用 {} 按需接收;
// 注意: 使用 export 导出的成员,如果 就想 换个 名称来接收,可以使用 as 来起别名;
  • 使用 import from 和 import ‘路径’ 还有 import {a, b} from ‘模块标识’ 导入其他模块
import m222, { title as title123, content } from './test.js'
console.log(m222)
console.log(title123 + ' --- ' + content)

八、在vue组件页面中,集成vue-router路由模块

vue-router官网

cnpm install vue-router

  1. 导入路由模块:
import Vue from 'vue'
import VueRouter from 'vue-router'
  1. 安装路由模块:
Vue.use(VueRouter);
  1. 导入需要展示的组件:
import login from './components/account/login.vue'
import register from './components/account/register.vue'
  1. 创建路由对象:
var router = new VueRouter({
routes: [
{ path: '/', redirect: '/login' },
{ path: '/login', component: login },
{ path: '/register', component: register }
]
});
  1. 将路由对象,挂载到 Vue 实例上:
var vm = new Vue({
el: '#app',
// render: c => { return c(App) }
render(c) {
return c(App);
},
router // 将路由对象,挂载到 Vue 实例上
});
  1. 改造App.vue组件,在 template 中,添加router-link和router-view:
<router-link to="/login">登录</router-link>
<router-link to="/register">注册</router-link>
<router-view></router-view>

九、组件中css作用域问题(scoped属性)

  1. 普通的style标签,只支持普通的样式,如果想要启用scss或者less,需要为style元素设置lang属性
<style lang="scss" scoped>
  1. 只要是style标签,是在.vue组件中定义的,那么推荐都为style开启scoped属性,可以防止组件间样式相互干扰,样式的scoped属性是通过css的属性选择器实现的
Lililich's Blog