vue(9)—— 组件化开发 - webpack(3) vue(8)—— 组件化开发 - webpack(2) vue(7)—— 组件化开发 — webpack(1) vue(7)—— 组件化开发 — webpack(1)

前面两个终于把webpack相关配置解析完了。现在终于进入vue的开发了

  

vue组件化开发预热 

前期准备 

创建如下项目:

 

 app.js:

 footer.js:

main.js:

webpack.config.js:

同样的生成两个webpack配置文件,webpack.dev.config.js,webpack.prod.config.js,配置跟webpack.config.js一模一样

package.json:

组件化开发终于到了重头戏了

webpack引入vue

有几种方法导入

1.第一种

这个前面文章 vue(8)—— 组件化开发 - webpack(2)   已经用过了,不多说,直接在html文件里导入

2.第二种

在入口函数里引入:

然后在webpack配置文件里添加一个resolve属性:

注意,使用import导入的方法导入vue,导入的vue并不是完整的vue对象,只提供runtime-only的方式。

安装loader 

其实vue真的做组件化开发的时候,文件后缀名是.vue,并不是.js,所以webpack要识别后缀为vue的组件的话,需要安装loader

这里要注意,需要安装vue-loader和vue-template-compiler,前者是识别vue后缀的文件的,后者是识别vue后缀文件里的组件代码的,并且两者版本是配套,必须匹配,

我这安装的是vue-loader14.1.1 和[email protected]版本,当然你也可以安装更高版本的两个匹配的

webpack配置文件里配置 

配置上webpack-dev-server,html-webpack-plugin的配置,这里就略过了,还不太会的回过头去看

package.json配置:

 在项目根目录创建一个src文件,将刚才的app.js,footer.js,main.js移到src文件夹内,并把app.js和footer.js文件重命名后缀为.vue:

 

代码规范整合

vue文件

上面的app.js文件修改成app.vue之后,开发规范已经变了,只有如下三个标签作为逻辑代码,之前我们写的代码已经不认识

<!--结构-->
<template>    

</template>

<!--逻辑-->
<script>
export default {
    
}
</script>

<!--样式-->
<style>

</style>

 改成正确的代码:

export default 抛出一个vue组件,组件的结构为template,数据为data抛出,因为vue组件的data必须是一个函数,所以这里是函数

style样式则和之前用的没什么区别

footer.vue文件:

入口文件 

入口函数不用改为js文件

 main.js:

其他配置

其他webpack.dev.config.js和package.json不用变

编译运行 

npm  run dev: 

发现报错了,这里就解释前面文章 vue(7)—— 组件化开发 — webpack(1)   的问题为什么已经在全局安装webpack,在开发环境下还要再装一次了

npm i webpack -D 之后,再次编译运行,注意安装指定版本的webpack vue(7)—— 组件化开发 — webpack(1)

 运行是运行了,但是页面打开报错了,大概意思是说vue-loader和vue-template-compiler这两个插件有问题

按照我多年解决bug的问题,我把当前的vue版本卸载了,然后装了个低版本的,装了个与vue-template-compiler的版本一样的2.5.17版本的,完美解决上面这个问题

重新编译:

 发现还是报错,意思是这个App组件没有正确注册,检查代码,发现根本没有问题,把App删除之后,只留一个Footer看看:

 可以渲染,但是没有任何数据,按理说是有的

这下怎么办呢?进入关键地步,仔细看

初学者容易入的坑

错误分析

其实按道理完全没有问题,因为在之前非webpack下的vue开发中,在一个html文件就是这么用的没有错,那为什么这里的footer可以,app不行呢?大众思维,先把App删除掉,看Footer呢?

这到底怎么回事呢?标签可以出,但是没有数据渲染,卡在这了。

这里如果你去发现研究的话花些时间也会发现问题的,但是为了不浪费你的时间,你不用自己去研究了。

其实上面的Footer和App组件都错的,都不可以渲染成功的,其实footer的显示,其实是被浏览器当html5的标签处理了

如果你运气好,定义的两个组件的名字刚好和html5的标签撞上,那绝对不会报错,但是一样不会把数据渲染出来

总之,按以上以前简单的html页面的vue配置,根本就是错的,组件化开发根本不认这种写法。

为什么,就因为多定义了一个局部,然后再从这个局部组件挂载到vue实例,所以关键就在于我标注出的位置

 

