【Vue】三


Vue组件

非单文件组件

一个文件包含多个组件

单文件组件

一个文件只包含一个组件,vue文件初始化:vueInit




template写组件的结构,script中写组件的交互(数据、方法等),style写组件的样式




三种组件暴露方式

①分别暴露

    export const book = Vue.extend({
        data() {
            return {
                BookName: 'ABC Muder',
                BookAuthor: '阿加莎克里斯蒂'
            }
        },
        methods: {
            alterBookName() {
                alert(this.BookName)
            }
        }
    })

②统一暴露

    const Book = Vue.extend({
        data() {
            return {
                BookName: 'ABC Muder',
                BookAuthor: '阿加莎克里斯蒂'
            }
        },
        methods: {
            alterBookName() {
                alert(this.BookName)
            }
        }
    })
    export {Book}

③默认暴露

    export default{
        name: 'Book',
        data() {
            return {
                BookName: 'ABC Muder',
                BookAuthor: '阿加莎克里斯蒂'
            }
        },
        methods: {
            alterBookName() {
                alert(this.BookName)
            }
        }
    }

默认暴露使用最多,可以直接将组件配置暴露出来,并且在被import导入的时候不必写{{}}

App.vue 用于管理所有的组件




main.js 用于管理App.vue并创建vm




index.html




    
    
    
    Document


    

main.js要在容器声明之后引入,vue.js要在main.js声明之前引入

上面的内容es6语法import浏览器是不能识别的,需要引入脚手架进行翻译

Vue CLI

CLI:command line interface,命令行接口工具

vue create xxx

render模板渲染函数

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

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

为什么要设计render函数

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

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')
[Vue warn]: 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.

如提示,由于Vue设计,当使用ES6的引入方式时,引入的Vue是不含有模板解析(即解析template)的vue.js,解决方法有两种:

①引入完整版的Vue

import Vue from 'vue/dist/vue'

②使用render函数

new Vue({
  // render: h => h(App),
  render(createElement) {
    return createElement(App)
  }
}).$mount('#app')

改写为箭头函数:

new Vue({
  // render: h => h(App),
  render: h => h(App)
}).$mount('#app')

标签内的template是有专门的vue模板编译器解析,但是main.js必须由render函数解析

ref属性




1.被用来给元素和子组件注册引用信息 (id的替代者)

2.应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(VueComponent)

3.使用方法

打标识:

获取:this.$refs.xxx

props属性:让组件接收外部传来的数据

(1)传递数据

    
    

(2)接收数据

①简单接收

props:['BookName', 'BookAuthor', 'BookPrice']

②限制类型和空接收

    export default{
        name: 'Book',
        data() {
            return {
                BookPress: '新星出版社',
                // BookName: this.BookName,
                // BookAuthor: this.BookAuthor,
                // BookPrice: this.BookPrice
            }
        },
        props: {
            BookName: {
                type: String,
                required: true 
            },
            BookAuthor: {
                type: String,
                required: true 
            },
            BookPrice: {
                type: Number,
                required: true 
            }  
        }
    }

如此,外来数据与props类型不一致时就会报错

需求分析:实现对外来数据BookPrice的自增

问题

1. 直接对插值语法中的数据{{BookPrice+1}}的话会出现错误,原因是这里将BookPrice视作了字符串,+1操作会进行字符串拼接

2. 接收数据组件不允许对外来数据进行修改

解决方法

1. 在外来数据传入时使用v-bind,这样“”中的数字就会被当作js表达式,最后被视作number类型而不是字符串



2. 通过组件的this指针,将外来数据的值赋值给data

        data() {
            return {
                BookPress: '新星出版社',
                Name: this.BookName,
                Author: this.BookAuthor,
                Price: this.BookPrice
            }
        },

mixin 混入:把多个组件公用的配置提取成一个混入对象

(1)定义混入mixin.js

export const mixin = {
    methods: {
        AddPrice() {
            this.Price++;
        }
    } 
}

可以配置组件的所有属性(data、方法甚至mounted),除了mounted,冲突时其他优先级均低于组件中的属性

