首页 技术 正文
技术 2022年11月15日
0 收藏 360 点赞 4,723 浏览 7476 个字

之前都是在html文件中写组件的css,组件的js,组件的模板来演示vue组件的语法,下面介绍以.vue结尾的单文件组件。vue-loader是一个Webpack的loader,可以将单文件组件转换为JavaScript模块。
一、基本组成
单文件组件中包含<template>、<script>、<style>三种代码块。
<template>默认语言是html,内容将被提取为字符串,编译结果作为Vue组件的template选项,一个.vue文件最多包含一个<template>代码块。
<script>默认语言是js,如果检测到babel-loader的配置,将自动支持es6语法,一个.vue文件最多包含一个<script>代码块。
<style>默认语言是css,默认使用style-loader提取内容,并通过<style>标签动态加入文档的<head> 中,一个.vue文件可以包含多个<style>代码块。<style>标签有scoped属性时,它的css只作用于当前组件中的元素。

二、运行时构建的demo
1、新建package.json文件

{  "name": "vuetest",  "version": "1.0.0",  "description": "",  "scripts": {    "test": "echo \"Error: no test specified\" && exit 1",    "server": "webpack-dev-server --open",    "build": "webpack-dev-server"  },  "author": "camille",  "license": "ISC",  "devDependencies": {    "css-loader": "^0.28.7",    "style-loader": "^0.19.0",    "vue": "^2.5.2",    "vue-loader": "^13.3.0",    "vue-template-compiler": "^2.5.1"  }}

2、新建webpack.config.js文件

module.exports = {  entry: './main.js',  output: {    path: __dirname,    filename: 'bundle.js'  },  devtool: "inline-source-map",  module: {    rules: [      {        test: /\.vue$/,        loader: 'vue-loader'      },      {        test: /\.css$/,        use: ['style-loader','css-loader']      }    ]  }}

3、新建index.html文件

<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <title>单文件组件运行时构建</title></head><body>  <div id="J_vapp"></div>  <script type="text/javascript" src="bundle.js"></script></body></html>

4、新建hello.vue单文件组件

<template>  <p>{{ greeting }},vue</p></template><script>  module.exports={    data:function(){      return {        greeting:"hello"      }    }  }</script><style scoped>  p{    font-size:15px;    color:red;  }</style>

5、新建main.js文件

import Vue from 'vue'import sfile from './hello.vue'var vm = new Vue({  el: '#J_vapp',  render: function(h){    return h(sfile)  }})

6、渲染结果

<p data-v-d0145a06="">hello,vue</p>

可以看出html中的J_vapp相当于桥梁,最后不会出现在dom中。
7、疑惑
我明明没有安装babel-loader,为什么上面可以用import from方式引入模块,而且没报错?vue-loader的v13.0.0版本告诉我,.vue文件将被默认为一个es模块。

四、运行时构建demo的另一种表达
众所周知,在main.js中既可以用import引入文件,也可以用require,下面就用require引入。

1、修改main.js文件

var Vue = require('vue')var sfile = require('./hello.vue')var vm = new Vue({  el: '#J_vapp',  render: function(h){    return h(sfile)  }})

紧接着出现“Vue is not a constructor”问题。

2、修改webpack.config.js文件