也就是说,在webpack里,或者说在vue-loader和vue-template-compiler插件里,不认这种写法 

 既然都已经是组件化开发了,那么你要定义局部组件,完全可以再新建一个vue文件,然后写上组件代码,最后在入口文件main.js里挂载就行了

不信的话,看我现在不通过Main组件挂载,直接在vue实例对象里挂载App和Footer看看:

其他配置不变

打开页面,是不是显示了,而且没报错

正确引入vue组件

 好,再把刚才按个Main组件新建一个vue文件放进去

 

注意在vue文件里导入另一个vue文件的用法

main.js:

其他不变,打开网页,正确返回

好了组件化开发规范终于解析完了,下面才开始真正的开发测试

Vue组件化开发

掌握以上的规范之后,你就可以利用前面学到的vue开发,只要符合规范,随心所欲的在里面写你的代码了。如下,给一个简单的例子:

package.json:

 webpack.dev.config.js

 

入口文件  main.js:

main.vue

 

app.vue

 footer.vue

index.html

编译运行

打开网页:

页面数据是有了,但是这个有个问题,css样式乱了,我明明每个vue组件都设置了css的,但是都乱了

问题解决

这个就不多说了,在每个vue组件的sytle标签里都加上  scoped参数就行了

这个scoped就不多说了,它是由css属性选择器实现的,没必要去深究了,反正你就记住设置scoped之后当前的css样式只对当前的元素生效,对其他文件上的html元素不生效就行了

相关代码:

{
  "name": "day3",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "webpack-dev-server --open --hot --inline --config ./webpack.dev.config.js",
    "build": "webpack --config ./webpack.prod.config.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {},
  "devDependencies": {
    "css-loader": "^2.1.1",
    "html-webpack-plugin": "^3.2.0",
    "style-loader": "^0.23.1",
    "vue": "^2.5.17",
    "vue-loader": "^14.1.1",
    "vue-template-compiler": "^2.5.17",
    "webpack": "^3.12.0",
    "webpack-dev-server": "^2.9.0"
  }
}
package.json
var path = require('path')
var htmlwebpackplugin = require('html-webpack-plugin')
module.exports = {
    entry: {
        name: './src/main.js'
    },
    output: {
        path: path.resolve('./dist'), // 项目输出文件路径
        filename: './bundle.js'
    },
    watch: true,
    module: {
        loaders: [
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            },
            {
                test: /\.css$/,
                loader: 'style-loader!css-loader'
            }
        ]
    },
    plugins: [
        new htmlwebpackplugin({
            template: `./index.html`  //参照物
        })
    ]
}
webpack.dev.config.js
var path = require('path')
var htmlwebpackplugin = require('html-webpack-plugin')
module.exports = {
    entry: {
        name: './src/main.js'
    },
    output: {
        path: path.resolve('./dist'), // 项目输出文件路径
        filename: './bundle.js'
    },
    module: {
        loaders: [
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            },
            {
                test: /\.css$/,
                loader: 'style-loader!css-loader'
            }
        ]
    },
    plugins: [
        new htmlwebpackplugin({
            template: `./index.html`  //参照物
        })
    ]
}
webpack.prod.config.js
import Vue from '../node_modules/vue/dist/vue.js'
import Main from './Main.vue'
new Vue({
    el: '#app',
    data() {
        return {
        }
    },
    components: {
        Main
    },
    render(createdElements) {
        return createdElements(Main)
    },
    // template: `<Main />`
});
main.js
<template>
    <div class='main'> {{msg}}
        <App @postHander='postHanders'/>
        <Footer :cont='sendmsg'/> 
    </div>
</template>
<script>
import App from './app.vue'  // 在vue组件里导入另一个vue组件,得在script标签里导入
import Footer from './footer.vue'
export default {
    name:'Main',
    data(){
        return {
            msg:'Main入口',
            sendmsg:'',
        }
    },
    components:{
        App,
        Footer
    },
    methods:{
        postHanders(value){
            console.log(value,'父级接收到了数据,正准备传给footer组件')
            this.sendmsg = value // app.vue组件传来的数据,值为true
        }
    },    
}
</script>
<style scoped>
    .main{
        color: brown;
    }
</style>
Main.vue
<template>
  <div class='apps'> {{msg}}
    <div v-bind:class="isShow"></div>
    <input type="text" v-model="test"><span>{{test}}</span><br>
    <input type="text" ref='inputs' v-model='test2'><br>
    <button @click="btnHander" ref="btn">点我传数据给父级</button>
  </div>
