Vue07-脚手架+ref+props+插件+scoped

 


Vue07-脚手架+ref+props+插件+scoped

1.脚手架-脚手架简介

  1. Vue脚手架是Vue官方提供的标准化开发工具,最新的版本是5.x。
  2. Vue脚手架官方文档地址,文档: https://cli.vuejs.org/zh/
  3. Vue脚手架也称为Vue CLI,CLI表示command line interface

2.脚手架-脚手架的安装

  1. 按照nodejs。
    1. nodejs官网地址,http://nodejs.cn/download/
    2. 在官网下载node-v16.17.0-x64.msi,然后直接下一步安装。
  2. 配置淘宝镜像,npm config set registry https://registry.npm.taobao.org
  3. 如果是第一次安装,则需要全局安装@vue/cli,npm install -g @vue/cli
  4. 使用命令创建项目,vue create xxx
  5. 常用的npm命令。
npm run serve # 启动项目。
npm run build # 将vue项目构建为html、css和js文件。
npm run lint # 语法检查。

npm view webpack versions # 查看webpack所有的版本
npm view less-loader versions # 查看less-loader版本。
npm i less-loader # 安装less-loader,安装之后style中就可以使用lang="less"。
npm i less-loader@9,安装less-loader中9版本的最高版本。

3.脚手架-脚手架包目录结构分析

  1. babel.config.js将ES6语法转换为ES5语法,保证浏览器的兼容性。
  2. src/main.js是整个项目的入口文件。
  3. src/assets中存放项目中静态资源文件。
  4. src/components中存储程序员开发的组件。
  5. public文件夹中存放图标和index.html。
  6. public/index.html就是vue的首页。
  7. vue.config.js中可以配置vue脚手架的一些设置。

4.脚手架-脚手架的默认配置

  1. vue默认将脚手架的配置隐藏了。如果想查看,可以使用命令vue inspect > output.js将脚手架的配置导出为output.js文件。
  2. https://cli.vuejs.org/zh/config/#vue-config-js,中可以查看脚手架中可以修改的配置。
  3. 修改vue脚手架配置的方式,在vue.config.js中覆盖需要修改的属性。
module.exports = defineConfig({
    transpileDependencies: true,
    lintOnSave: false, // 关闭语法检查。
    // pages配置可以修改程序的入口JavaScript文件。
    pages: {
        index: {
            entry: 'src/main.js'
        }
    }
})

5.ref标识元素或者组件

  1. ref属性被用来给元素或者子组件注册引用信息,即ref是id的替代者。
  2. 如果ref应用在html标签上获取的是真实的DOM元素,应用在组件标签上获取的是组件实例对象vc(VueCompontent)。
  3. ref的使用方式。
1 给元素或者组件打标识。如<h1 ref="xxx"></h1>或者<School ref="xxx"></School>。
2 通过ref获取元素或者组件实例对象,this.$refs.xxx。
  1. ref案例。

    1. App.vue。
    <template>
        <div>
            <School/>
            <School/>
            <School/>
    
            <h2 id="ref01">{{msg}}</h2>
            <h2 ref="ref02">{{msg}} -- 02</h2>
            <button @click="get01">获取html元素</button>
    
            <School id="ref03"/>
            <School ref="ref04"/>
            <button @click="get02">获取组件</button>
        </div>
    </template>
    
    <script>
        import School from './components/School'
    
        export default {
            name: "App",
            data() {
                return {
                    msg: 'hello'
                }
            },
            methods: {
                get01() {
                    // 通过原生JavaScript获取元素。
                    // <h2 id="ref01">hello</h2>
                    console.log(document.getElementById('ref01'));
    
                    // 通过ref获取元素,获取的是元素的真实DOM。
                    // <h2>hello</h2>
                    console.log(this.$refs.ref02);
                },
                get02() {
                    /*
                    通过id获取组件,获取的是组件的DOM结构。
                    <div data-v-3375b0b8 class="demo">
                        <p data-v-3375b0b8>学校名 A01</p>
                        <p data-v-3375b0b8 >学校地址 北京</p>
                    </div>
                     */
                    console.log(document.getElementById('ref03'));
    
                    // 通过ref获取组件,获取的是组件的实例对象vc(VueComponent)
                    console.log(this.$refs.ref04); //
                }
            },
            components: {
                School
            }
        }
    </script>
    
    1. School.vue。
    <template>
        <div class="demo">
        <p>学校名 {{name}}</p>
        <p>学校地址 {{address}}</p>
    </div>
    </template>
    
    <script>
        export default {
            name: "School",
            data() {
                return {
                    name: 'A01',
                    address: '北京',
                }
            }
        }
    </script>
    
    <style scoped>
        .demo {
            background-color: orange;
        }
    </style>
    