module.exports = {  entry: './main.js',  output: {    path: __dirname,    filename: 'bundle.js'  },  devtool: "inline-source-map",  module: {    rules: [      {        test: /\.vue$/,        loader: 'vue-loader'      },      {        test: /\.css$/,        use: ['style-loader','css-loader']      }    ]  },  resolve: {    alias: {      vue$: 'vue/dist/vue.js', //vue$表示精确匹配    }  }}

前面那个问题解决了,接着又有“Failed to mount component: template or render function not defined.”问题。

3、修改main.js文件

各种探索,终于在vue-loader变更这里找到问题根源,如果依赖了v13+的vue-loader,用require引入.vue文件时,后面加上default。

var Vue = require('vue')var sfile = require('./hello.vue').defaultvar vm = new Vue({  el: '#J_vapp',  render: function(h){    return h(sfile)  }})

五、独立构建的demo
1、新建package.json文件
同运行时构建。
2、新建webpack.config.js文件

module.exports = {  entry: './main.js',  output: {    path: __dirname,    filename: 'bundle.js'  },  devtool: "inline-source-map",  module: {    rules: [      {        test: /\.vue$/,        loader: 'vue-loader'      },      {        test: /\.css$/,        use: ['style-loader','css-loader']      }    ]  },  resolve: {    alias: {      vue$: 'vue/dist/vue.js' //vue$表示精确匹配    }  }}

注意:如果没有resolve的配置,这里会报错。You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

3、新建index.html文件

<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <title>单文件组件,独立构建,模板命名很重要</title></head><body>  <div id="J_vapp">    <temptpl></temptpl>  </div>  <script type="text/javascript" src="bundle.js"></script></body></html>

4、新建hello.vue单文件组件

<template>  <p>{{greeting}},vue</p></template><script type="text/javascript">  export default {    data:function(){      return {        greeting:"hello"      }    }  }</script><style scoped>  p{    font-size:15px;    color:red;  }</style>

5、新建main.js文件

import Vue from 'vue'import temptpl from './hello.vue'var vm = new Vue({  el: '#J_vapp',  components: { temptpl }})

6、渲染结果

<div id="J_vapp">  <p data-v-d0145a06="">hello,vue</p></div>

可以看出html中的J_vapp元素不会消失,充当载体桥梁的是temptpl,temptpl最后不会出现在dom中。

六、提取单文件组件的css
1、安装webpack插件

cnpm i -D extract-text-webpack-plugin

2、安装webpack

cnpm i -D webpack

extract-text-webpack-plugin需要webpack作为依赖,npm3不会自动安装依赖。
如果不安装webpack,你会看到报错,Cannot find module ‘webpack/lib/Chunk’。
3、配置webpack.config.js

var ExtractTextPlugin = require("extract-text-webpack-plugin");module.exports = {  entry: './main.js',  output: {    path: __dirname,    filename: 'bundle.js'  },  devtool: "inline-source-map",  module: {    rules: [      {        test: /\.vue$/,        loader: 'vue-loader',        options: {          loaders: {            css: ExtractTextPlugin.extract({              use: 'css-loader',              fallback: 'vue-style-loader' //这是vue-loader的依赖,所以如果使用npm3,则不需要显式安装。            })          }        }      }    ]  },  resolve: {    alias: {      vue$: 'vue/dist/vue.js' //vue$表示精确匹配    }  },  plugins: [    new ExtractTextPlugin("style.css")  ]}

4、新建index.html

<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <title>提取单文件组件的css</title>  <link rel="stylesheet" type="text/css" href="style.css" rel="external nofollow" ></head><body>  <div id="J_vapp">    <temptpl></temptpl>  </div>  <script type="text/javascript" src="bundle.js"></script></body></html>

5、其他文件
与独立构建的demo中的package.json文件,hello.vue,main.js文件保持一致。

七、提取自定义块
1、安装raw-loader

cnpm i -D raw-loader

2、修改hello.vue文件

<docs>## This is an Example component.</docs><template>  <p>{{greeting}},vue</p></template><script type="text/javascript">  export default {    data:function(){      return {        greeting:"hello"      }    }  }</script><style scoped>  p{    font-size:15px;    color:red;  }</style>

3、配置webpack.config.js文件

var ExtractTextPlugin2 = require("extract-text-webpack-plugin");module.exports = {  entry: './main.js',  output: {    path: __dirname,    filename: 'bundle.js'  },  devtool: "inline-source-map",  module: {    rules: [      {        test: /\.css$/,        use: ['style-loader','css-loader']      },      {        test: /\.vue$/,        loader: 'vue-loader',        options: {          loaders: {            // 提取 <docs> 中的内容为原始文本            'docs': ExtractTextPlugin2.extract('raw-loader')          }        }      }    ]  },  resolve: {    alias: {      vue$: 'vue/dist/vue.js' //vue$表示精确匹配    }  },  plugins: [    new ExtractTextPlugin2("docs.md")  ]}

4、疑惑
自定义块是按照期望提取到docs.md中了,但是如果我想把.vue文件中的自定义块提取到docs.md,css提取到style.css,我该怎么办?我尝试实例化两个ExtractTextPlugin,发现提取结果是自定义块和css同时出现在docs.md和style.css中,不是我想要的结果。理想的结果应该是,docs.md只包含自定义块的内容,style.css只包含css的内容。

八、代码检验
eslint-loader能够在开发期间每次保存.vue文件时自动检验js代码规范。

1、安装loader

cnpm i -D eslint eslint-loader eslint-plugin-html

2、修改webpack.config.js文件

module.exports = {  entry: './main.js',  output: {    path: __dirname,    filename: 'bundle.js'  },  devtool: "inline-source-map",  module: {    rules: [      {        enforce: 'pre',        test: /\.(js|vue)$/,        loader: 'eslint-loader',        exclude: /node_modules/      },      {        test: /\.vue$/,        loader: 'vue-loader'      },      {        test: /\.css$/,        use: ['style-loader','css-loader']      }    ]  },  resolve: {    alias: {      vue$: 'vue/dist/vue.js' //vue$表示精确匹配    }  }}

Webpack loader处理顺序是从右到左。确保在vue-loader之前应用eslint-loader,这样才能检验编译前的代码。webpack中所有的loader都可以拥有include和exclude属性,exclude排除不满足条件的文件夹,include匹配需要被loader处理的文件或文件夹。第三方的.vue组件可以不用检验,只检验自己写的。
3、修改package.json文件

{  "name": "vuetest",  "version": "1.0.0",  "description": "",  "scripts": {    "test": "echo \"Error: no test specified\" && exit 1",    "server": "webpack-dev-server --open",    "build": "webpack-dev-server"  },  "author": "camille",  "license": "ISC",  "devDependencies": {    "css-loader": "^0.28.7",    "eslint": "^4.9.0",    "eslint-loader": "^1.9.0",    "eslint-plugin-html": "^3.2.2",    "style-loader": "^0.19.0",    "vue": "^2.5.2",    "vue-loader": "^13.3.0",    "vue-template-compiler": "^2.5.2"  },  "eslintConfig": {    "env": {      "browser": true    },    "plugins": [      "html"    ]  }}

4、新建index.html

<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <title>代码检查eslint,.vue文件和js文件</title></head><body>  <div id="J_vapp"></div>  <script type="text/javascript" src="bundle.js"></script></body></html>

5、修改main.js文件

var Vue = require('vue')var temptpl = require('./hello.vue').defaultvar vm = new Vue({  el: '#J_vapp',  template:'<tpl/>',  components: { tpl: temptpl }})

6、新建hello.vue文件

<template>  <p>{{greeting}},vue</p></template><script type="text/javascript">  module.exports={    data:function(){      return {        greeting:"hello"      }    }  }</script><style scoped>  p{    font-size:15px;    color:red;  }</style>

7、测试
故意写个错误,看看eslint-loader会不会起作用。
8、渲染结果

<p data-v-17976ece>hello,vue</p>

可以看出html中的J_vapp相当于桥梁,最后不会出现在dom中。

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,130
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,601
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,444
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,218
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,852
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,940