</template>
<script>
export default {
    name:'App',
    data(){
        return {
            msg:'app内容',
            isShow:true,
            test:'', 
            test2:''  }
    },
    methods:{
        btnHander(){
            this.$emit('postHander',this.isShow)
            this.$refs.btn.innerHTML = '数据已发送'  }
    },
    watch: {
        test2(value){
            if(value=='vue'){
                this.test2 = '我监听到你填了vue'
                this.$refs.inputs.value = '' }
        }
    }
}
</script>
<style scoped>
    .apps{
        font-size: 12px;
        background: salmon;
        color: blue;
    }
</style>
app.vue
<template>
    <div class='footers'>{{msg}}
        <p v-text="test1"></p>  
        <p v-html="test2"></p>       
        <button @click="getHander(cont)">点我展示从父级获取到的数据</button>
        <ul v-show="isShow">
            <li v-for = 'item in datas' :key = 'item.id'>  {{ item.name }} -- {{item.age}} </li>
        </ul>
    </div>
</template>
<script>
export default {
    name:'Footer',
    data(){
        return {
            msg:'footer内容',
            test1:'测试1',
            test2:'<h4>测试2</h4>',
            datas:[
                {'id':1,'name':'jack','age':30},
                {'id':2,'name':'lucy','age':26},
                {'id':3,'name':'lily','age':28},],
            isShow:false }},
    methods:{
        getHander(cont){
            this.isShow = cont }
    },
    props:['cont'], // 父级传来的数据,值为true
    mounted(){      // 生命周期函数
        console.log() }
}
</script>
<style scoped>
    .footers{
        color: purple;
        font-size: 15px;
        font-weight: bold;  }
</style>
footer.vue
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    
    <div id="app">    
        <p>test</p>
    </div>    
</body>
</html>
index.html

补充

render渲染

在vue中,渲染网页数据还可以用render渲染:

其他配置如上,只是入口函数Vue实例对象部分,将template属性注释掉,使用了render渲染,里面传入的createdElements是一个固定的方法,它能把传入的组件模板渲染成html结构,个人觉得render跟template的用法是一样的都会把之前的模板清理掉重新渲染使用<component is='app id'>就不会清理掉再重新渲染

不过这个与templated的相同与否还有待各项测试论证,只是我个人发现

如果你实在记不住createdElements方法,render还有更简单的写法,用箭头函数:

打开网页: 

export语法

export在前面可能说得不太清楚,这里补充说明下

到目前为止,其实看到了两种export,一种是Node.js的webpack中的export,一种是es6语法中的export

  • module.exports = {} 是Node中向外抛出变量的形式
  • export default  {}  是es6中向外抛出变量的形式,与之配套的接收变量导入是用  import  {} from './...'
分别的导入导出
  • webpack里的module.exports没什么需要注意的,导入方使用 requre('模块名')导入
  • es6中的export,当使用export  default 向外抛出变量式,import导入接收变量方可以使用任意的变量名接收
  • 在一个文件中,export  default只能使用一次,只能默认抛出一个默认的变量,但是export default和export (不加default)可以同时使用
  • 使用export (不加default)抛出变量时,可以同时抛出多个变量,import导入接收变量一方只能使用 {} 的形式接收,但不必全部接收,需要什么就接收什么,并且必须严格按照export抛出方的变量名接收,但可以用 as  取别名

脚手架式开发

什么是脚手架

最开始的意思就是建筑施工队用的梯子架子等工具,在开发界也有这个词。

这里就不去溯源最开始什么意思,到现在什么意思了,我就直说按我的理解:

脚手架就是说一些已经有人帮你把开发过程要用的工具环境都开发配置好了,你拿来直接可以用就行了,可以帮助你减轻很多重复的工作,更利于让你专注业务开发。这个开发环境就是脚手架

前端开发中的脚手架是一种形象的比喻,比如各类语言的工作环境

Yeoman

关于前端的脚手架官网:传送门  里面的就类似npm官网一样,里面有很多别人写好的脚手架,你拿来直接用就可以了

Yeoman其实是3套工具的总和:

  • yo --- 脚手架,自动生成工具
  • Grunt、gulp --- 构建工具 (最初只有grunt,后面gulp火了添加进来的)
  • Bower、npm --- 包管理工具 (原来是 bower,后面添加了npm)

vue的脚手架