6.props父子组件间数据传递

  1. props用来实现父子组件间数据的传递。
  2. props在父组件中发送数据的两种方式。
<!-- 传递方式一,使用name="tom"直接将"tom"当做字符串传递给Student组件。 -->
<Student name="tom"/>

<!-- 传递方式二,:age,是v-bind:age的简写,:age会将值会被作为JavaScript表达式处理。 -->
<Student :age="20"/>
  1. props在子组件中接受数据的两种方式。
<!-- 子组件中props为数组类型。 -->
props: ['name', 'address', 'age']

<!-- 子组件中props为对象类型,可以对接受到的数据进行限制。 -->
props: {
    name: {
        type: String,
        require: true,
    },
    age: {
        type: Number,
        require: false,
        default: 100
    },
    address: {
    	type: String
    }
}
  1. props是只读的,Vue底层会监视对props的修改,如果对props进行了修改,就会发出警告。所以如果业务需求确实需要修改,可以复制props内容到data中,然后修改data中的数据。

  2. props传递数据案例。

    1. App.vue。
    <template>
        <div>
            <!-- name="tom"直接将"tom"当做字符串传递给Student组件。 -->
            <!-- :age,是v-bind:age的简写,:age会将值作为JavaScript表达式处理。 -->
            <Student name="tom" :age="20" address="北京"/>
            <hr>
            <Student name="alice" address="北京"/>
            <hr>
            <Student name="bob" address="北京"/>
    
            <!-- 传递参数的key不能随便随便定义,如key和ref都不可以使用。 -->
            <!--<Student name="bob" address="北京" key="key" ref="ref"/>-->
        </div>
    </template>
    
    <script>
        import Student from './components/Student'
    
        export default {
            name: "App",
            components: {
                Student
            }
        }
    </script>
    
    1. Student.vue。
    <template>
        <div>
            <p>{{msg}}</p>
            <p>学生名 {{myName}}</p>
            <p>学生地址 {{address}}</p>
            <p>学生年龄 {{age}}</p>
            <button @click="updateName02">更新姓名</button>
        </div>
    </template>
    
    <script>
        export default {
            name: "Student",
            data() {
                return {
                    msg: '我是一个学生',
                    // 如果想要修改组件props接受的值,可以将props的值赋给data返回值。
                    // 组件初始化时会先执行props中的逻辑,所以这里可以拿到name值。
                    myName: this.name,
                }
            },
            methods: {
                // 接受的参数是需要避免修改的,修改时会报错。
                // Avoid mutating a prop directly since the value will be overwritten whenever the parent component
                // re-renders. Instead, use a data or computed property based on the prop's value.
                // Prop being mutated: "name"
                updateName01() {
                    this.name = 'lisi';
                },
                updateName02() {
                    this.myName = 'lisi';
                }
            },
            props: ['name', 'address', 'age'] // props接受参数简写
    
            // props接受参数是限制类型。
            // props: {
            //     name: String,
            //     address: String,
            //     age: Number,
            // }
    
            // props参数限制:类型限制、必填限制和指定默认值。
            // props: {
            //     name: {
            //         type: String,
            //         require: true,
            //     },
            //     age: {
            //         type: Number,
            //         require: false,
            //         default: 100
            //     },
            //     address: {
            //         type: String
            //     }
            // }
        }
    </script>
    

7.mixin混合混入

  1. mixin混入(混合)的作用:可以将多个组件通用的代码提取为混合mixin.js。
  2. 混合的定义和使用。
// 1 定义混合。mixin.js定义并导出。
export const mixin = {
    data() {
        return {
            x: 100
        }
    },
    methods: {}
}

// 2 混合的使用。
// 2-1 全局使用。main.js中引入并全局使用。
import {mixin} from "./mixin";
// 全局引入混合,全局引入后所有的组件都可以使用。
Vue.mixin(mixin);

