Vue基础教程深入篇

文章目录

            • 1. 父级向子级组件传值
            • 2. 子级向父级组件传值
            • 3. 平行组件传值
            • 4. Vue全家桶是什么
            • 5. 为什么要使用单页面应用
            • 6. 安装vue-cli脚手架
            • 7. 过滤器的使用
            • 8. 生命周期的钩子函数
            • 9. router的基本使用
            • 10. 命名路由和动态路由匹配
            • 11. 编程式导航
            • 12. refs属性的使用
            • 13. 模块化初探索
            • 14. Vue的模块化初探索
            • 15. webpack的使用
            • 16. webpack中loader的使用
            • 17. webpack中plugin的使用
            • 18. 单文件的使用
            • 19. 单页面SPA应用
            • 20. css中scoped的使用
            • 21. vue-cli的使用
            • 22. element-ui的使用

Githubhttps://github.com/ThanlonSmith/vue-tutorial-chinese

1. 父级向子级组件传值

父组件中可以使用静态绑定传入子组件的值,也可以动态绑定传入子组件的值:


<html lang="zh-CH">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>父级向子级组件传值title>
head>
<body>
<div id="app">
    <App>App>
div>
body>
<script src="//cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script>
    Vue.component('VBtn', {
      
        data() {
      
            return {
      }
        },
        template: `
          
        `,
        props: ['id'],
        methods: {
      
            clickHandler() {
      
                // 每个组件中的this指的是当前组件对象
                console.log(this) // VueComponent {_uid: 3, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
            }
        },
        created() {
      
            console.log(this) // VueComponent {_uid: 3, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
        }
    })
    let Vheader = {
      
        data() {
      
            return {
      
                text: '我是子组件中的数据!'
            }
        },
        template: `
          
{ { text }}分割线下面是来自父组件传过来的值:
msg:{ { msg }}
post.id:{ { post.id }}
post.title:{ { post.title }}

`
, // 挂载父组件属性。只要声明了父组件的属性就可以使用 props: ['msg', 'post'], methods: { // 由于是VBtn调用clickHandler,所以这里的clickHandler不会被执行 clickHandler() { alert(1) } }, created() { console.log(this) // VueComponent {_uid: 2, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …} } } let App = { data() { return { text: '我是父组件中准备传入子组件中的数据,可以使用v-bind动态绑定也可以静态绑定!', post: { id: 1, title: '我是父组件自定的属性title!' } } }, template: `
`
, components: { Vheader: Vheader }, created() { console.log(this) // VueComponent {_uid: 1, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …} } } let vm = new Vue({ el: '#app', data() { return { } }, components: { App }, created() { console.log(this) // Vue {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …} } })
script> html>

Vue基础教程深入篇_第1张图片

2. 子级向父级组件传值

这里沿用第1部分做的:


<html lang="zh-CH">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>子组件向父组件传值title>
head>
<body>
<div id="app">
    <App>App>
div>
body>
<script src="//cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script>
    Vue.component('VBtn', {
      
        data() {
      
            return {
      }
        },
        template: `
          
        `,
        props: ['id'],
        methods: {
      
            clickHandler() {
      
                // 每个组件中的this指的是当前组件对象
                console.log(this) // VueComponent {_uid: 3, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
                // this.$emit('父组件声明自定义的事件', '传值')
                console.log('VBtn组件:', this.id)
                this.$emit('VheaderHandler', this.id)
            }
        },
        created() {
      
            console.log(this) // VueComponent {_uid: 3, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
        },
    })
    let Vheader = {
      
        data() {
      
            return {
      
                text: '我是子组件中的数据!'
            }
        },
        template: `
          
{ { text }}分割线下面是来自父组件传过来的值:
msg:{ { msg }}
post.id:{ { post.id }}
post.title:{ { post.title }}

`
, // 挂载父组件属性。只要声明了父组件的属性就可以使用 props: ['msg', 'post'], methods: { // 由于是VBtn调用clickHandler,所以这里的clickHandler不会被执行 VheaderHandler(val) { // @VheaderHandler与其值可以不一样,但必须与子组件中的this.$emit('VheaderHandler', this.id)中的VheaderHandler一样 console.log('Vheader组件:' + val) this.$emit('AppHandler', val) } }, created() { console.log(this) // VueComponent {_uid: 2, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …} } } let App = { data() { return { text: '我是父组件中准备传入子组件中的数据,我需要通过v-bind绑定才能使用!', post: { id: 1, title: '我是父组件自定的属性title!' } } }, template: `
`
, components: { Vheader: Vheader }, created() { console.log(this) // VueComponent {_uid: 1, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …} }, methods: { app_handler(val) { console.log('App组件:' + val) this.post.id = val } } } let vm = new Vue({ el: '#app', data() { return { } }, components: { App }, created() { console.log(this) // Vue {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …} } })
script> html>

Vue基础教程深入篇_第2张图片

3. 平行组件传值

<html lang="zn-CH">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>平行组件传值title>
head>
<body>
<div id="app">
    <App>App>
div>
body>
<script src="//cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script>
    // Test1组件向Test2传值,Test2要声明事件:$on('事件的名字',function(){}),Test1要触发事件:$emit('Test声明的事件的名字','值')
    // 前提:这两个方法必须同一个实例化对象“bus”上
    let bus = new Vue() // 新建Vue对象作为两个方法共同绑定的实例化对象
    Vue.component('Test2', {
      
        data() {
      
            return {
      
                txt: '我是Test2组件!',
                text: ''
            }
        },
        template: `
          
{ { txt }} { { text }}
`
, created() { bus.$on('testData', (val) => { console.log(bus) console.log('传递过来的值:' + val) this.text = val }) } }) Vue.component('Test1', { data() { return { msg: '收到来自Test1组件的数据!' } }, props: ['txt'], template: ` `, methods: { clickHandler() { console.log("bus:" + bus) bus.$emit('testData', this.msg) } } }) let Vheader = { data() { return { txt: '传递' } }, template: `
`
} let App = { data() { return { } }, template: `
`
, components: { Vheader: Vheader } } let vm = new Vue({ el: '#app', data() { return { } }, components: { App: App } })
script> html>

在这里插入图片描述
在这里插入图片描述

4. Vue全家桶是什么

vue和vue-router以及vuex三者合起来是Vue的全家桶,Vue全家桶主要用来做SPA(Simple Page Application)单页面应用。

5. 为什么要使用单页面应用

传统的路由跳转,如果后端资源比较多,会导致页面出现 “白屏” 现象。让前端来做路由,在某个生命周期函数中发送 AJAX,数据驱动视图,提升用户体验。

6. 安装vue-cli脚手架

淘宝npm镜像:https://developer.aliyun.com/mirror/NPM?from=tnpm
vue-cli官网:https://cli.vuejs.org/zh/guide/

# 安装cnpm
$ npm install -g cnpm --registry=https://registry.npm.taobao.org
# 安装vue-cli
$ npm install -g @vue/cli
7. 过滤器的使用

局部过滤器:在当前组件内部使用过滤器。使用过滤器其实就是给某系数据“添油加醋”,使用的格式(伪代码):

//声明
filters:{
     
    '过滤器的名字':function(val,a,b){
     
        // val就是当前的数据,a和b是参数
	}
}
//使用管道符
数据 | 过滤器的名字('erics''thanlon') // a='erics',b='thanlon',管道符|左右的空格也可以删除

局部过滤器使用示例:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>过滤器title>
head>
<body>
<div id="app">
    <App/>
div>
body>
<script src="//cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.27.0/moment.js">script>
<script>
    // 这是个局部组件,非全局组件
    let App = {
      
        data() {
      
            return {
      
                msg: 'Hello World!',
                time: new Date()
            }
        },
        template: `
          
{ { msg|myReverse }} { { time | myTime('YYYY-MM-DD') }}
`
, filters: { myReverse: function (val) { console.log(val) // Hello World! return val.split('').reverse().join('') // 'Hello World!'->['H','e',,,,]->['!','d']->'!dlroW olleH' }, // 年-月-日(YYYY-MM-DD),年可以不区分大小写,但月日必须区分 myTime: function (val, formatStr) { return moment(val).format(formatStr) } } } new Vue({ el: '#app', data() { return { } }, components: { App } })
script> html>

在这里插入图片描述

全局过滤器:只要过滤器一创建,在任何组件中都能使用。使用的格式(伪代码):

Vue.filter('过滤器的名字'function(val,a,b){
     })
//在各个组件中都能使用
数据 | 过滤器的名字('thanlon''erics')

全局过滤器使用示例:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>过滤器title>
head>
<body>
<div id="app">
    <App/>
div>
body>
<script src="//cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.27.0/moment.js">script>
<script>
    //全局过滤器,
    Vue.filter('myTime', function (val, formatStr) {
      
        return moment(val).format(formatStr);
    })
    // 这是个局部组件,非全局组件
    let App = {
      
        data() {
      
            return {
      
                msg: 'Hello World!',
                time: new Date()
            }
        },
        template: `
          
{ { msg|myReverse }} { { time | myTime('YYYY-MM-DD') }}
`
, filters: { myReverse: function (val) { console.log(val) // Hello World! return val.split('').reverse().join('') // 'Hello World!'->['H','e',,,,]->['!','d']->'!dlroW olleH' }, } } new Vue({ el: '#app', data() { return { } }, components: { App } })
script> html>

同样的效果:
在这里插入图片描述

过滤器是针对某一个页面的某些个操作,如将后端返回的钱数加上美元符号$或者做其它的处理,如将后端返回的很长的文本进行处理,截取指定长度的字符串,多余的字符串可以拼接上三个点。

8. 生命周期的钩子函数

开始到结束的过程就是一个生命周期,Vue生命周期的钩子函数主要有以下几种:beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、activated、deactivated、beforeDestory、destoryed。

beforeCreate:组件创建之前
created:组件创建之后
beforeMount:装载数据到DOM之前
mounted:装载数据到DOM之后
beforeUpdate:获取原始DOM
updated:获取更新之后的DOM
activated:激活当前组件(vue提供内置组件
deactivated:停用当前组件
beforeDestory:组件销毁之前
destoryed:组件销毁之后

生命周期钩子函数.html:(不建议使用中文命名)


<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>生命周期钩子函数title>
head>
<body>
<div id="app">
    <App>App>
div>
body>
<script src="//cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script>
    let Test = {
      
        data() {
      
            return {
      
                msg: 'Erics',
                count: 0,
                timer: null,
            }
        },
        template: `
          
我的名字是{ { msg }}!

{ { count }}
`
, methods: { changeName() { this.msg = 'Kiku' document.getElementById('box').style.color = 'red' } }, beforeCreate() { /** * 组件创建之前 * beforeCreate获取不到数据 */ console.log('组件创建之前:', this.msg) }, created() { /** * 组件创建之后,使用该组件就会触发以上钩子方法,created中可以操作数据、可以发送AJAX,并且可以实现数据驱动视图 * 已经有数据了(DOM渲染完成之前),created只是把template创建出来,但是还没有被渲染到app组件中,更没有渲染到Vue中 * Tip:90%的情况下是在created方法中获取数据 * 组件创建之后才可以获取数据 */ console.log('组件创建之后:', this.msg) // this.msg = 'Thanlon' this.timer = setInterval(() => { this.count++ }, 5000) /** *虚拟DOM:由React引出,比原生js和jquery操作DOM效率要有所提高 */ }, beforeMount() { /** * 装载数据到DOM之前会调用 */ console.log('装载数据到DOM之前会调用:', document.getElementById('app')) }, mounted() { /** * 这个地方可以操作DOM,装载数据到DOM之后(DOM挂载完成)会被调用,可以获取真实存在的DOM元素(标签已经被渲染了) * Tip:这里可以操作DOM;能用数据驱动改数据就不用操作DOM */ console.log('装载数据到DOM之后会调用:', document.getElementById('app')) }, beforeUpdate() { /** * 在更新之前调用,获取原始的DOM */ console.log('在更新之前调用:') console.log(document.getElementById('app').innerHTML); }, updated() { /** * 在更新之后调用,获取嘴型的DOM */ console.log('在更新之后调用:') console.log(document.getElementById('app').innerHTML) }, beforeDestroy() { console.log('销毁组件之前调用!') }, destroyed() { console.log('销毁组件之后调用!', this.timer) // 每次创建定时器数字是不一样的 // 销毁定时器,销毁和创建很消耗性能 clearInterval(this.timer) }, activated() { console.log('组件被激活了!') }, deactivated() { console.log('组件被停用了!') } } let App = { data() { return { isShow: true } }, /** template: `

`, **/
// 这个组件被缓存起来,keep-alive是Vue内置的,其作用是让组件产生缓存 template: `

`
, components: { Test: Test }, methods: { clickHandler() { this.isShow = !this.isShow } } } let vm = new Vue({ el: '#app', data() { return { }; }, components: { App: App } })
script> html>

没有使用 keep-alive 缓存组件:

Vue基础教程深入篇_第3张图片

Vue基础教程深入篇_第4张图片
Vue基础教程深入篇_第5张图片
使用 keep-alive 缓存组件时:

Vue基础教程深入篇_第6张图片
Vue基础教程深入篇_第7张图片
Vue基础教程深入篇_第8张图片

created 和 mounted 是比较重要的两个钩子函数!created 是在组件创建完成后触发的钩子函数,在函数中可以发起 ajax (XMLHttpRequest,XHR)、axios、fetch、$ajax 请求实现数据驱动视图。mounted 是在 DOM 装载数据之后调用,可以在这里请求数据。组件创建完成后和 DOM 装载数据之后发送获取数据的请求都是没所谓的。获取数据的过程是很快的,大部分是在组件加载之后提前准备好数据。

9. router的基本使用

router的基本使用.html:


<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>router的基本使用title>
head>
<body>
<div id="app">

div>
body>
<script src="//cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script src="//unpkg.com/vue-router/dist/vue-router.js">script>
<script>
    let Home = {
      
        data() {
      
            return {
      }
        },
        template: `
          
首页内容!
`
} let Course = { data() { return { } }, template: `
免费课程内容!
`
} const router = new VueRouter({ mode: 'history', //定义路由规则 routes: [ { path: '/', redirect: '/home' }, { path: '/home', component: Home }, { path: '/course', component: Course } ] }) let App = { data() { return { } }, // router-link和router-view是vue-router提供的两个全局组件,vue-router是路由组件的出口 template: `
首页 免费课程

`
, components: { Home: Home } } let vm = new Vue({ el: '#app', // 挂载路由对象(router对象)到Vue的实例中 router: router, data() { return { } }, template: ` `, components: { App: App } })
script> html>

Vue基础教程深入篇_第9张图片
Vue基础教程深入篇_第10张图片

router-link默认被渲染成a标签,to属性会被渲染成href!

10. 命名路由和动态路由匹配

命名路由其实就是给路由命名,使用的时候直接使用路由的名字来代替路由。

命名路由.html:


<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>命名路由title>
head>
<body>
<div id="app">

div>
body>
<script src="//cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script src="//unpkg.com/vue-router/dist/vue-router.js">script>
<script>
    let Home = {
      
        data() {
      
            return {
      }
        },
        template: `
          
首页内容!
`
} let Course = { data() { return { } }, template: `
免费课程内容!
`
} const router = new VueRouter({ mode: 'history', //定义路由规则 routes: [ { path: '/', redirect: '/home' }, { path: '/home', name: 'Home', component: Home }, { path: '/course', name: 'Course', component: Course } ] }) let App = { data() { return { } }, // router-link和router-view是vue-router提供的两个全局组件,vue-router是路由组件的出口 template: `
首页 免费课程

`
, components: { Home: Home } } let vm = new Vue({ el: '#app', // 挂载路由对象 router: router, data() { return { } }, template: ` `, components: { App: App } })
script> html>

/user/1和/user/2加载的是同一个组件,动态路由匹配示例:

动态路由匹配.html:


<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>动态路由匹配title>
head>
<body>
<div id="app">

div>
body>
<script src="//cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script src="//unpkg.com/vue-router/dist/vue-router.js">script>
<script>
    let User = {
      
        data() {
      
            return {
      
                user_id: null,
            }
        },
        template: `
          
我是用户{ { user_id }}!
`
, created() { /** * 当使用路由参数时,例如从 /user/foo 导航到 /user/bar,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。 * 只调用一次 */ console.log(this.$route) // 路由信息对象:{name: "User", meta: {…}, path: "/user/1", hash: "", query: {…}, …} }, watch: { '$route'(to, from) { // 对路由变化做出响应 console.log('to:', to) // to: {name: "User", meta: {…}, path: "/user/2", hash: "", query: {…}, …}\ console.log('from:', from) // from: {name: "User", meta: {…}, path: "/user/1", hash: "", query: {…}, …} console.log(to.params.id) this.user_id = to.params.id // 发送AJAX } } } // 创建路由 const router = new VueRouter({ mode: 'history', //定义路由规则 routes: [ { path: '/user/:id', name: 'User', component: User }, ] }) let App = { data() { return { } }, // router-link和router-view是vue-router提供的两个全局组件,vue-router是路由组件的出口 template: `
用户1 用户2

`
, components: { User: User } } let vm = new Vue({ el: '#app', // 挂载路由对象 router: router, data() { return { } }, template: ` `, components: { App: App } })
script> html>

Vue基础教程深入篇_第11张图片

watch可以用来监听路由的变化!

$.route是路由信息对象,$router是路由对象VueRouter!

11. 编程式导航

上面所有部分使用的是声明式导航:

<router-link :to="{name:'User',params:{id:1}}">用户1router-link>
<router-link :to="{name:'User',params:{id:2}}">用户2router-link>

编程式导航:


<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>编程式导航title>
head>
<body>
<div id="app">

div>
body>
<script src="//cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script src="//unpkg.com/vue-router/dist/vue-router.js">script>
<script>
    let Home = {
      
        data() {
      
            return {
      }
        },
        template: `
          
我是首页
`
} let User = { data() { return { user_id: null, } }, template: `
User{ { user_id }}!
`
, created() { /** * 当使用路由参数时,例如从 /user/foo 导航到 /user/bar,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。 * 只调用一次 */ console.log(this.$route) // 路由信息对象:{name: "User", meta: {…}, path: "/user/1", hash: "", query: {…}, …} }, watch: { '$route'(to, from) { // 对路由变化做出响应 console.log('to:', to) // to: {name: "User", meta: {…}, path: "/user/2", hash: "", query: {…}, …}\ console.log('from:', from) // from: {name: "User", meta: {…}, path: "/user/1", hash: "", query: {…}, …} console.log(to.params.id) this.user_id = to.params.id // 发送AJAX } }, methods: { // 编程式导航 clickHandler() { this.$router.push({ name: 'Home' }) } } } // 创建路由 const router = new VueRouter({ mode: 'history', //定义路由规则 routes: [ { path: '/home', name: 'Home', component: Home }, { path: '/user/:id', name: 'User', component: User }, ] }) let App = { data() { return { } }, // router-link和router-view是vue-router提供的两个全局组件,vue-router是路由组件的出口 template: `
用户1 用户2

`
, components: { User: User } } let vm = new Vue({ el: '#app', // 挂载路由对象 router: router, data() { return { } }, template: ` `, components: { App: App } })
script> html>

Vue基础教程深入篇_第12张图片
Vue基础教程深入篇_第13张图片

12. refs属性的使用

refs属性可以用来获取标签原生的DOM对象和组件实例,需要在mounted函数中获取。


<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>refs属性的使用title>
head>
<body>
<div id="app">

div>
body>
<script src="//cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script>
    Vue.component('Test', {
      
        data() {
      
            return {
      }
        },
        template: `
          
我是测试组件1!
`
}) Vue.component('Test2', { data() { return { } }, template: `
我是测试组件2!
`
}) let App = { data() { return { } }, template: `
`
, mounted() { console.log(this.$refs.input) // 获取原始DOM对象: console.log(this.$refs) // {input: input}...可以展开 this.$refs.input.focus() console.log(this) // VueComponent {_uid: 1, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …} console.log(this.$root) // VueComponent {_uid: 1, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …} console.log(this.$refs.abc) // VueComponent {_uid: 2, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …} console.log(this.$refs.parent) // undefined console.log(this.$refs.root) // undefined console.log(this.$children[0]) // VueComponent {_uid: 2, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …} } } let vm = new Vue({ el: '#app', data() { return { } }, template: ` `, components: { App } })
script> html>

Vue基础教程深入篇_第14张图片

13. 模块化初探索

使用node来运行模块化的JavaScript程序:

test.js:

let person = {
     
    name: 'erics'
}
module.exports = person

index.js:

let person = require('./test')
console.log(person)
console.log(person.name)

可以使用 node index.js 命令来运行,

$ node index.js 
{
      name: 'erics' }
erics

使用webpack打包:

module.js:

let person = {
     
    name: 'erics',
    func: function () {
     
        alert('success!')
    }
}
export default person;

main.js:

import person from './module'
console.log(person.func())

使用webpack进行打包:

$ sudo webpack ./main.js -o ./bundle.js
Hash: b7b9dbe6291ed213470d
Version: webpack 4.44.1
Time: 168ms
Built at: 2020/08/21 下午1:52:26
    Asset   Size  Chunks             Chunk Names
bundle.js  1 KiB       0  [emitted]  main
Entrypoint main = bundle.js
[0] ./main.js + 1 modules 170 bytes {
     0} [built]
    | ./main.js 56 bytes [built]
    | ./module.js 114 bytes [built]

打包完成后当前目录中多了一个bundle.js文件,这就是打包后的文件。在index.html中只需要引入它:

index.html:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Documenttitle>
head>
<body>

body>
<script src="bundle.js">script>
html>

main.js和module.js里面的代码成功被执行:
Vue基础教程深入篇_第15张图片
可以抛出多个变量,修改model.js和main.js重新打包,

module.js:

let person = {
     
    name: 'erics',
    func: function () {
     
        alert('success!')
    }
}
let name = 23
// 可以抛出多个变量
export {
     name}
export let nowYear = 2020
export default person;

main.js:

import * as a from './module'

console.log(a)

Vue基础教程深入篇_第16张图片
当然可以使用a.xxx来执行函数或者获取变量。

webpack依赖于node.js!

14. Vue的模块化初探索

可以把模块化应用在Vue上,

App.js:

let App = {
     
    template: `
    
我是App组件!
`
} export default App;

main.js:

import Vue from './vue'
import App from './App'

let vm = new Vue({
     
    el: '#app',
    template: `
        
    `,
    components: {
     
        App
    }
})

index.html:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<div id="app"></div>
</body>
<script src="./bundle.js"></script>
</html>

使用webpack命令打包:webpack main.js -o bundle.js,然后可以正常访问 index.html

15. webpack的使用

很明显上面的例子中每次更新 JavaScript 代码都会重新打包,这是很繁琐的。实际上,通过设置完全可以自动打包,实时编译。首先需要通过 npm -init --yes 命令来创建配置文件 package.json

{
     
  "name": "webpack_use",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
     
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

接下来通过 $ cnpm i webpack -D 下载 webpack

可以指定webpack的版本:$ cnpm i [email protected] -D

下载完成后配置文件 package.json 中发生了变化:

"devDependencies": {
     
  "webpack": "^4.44.1"
}

devDependencies 指的是开发环境依赖。可以对 package.json 进行修改,使用 npm 命令 $ npm run dev 来替代 $ webpack ./main.js -o ./bundle.js 打包文件。所以,还需要修改配置文件:

"scripts": {
     
  "dev": "webpack ./main.js ./bundle.js"
},

还可以进行改进,修改 package.json :

"scripts": {
     
  "dev": "webpack"
},

我们想要只使用 webpack 命令来打包,可以在项目中创建一个 webpack 默认的配置文件 webpack.config.js,该配置文件写的都是 nodejs 代码:

module.exports = {
     
    entry: {
     
        'main': './main.js'
    },
    output: {
     
        'filename': './bundle.js'
    }
}

使用 $npm run dev 会优先找配置文件 webpack.config.js,找到入口 main.js,打包输出 bundle.js。为了实现 监听代码的改动自动编译,需要加上 watch:true

module.exports = {
     
    entry: {
     
        'main': './main.js'
    },
    output: {
     
        'filename': './bundle.js'
    },
    watch: true
}

开发环境中需要有监听代码自动编译功能,生产环境不需要,

webpack.dev.config.js:

module.exports = {
     
    entry: {
     
        'main': './main.js'
    },
    output: {
     
        'filename': './bundle.js'
    },
    watch: true
}

webpack.pro.config.js:

module.exports = {
     
    entry: {
     
        'main': './main.js'
    },
    output: {
     
        'filename': './bundle.js'
    }
}

package.json:

{
     
  "name": "webpack_use",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
     
    "dev": "webpack --config ./webpack.dev.config.js",
    "build": "webpack --config ./webpack.pro.config.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
     
    "webpack": "^4.44.1",
    "webpack-cli": "^3.3.12"
  }
}

如果是新版本的 webpack,可以这样配置,

webpack.pro.config.js:

module.exports = {
     
    // entry: './main.js',
    entry: {
     
        'main': './main.js'
    },
    output: {
     
        'filename': './bundle.js'
    },
    watch: true,
    mode: 'development'
}

package.json:

{
     
  "name": "webpack_use",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
     
    "dev": "webpack --mode development",
    "build": "webpack --mode production"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
     
    "webpack": "^4.44.1",
    "webpack-cli": "^3.3.12"
  }
}
16. webpack中loader的使用

可以把css直接打包到js文件中,不需要再html文件中再引用。新建 index.css 文件,在里面写好样式,然后导入到 main.js 中,

index.css:

body{
     
    background: rebeccapurple;
}

main.js:

import Vue from './vue'
import App from './App'
import './index.css'
let vm = new Vue({
     
    el: '#app',
    template: `
        
    `,
    components: {
     
        App
    }
})

但是会报错:

ERROR in ./index.css 1:4
Module parse failed: Unexpected token (1:4)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> body{
     
|     background: rebeccapurple;
| }
 @ ./main.js 3:0-20

在组件中引入css,需要用到css-loader和style-loader, css-loader是用来解析css文件,style-loader是用来解析style标签的。所以需要下载并配置它们:$ cnpm i css-loader style-loader -D

webpack.config.js:

module.exports = {
     
    // entry: './main.js',
    entry: {
     
        'main': './main.js'
    },
    output: {
     
        'filename': './bundle.js'
    },
    watch: true,
    mode: 'development',
    module: {
     
        rules: [
            {
     
                /**
                 * 遇到后缀是css的文件,webpack首先用css-loader加载器去解析这个文件
                 * 最后计算完的css,将会使用style-loader生成一个内容为最终解释完的css代码的style标签,放在head标签里
                 * webpack在打包国城中,遇到后缀为css的文件,就会使用style-loader和css-loader去加载这个文件
                 */
                test: /\.css$/, // 后缀是css的文件
                loader: 'style-loader!css-loader', // 先去使用css-loader解析css文件再使用style-loader生成style标签(link)插入head标签中
            }
        ]
    }
}

这个时候css就会被加入到html中。

17. webpack中plugin的使用

一般也会把 index.html 文件自动生成到 dist 文件中,所以需要使用到 html-webpack-plugin 插件。安装该插件:$ cnpm i html-webpack-plugin -D,指定版本需要加上@跟版本号。另外一个命令是 $ cnpm i html-webpack-plugin --save-dev。还需要在 webpack.config.js 进行配置:

const path = require('path')
// 导入模块
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
     
    // entry: './main.js',
    entry: {
     
        // 可以有多个入口,也可以有一个,如果有一个默认从这个入口开始分析
        'main': './src/main.js'
    },
    output: {
     
        // 指定产出目录
        path: path.resolve('./dist'), // 相对转绝对路径,dist也可以改成static,webpack默认使用dist
        'filename': 'build.js'
    },
    watch: true, // 文件监视改动,自动产生build.js
    mode: 'development',
    module: {
     
        rules: [
            {
     
                /**
                 * 遇到后缀是css的文件,webpack首先用css-loader加载器去解析这个文件
                 * 最后计算完的css,将会使用style-loader生成一个内容为最终解释完的css代码的style标签,放在head标签里
                 * webpack在打包国城中,遇到后缀为css的文件,就会使用style-loader和css-loader去加载这个文件
                 */
                test: /\.css$/, // 后缀是css的文件
                use: ["style-loader", 'css-loader',], // 先去使用css-loader解析css文件再使用style-loader生成style标签(link)插入head标签中
            }
        ]
    },
    // 添加插件
    plugins: [
        new HtmlWebpackPlugin({
     
            // 插件的执行运行与元素索引有关
            template: './src/index.html', //参照物
        })
    ]
}

生成之前的项目目录结构:
Vue基础教程深入篇_第17张图片
执行 $ npm run dev 执行生成之后的目录结构:
Vue基础教程深入篇_第18张图片

index.html:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>webpack中plugin的使用title>
head>
<body>
<div id="app">div>
<script src="build.js">script>
body>

<script src="dist/build.js">script>
html>
18. 单文件的使用

使用 $ cnpm i vue-loader vue-template-compiler -D 下载用于解析 Vue文件的包 vue-loadervue-template-compiler。创建 App.vue 文件:

<!--组件的模板结构-->
<template>
  <div>
   App组件
  </div>
</template>
<!--组件的业务逻辑-->
<script>
export default {
     
  name:'App',
  data() {
     
    return {
     
      text: 'Hello fingle file...'
    }
  }
}
</script>
<!--组件的样式-->
<style>
body {
     
  background-color: rebeccapurple;
}
</style>

需要在 webpack.config.js 中进行配置:

const path = require('path')
// 导入模块
const HtmlWebpackPlugin = require('html-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin');
module.exports = {
     
    // entry: './main.js',
    entry: {
     
        // 可以有多个入口,也可以有一个,如果有一个默认从这个入口开始分析
        'main': './src/main.js'
    },
    output: {
     
        // 指定产出目录
        path: path.resolve('./dist'), // 相对转绝对路径,dist也可以改成static,webpack默认使用dist
        'filename': 'build.js'
    },
    watch: true, // 文件监视改动,自动产生build.js
    mode: 'development',
    module: {
      // 这个节点用于配置所有的第三方模块加载器
        rules: [
            {
     
                /**
                 * 遇到后缀是css的文件,webpack首先用css-loader加载器去解析这个文件
                 * 最后计算完的css,将会使用style-loader生成一个内容为最终解释完的css代码的style标签,放在head标签里
                 * webpack在打包国城中,遇到后缀为css的文件,就会使用style-loader和css-loader去加载这个文件
                 */
                test: /\.css$/, // 后缀是css的文件
                use: ["style-loader", 'css-loader',], // 先去使用css-loader解析css文件再使用style-loader生成style标签(link)插入head标签中
            },
            {
     
                test: /\.vue$/,
                use: 'vue-loader'
            }
        ]
    },
    // 添加插件
    plugins: [
        new HtmlWebpackPlugin({
     
            // 插件的执行运行与元素索引有关
            template: './index.html', //参照物
        }),
        new VueLoaderPlugin()
    ]
}

还要记得修改 main.js:

import Vue from './vue'
import App from './App.vue'
import './index.css'
let vm = new Vue({
     
    el: '#app',
    template: ``,
    components: {
     
        App
    }
})

执行 $ npm run dev 命令正常打包即可!

19. 单页面SPA应用

使用 $ cnpm i vue vue-router -S 安装 vuevue-router 模块,-S 表示当前项目依赖,查看 package.json:

{
     
  "name": "webpack_use",
  "version": "1.0.0",
  "description": "",
  "main": "src/main.js",
  "scripts": {
     
    "dev": "webpack --mode development",
    "build": "webpack --mode production"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
     
    "css-loader": "^4.2.1",
    "html-webpack-plugin": "^4.3.0",
    "style-loader": "^1.2.1",
    "vue-loader": "^15.9.3",
    "vue-template-compiler": "^2.6.12",
    "webpack": "^4.44.1",
    "webpack-cli": "^3.3.12"
  },
  "dependencies": {
     
    "vue": "^2.6.12",
    "vue-router": "^3.4.3"
  }
}

配置路由:main.js

import Vue from './vue'
import App from './App.vue'
import './index.css'
import VueRouter from 'vue-router'
import Home from './components/Home/Home'
import Course from './components/Course/Course'

//创建路由对象
const router = new VueRouter({
     
    // 配置路由信息
    routers: [
        {
     
            path: '/',
            name: 'Home',
            component: Home
        },
        {
     
            path: '/course',
            name: 'Course',
            component: Course
        },
    ]
})
let vm = new Vue({
     
    el: '#app',
    router: router,
    template: `
      `,
    components: {
     
        App
    }
})

常用配置相关参数:

--open:自动打开浏览器
--hot:热更新,不在刷新的情况下替换css样式
--inline:自动刷新
--port 9000:指定端口
--process:显示编译进度

希望可以在服务器上运行,下载模块:$ cnpm i webpack-dev-server --save-dev,查看 package.json:

{
     
  "name": "webpack_use",
  "version": "1.0.0",
  "description": "",
  "main": "src/main.js",
  "scripts": {
     
    "dev": "webpack-dev-server --open --hot --inline --config ./webpack.config.js",
    "build": "webpack --mode production"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
     
    "css-loader": "^4.2.1",
    "html-webpack-plugin": "^4.3.0",
    "style-loader": "^1.2.1",
    "vue-loader": "^15.9.3",
    "vue-template-compiler": "^2.6.12",
    "webpack": "^4.44.1",
    "webpack-cli": "^3.3.12",
    "webpack-dev-server": "^3.11.0"
  },
  "dependencies": {
     
    "vue": "^2.6.12",
    "vue-router": "^3.4.3"
  }
}

然后执行 $ npm run dev,自动打开了浏览器但是编译脚本报错:
Vue基础教程深入篇_第19张图片
Vue基础教程深入篇_第20张图片
找不到模块,Course.vue 和 Home.vue,排查后发现之前声明组件的时候 Home.vueCourse.vue 书写有误,修改 main.js:

import Vue from './vue'
// 一定要以vue结尾
import App from './App.vue'
import './index.css'
import VueRouter from 'vue-router'
// 如果基于模块化机制:Vue.use(VueRouter)
// 声明组件
import Home from './components/Home/Home.vue'
import Course from './components/Course/Course.vue'
//创建路由对象
const router = new VueRouter({
     
    // 配置路由信息
    routers: [
        {
     
            path: '/',
            name: 'Home',
            component: Home
        },
        {
     
            path: '/course',
            name: 'Course',
            component: Course
        },
    ]
})
let vm = new Vue({
     
    el: '#app',
    router: router,
    template: `
      
    `,
    components: {
     
        App
    }
})

这个时候就可以正常编译了,编译后遇到下面的问题:
Vue基础教程深入篇_第21张图片
Vue基础教程深入篇_第22张图片
需要在 main.js 中加上 Vue.use(VueRouter)

import Vue from './vue'
// 一定要以vue结尾
import App from './App.vue'
import './index.css'
import VueRouter from 'vue-router'
// 基于模块化机制
Vue.use(VueRouter)
// 声明组件
import Home from './components/Home/Home.vue'
import Course from './components/Course/Course.vue'
//创建路由对象
const router = new VueRouter({
     
    // 配置路由信息
    routers: [
        {
     
            path: '/',
            name: 'Home',
            component: Home
        },
        {
     
            path: '/course',
            name: 'Course',
            component: Course
        },
    ]
})
let vm = new Vue({
     
    el: '#app',
    router: router,
    template: ``,
    components: {
     
        App
    }
})

这里可以把 main.js 中的Vue的部分修改为:

let vm = new Vue({
     
    el: '#app',
    router: router,
    render: c => c(App)
    // template: ``,
    // components: {
     
    //     App
    // }
})

在这里插入图片描述
在这里插入图片描述
Githubhttps://github.com/ThanlonSmith/SPA-Vue

20. css中scoped的使用

scoped可以使当前样式只在当前组件生效,如,

Course.vue:

<template>
  <div>
    课程列表!
  </div>
</template>
<!--组件的业务逻辑-->
<script>
export default {
     
  name: 'Course',
  data() {
     
    return {
     }
  },
}
</script>
<!--组件的样式-->
<style scoped>
* {
     
  color: orange;
}
</style>

Home.vue:

<template>
  <div>
    首页!
  </div>
</template>
<!--组件的业务逻辑-->
<script>
export default {
     
  name: 'Home',
  data() {
     
    return {
     }
  },
}
</script>
<!--组件的样式-->
<style scoped>
*{
     
  color: red;
}
</style>

在这里插入图片描述
在这里插入图片描述

class重复也是没有关系的!

21. vue-cli的使用

可使用的模块有:

  • webpack:一个功能齐全的 webpack + vue-loader 设置,具有热重载、linting、测试和css提取功能
  • webpack-simple:一个简单的 Webpack + vue-loader 设置,用于快速设计原型
  • browserify:全功能 browserify + vueify 设置,具有热重载,linting和单元测试功能
  • browserify-simple:一个简单的 browserify + vueify 设置,用于快速原型设计
  • pwa:基于 webpack 模板的 vue-cli 的 pwa 模板
  • simple:单个 html 文件中最简单的 Vue 设置
  • progress:滚动

使用脚手架创建一个基于 webpack-simple 模块的项目:

$ vue init webpack-simple my-project

? Project name my-project
? Project description A Vue.js project
? Author erics1996 <erics1996@yeah.net>
? License MIT
? Use sass? No

进入目录,安装需要的相关依赖包:

$ cd my-project
$ cnpm install
$ npm run dev

Vue基础教程深入篇_第23张图片
Vue基础教程深入篇_第24张图片
Vue基础教程深入篇_第25张图片

Vue基础教程深入篇_第26张图片
使用 $ cnpm i vue-router 下载路由,可以在src目录下创建router文件夹和index.js用来写路由相关信息:
Vue基础教程深入篇_第27张图片
将路由对象VueRouter 挂在到 Vue 实例,main.js:

import Vue from 'vue'
import App from './App.vue'
import router from './router/index.js' // 可以不用加js后缀,路由相关的信息在index.js中写

new Vue({
     
  router,
  el: '#app',
  render: h => h(App)
})

创建router目录用于存放路由相关的信息,创建componets用来存放组件:
Vue基础教程深入篇_第28张图片
index.js:

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from "../components/Home/Home";
import Course from "../components/Course/Course";

Vue.use(VueRouter) // use相当于挂在父类
const router = new VueRouter({
     
  // 配置路由信息
  routes: [ // 这里不要写错了
    {
     
      path: '/',
      redirect: '/home'
    },
    {
     
      path: '/home',
      name: 'Home',
      component: Home
    },
    {
     
      path: '/course',
      name: 'Course',
      component: Course
    },
  ]
})
export default router

Home.vue:

<template>
  <div>我是首页!</div>
</template>
<script>
export default {
     
  name: 'Home',
  data() {
     
    return {
     }
  },
}
</script>
<style></style>

Course.vue:

<template>
  <div>我是课程列表页面!</div>
</template>
<script>
export default {
     
  name: 'Course',
  data() {
     
    return {
     }
  },
}
</script>
<style></style>

App.vue:

<template>
  <!--  <div id="app">-->
  <!--    <img src="./assets/logo.png">-->
  <!--    <h1>{
     {
      msg }}</h1>-->
  <!--    <h2>Essential Links</h2>-->
  <!--    <ul>-->
  <!--      <li><a href="https://vuejs.org" target="_blank">Core Docs</a></li>-->
  <!--      <li><a href="https://forum.vuejs.org" target="_blank">Forum</a></li>-->
  <!--      <li><a href="https://chat.vuejs.org" target="_blank">Community Chat</a></li>-->
  <!--      <li><a href="https://twitter.com/vuejs" target="_blank">Twitter</a></li>-->
  <!--    </ul>-->
  <!--    <h2>Ecosystem</h2>-->
  <!--    <ul>-->
  <!--      <li><a href="http://router.vuejs.org/" target="_blank">vue-router</a></li>-->
  <!--      <li><a href="http://vuex.vuejs.org/" target="_blank">vuex</a></li>-->
  <!--      <li><a href="http://vue-loader.vuejs.org/" target="_blank">vue-loader</a></li>-->
  <!--      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank">awesome-vue</a></li>-->
  <!--    </ul>-->
  <!--  </div>-->
  <div id="app">
    <img src="./assets/logo.png">
    <h4>{
     {
      msg }}</h4>
    <router-link :to="{name:'Home'}">首页</router-link>
    <router-link :to="{name:'Course'}">课程</router-link>
    <router-view></router-view>
  </div>
</template>

<script>
export default {
     
  name: 'app',
  data() {
     
    return {
     
      msg: '基于webpack-simple模板构建!'
    }
  }
}
</script>
<style></style>

Vue基础教程深入篇_第29张图片
Vue基础教程深入篇_第30张图片
使用 webpack 模板来创建一个工程,

在这里插入图片描述
Vue基础教程深入篇_第31张图片
构建好的**工程目录结构:
Vue基础教程深入篇_第32张图片
同样使用 $ npm run dev 命令来运行:
Vue基础教程深入篇_第33张图片
默认找 index.js,可以不写后缀:

Vue基础教程深入篇_第34张图片
Vue.config.productionTip = false 的意思是生产环境不需要控制台有提示,@符号默认是 src 路径。
Vue基础教程深入篇_第35张图片

Vue基础教程深入篇_第36张图片

22. element-ui的使用

使用 $ cnpm i element-ui -S 安装 element-ui,使用 $ cnpm i 安装 element-ui 依赖的包,使用 element-ui 来布局 App.vue:

<template>
  <div id="app">
    <el-container>
      <el-header>
        <router-link :to="{name:'Home'}">首页</router-link>
        <router-link :to="{name:'Course',query:{userid:1}}">免费课程</router-link>
      </el-header>
      <el-main>
        <router-view/>
      </el-main>
    </el-container>
  </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>

main.js:

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router' // 默认找index.js
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import '../static/global/index.css'

Vue.config.productionTip = false // 生产环境不需要控制台有提示
Vue.use(ElementUI)
/* eslint-disable no-new */
new Vue({
     
  el: '#app',
  router,
  components: {
     App},
  template: ''
})

在这里插入图片描述
在这里插入图片描述

你可能感兴趣的:(Vue,vue,vue.js,nodejs,webpack,element-ui)