vue的脚手架就是vue-cli,这个cli在前面安装webpack的时候你可能就见过了,因为安装高版本的webpack组件时需要cli支持的。官网:传送门

安装vue-cli

npm i @vue/cli -g 

拉取vue-cli旧版本

因为vue-cli就跟Python的版本2和版本3一样,有很大不同,但也有很多相同,所以最好还是两个版本都装上最好:

npm i @vue/cli-init -g

vue-cli创建项目须知

3.0版本创建是用 vue create:

2.0版本用 vue init:

注:使用不同版本的vue-cli创建项目时,相关的参数也不一样的:

其中vue init中的<template>是模板类型的意思

webpack的模板类型有webpack-simple (简单模型)和webpack(复杂模型)

创建简单模型的webpack项目

 1. vue init命令创建

 

创建vue-cli项目时是需要联网的,因为要下载需要的脚手架

创建完成:

里面的参数就不多说了,都应该看得懂吧

2.按照提示,进入webpacksimple-test目录,执行npm install命令:

3.安装开发环境完成之后,直接执行npm  run dev:

浏览器自动打开:

很6对吧?这时你发现,卧槽,前面的webpack配置半天的东西,到这里用vue-cli三两句命令就直接出来了,太骚了

用开发工具,vscode打开项目文件夹:

 其实跟我们之前的配置真的没多大区别,稍微的有些组件什么的不一样而已,功能完全一样的,就不仔细展开了

4.改数据

你可以直接用它的模板改成你的数据:

 也支持热更新,直接就可以用:

具体就不多说了,自己去发现了

创建复杂型webpack项目

 1.命令vue init创建

 创建时,注意这里要选第一个:

 

其他相关配置:

之后就是网速限制思想的时候,等待吧

创建完成:

2.进入目录,直接npm  run dev:

 

 打开浏览器:

3.同样的,用开发工具打开项目目录,然后你就可以进行修改了

 

改完之后你就可以利用npm run build生成你的代码,放到服务器上了,具体怎么改就不掩饰了,根据自己的业务逻辑来了,后面的操作就是前面解析过的vue相关的操作了

引入UI组件

什么是UI

UI的意思就是用户界面,也就是用户的操作界面,换句话就是展示的页面,UI设计就是界面的样式,到现在,大家都这么理解的UI,bootstrap那种样式用过吧?它就可以说是一个UI组件。

通俗的说,就是各种样式效果,因为光是文字的话,看着是很单调的,这种对于用户体验来说是很不友好的,比如某某网,就不说是谁了,满屏的字,真的是看着很吃力的,而且字还不大,想起当年的我,还在大学里学着非常low的网页设计时,我那个教前端的老师让做一个个人主页出来,说按照他的做,就是满屏的字,图片没几个,而且还是五颜六色的字,真的看着很累。

到现在,已经有很多的UI库出现,比如就大家都爱用的bootstrap,还有font awesome和阿里的iconfont,这些是最常见的,很多平台用的UI都是这几家的。

MUI

官网 :传送门  ,不是小米系统那个MUI哈,这个是个移动端的UI库,据说是移动端的bootstrap,目前很多app用的都是MUI的样式

这个就不多介绍,官网里面基本都有,中文文档什么的写的很详细,还有些demo演示,要用直接看文档就行了。任何项目都可以使用MUI

Vue的UI组件

以下的UI组件原则上只能适用于vue开发,因为都是基于vue.js开发的

Mint UI 

Mint UI是基于vue开发的移动端的UI组件,官网:传送门  

VUX

VUX也是基于vue和微信的WeUI开发的移动端UI组件,官网:传送门  貌似可以用于开发其他的,不只是vue

Element UI 

Element UI是饿了么出的一个基于vue的PC端UI组件,官网:传送门

iView

也是基于vue的一个UI组件,官网:传送门

注:

以上几个UI都是目前比较火的UI组件,因为官网已经介绍的非常详细,所以完全可以按照官网的文档自学。

我有时间再出个文档,没时间就自己按照官网的自学吧

总结

以上就是webpack相关的配置了,vue部分已经完毕,后续原则上不打算更新了,当然如果我觉得有些很经典很有用的点的话,会有机会更新。

准备填我的坑了,前端基础部分和Python部分的坑都还有很多没有填的,后续会把这些更新了,感兴趣的朋友可以关注一波。

猜你喜欢

转载自www.cnblogs.com/yangva/p/10600648.html