// 2-2 局部使用。
import {mixin} from "../mixin";
export default {
    name: "School",
    mixins: [mixin]
}
  1. 当混合中定义的函数和组件中的函数冲突时的处理方式。

    1. 如果是data或者methods中的属性发生了冲突,就使用组件中定义的属性。
    2. 如果在混合和组中都定义了相同的vue生命周期函数,则混合和组件中的声明周期函数都会执行。
  2. mixin混合案例。

    1. mixin.js和main.js。
    // mixin.js。当js中有多个对象需要导出时的导出方式,分别进行导出。
    export const mixin = {
        methods: {
            showName() {
                alert(this.name);
            }
        },
        mounted() {
            console.log('混合中的mounted')
        }
    };
    export const data01 = {
        data() {
            return {
                x: 100
            }
        }
    }
    
    // main.js中全局混合。
    import Vue from 'vue'
    import App from './App'
    
    import {mixin, data01} from "./mixin";
    
    // 全局引入混合。
    Vue.mixin(mixin);
    Vue.mixin(data01);
    
    new Vue({
        el: '#app',
        render: h => h(App)
    })
    
    1. School.vue。
    <template>
        <div>
            <p>{{msg}}</p>
            <p @click="showName">学校名 {{name}}</p>
            <p>学校地址 {{address}}</p>
        </div>
    </template>
    
    <script>
        // 引入混合
        import {mixin, data01} from "../mixin";
    
        export default {
            name: "School",
            data() {
                return {
                    msg: '学校信息',
                    name: '学校名',
                    address: '学校',
                    // 当引入的混合和组件data中都有x属性,会使用组件中的x属性的值。
                    x: 999
                }
            },
            // 如果混合和组件中都定义了相同的vue声明周期函数,则在vue初始化时混合和组件中的函数都执行。
            mounted() {
                console.log('组件中的mounted')
            }
            mixins: [mixin, data01]
        }
    </script>
    

8.插件

  1. 插件的作用:插件用来增强vue。

  2. 插件本质是一个包含install方法的对象,install的第一个参数是Vue,第二个参数是插件使用者传递的参数。

  3. 插件的定义和使用。

    1. 插件的定义。
    install(Vue, x, y, z) {
    }
    
    1. 插件的使用。
    // main.js中导入插件
    import plugins from './plugins'
    // 使用插件
    Vue.use(plugins, 1, 2, 3);
    
  4. 插件案例。

    1. plugins.js和main.js。
    // plugins.js
    export default {
        /*
        插件中的install函数会被调用,同时将创建Vue的函数传入。
        ƒ Vue(options) {
          if ( true && !(this instanceof Vue)) {
            warn('Vue is a constructor and should be called with the `new` keyword');
          }
    
          this._init(options);
        }
         */
    
        // install第一个参数是Vue。
        // install第二个参数及后面的参数都可以接受Vue.use()传递的参数。
        install(Vue, x, y, z) {
            console.log('插件', Vue);
            console.log(x, y, z); // 1 2 3
    
            // 插件中可以对Vue进行增加,可以定义一些全局的配置,如全局过滤器。
            Vue.filter('mySlice', function (value) {
                return value + '过滤器';
            });
    
            // 定义全局混入
            Vue.mixin({
                methods: {
                    showName() {
                        alert(this.name);
                    }
                },
            });
    
            // 插件可以在Vue的原型链上增加属性,这样组件的实例就可以使用了。
            Vue.prototype.demo = function () {
                console.log('Vue原型上的demo函数')
            }
        }
    }
    
    // main.js
    import Vue from 'vue'
    import App from './App'
    
    // 导入插件
    import plugins from './plugins'
    // 使用插件
    Vue.use(plugins, 1, 2, 3);
    
    new Vue({
        el: '#app',
        render: h => h(App)
    })
    
    1. School.vue。
    <template>
        <div>
            <p>{{msg}}</p>
            <!-- 使用插件中的全局混入 -->
            <p @click="showName">学校名 {{name}}</p>
            <!-- 使用插件中全局过滤器 -->
            <p>学校地址 {{address | mySlice}}</p>
        </div>
    </template>
    
    <script>
        export default {
            name: "School",
            data() {
                return {
                    msg: '学校信息',
                    name: '学校名',
                    address: '学校',
                }
            },
        }
    </script>
    

9.scoped

  1. scoped可以让样式在组件局部生效,防止样式命名冲突。
  2. scoped案例,School.vue。
<template>
    <div class="bg">
        <p>{{msg}}</p>
        <p>学校名 {{name}}</p>
        <p>学校地址 {{address}}</p>
    </div>
</template>

<script>
    export default {
        name: "School",
        data() {
            return {
                msg: '学校信息',
                name: '学校名',
                address: '学校',
            }
        },
    }
</script>

<!--
    1 在组件内定义CSS时,vue脚手架会将所有组件内的CSS汇总到一个CSS文件中,
    如果两个组件有相同名称的样式,最先引入的组件的样式就会被覆盖。
    可以在style中加scoped,来解决这个问题。

    2 style中加scoped解决多个组件样式命名冲突问题的本质是,在打包时会给每个组件
    分配一个独立的值,data-v-22321ebb。

    CSS样式为 .bg[data-v-22321ebb]
    HTML元素为 <div data-v-22321ebb class="bg"></div>
-->

<!--
    lang属性用来定义css的编写方式,有两种编写方法,
    css,传统的css。
    less,需要使用web引入less-loader。
-->
<style scoped lang="css">
    .bg {
        background-color: orange;
    }
</style>
posted @   行稳致远方  阅读(40)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示