(2)使用混入

全局混入:Vue.mixin(xxx)

局部混入:mixins: [xxx, xxx]

原始方法实现组件间通信

App.vue






Myheader.vue




list.vue




Myitem.vue




Myfooter.vue




☆使用自定义组件事件实现App和Item跨组件通信

App.vue






由于App和MyItem中间隔着一个Mylist,所以能够实现两个组件的通信重点是以下代码

          
    mounted() {
      let items = this.$refs.list.$refs.item
      items.forEach(item => {
        item.$on('checkTodo', this.checkTodo)
        item.$on('deleteOne', this.deleteOne)
      });
    }

MyItem.vue




使用全局事件总线实现App与MyItem的通信

App.vue

    mounted() {
      this.bus.$on('checkTodo', this.checkTodo)
      this.bus.$on('deleteOne', this.deleteOne)
    }

MyItem.vue

    export default {
        name: 'Myitem',
        props:['todo'],
        methods: {
            handleCheck(id) {
                this.bus.$emit('checkTodo', id)
            },
            handleDelete(id) {
                if(confirm("确定删除吗")) {
                    this.bus.$emit('deleteOne', id)
                }
            }
        }
    }

Vue插件

(1)创建插件配置文件 plugins.js

export default {
    install(Vue) {
        Vue.filter('mySlice', function(val) {
            return val.slice(0, 3)
        })
    }
}

可以定义过滤器、自定义指令以及混入

(2)在main.js中引入并使用插件

import plugins from './plugins'
Vue.use(plugins)

(3)在组件中使用插件中的过滤器

BookAuthor:{{Author | mySlice}}


scoped样式

使得css样式只能在此组件中使用

路由简介

路由的基本使用

1 安装路由

npm i vue-router

2 在Vue入口文件main.js中导入并使用路由插件

import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import router from './router'

Vue.config.productionTip = false
Vue.use(VueRouter)

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

导入VueRouter的目的是为了在new Vue中使用router属性

导入的router为自定义的路由index.js配置文件

3 配置路由index.js文件

import VueRouter from 'vue-router' 
import Hello from '../components/Hello'
import Welcome from '../components/Welcome'

export default new VueRouter ({
    routes: [
        {
            path: '/Hello',
            component: Hello
        },
        {
            path: '/Welcome',
            component: Welcome
        }
    ]
})

注意这里是routes(多个路由)而不是routers(多个路由器)

4 在组件中使用路由

Welcome Hello

router-link 可被渲染为a标签,用于实现路由的切换

router-view用于指定路由指向的组件的呈现位置

路由组件和一般组件

1 路由组件一般放在pages,一般组件放在components

2 通过切换,‘隐藏’了的路由组件,默认是被销毁了的,需要的时候再去挂载

3 每个组件都有着自己的$route属性,存储着自己的路由信息

4 整个应用只有一个路由器,可以用组件的$router属性获取

嵌套路由

移动端UI组件库

1 Vant

2 Cube UI

3 Mint UI

PC端UI组件库

1 ElementUI

2 IViewUI

安装
npm i element-ui -S
在main.js中引用注册elementUI
import Vue from 'vue'
import App from './App.vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

Vue.config.productionTip = false
Vue.use(ElementUI)

new Vue({
  render: h => h(App),
}).$mount('#app')
按需引入

借助 babel-plugin-component,我们可以只引入需要的组件,以达到减小项目体积的目的。

首先,安装 babel-plugin-component:

npm install babel-plugin-component -D

然后,将babel.config.js 修改为:

module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset',
    ["@babel/preset-env", { "modules": false }],
  ],
  plugins: [
    [
      "component",
      {
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ]
  ]
}

修改main.js

import Vue from 'vue'
import App from './App.vue'
import {carousel, CarouselItem} from 'element-ui'

Vue.config.productionTip = false
Vue.component(carousel.name, carousel)
Vue.component(CarouselItem.name, CarouselItem)

new Vue({
  render: h => h(App),
}).$mount('#app')
vue