zoukankan      html  css  js  c++  java
  • js原型, Vue项目环境搭建, Vue项目目录结构, Vue项目生命周期, 小组件使用, 全局样式, 路由跳转, 组件的生命周期钩子, 路由传参

    习题详解

    i) 有两个大标题,电视和手机,点击对应的标题,渲染对应的数据
    ii) 一个字典作为一个显示单位,定义一个子组件进行渲染(涉及父子组件传参)

    3、在第2题基础上,页面最下方有一个 h2 标签,用来渲染用户当前选择的广告(点击哪个广告就是选中哪个广告)
    i)当没有点击任何广告,h2 标签显示:未选中任何广告
    ii)当点击其中一个广告,如tv1,h2 标签显示:tv1被选中

    '''
            <button @click="select = 'tv'" :class="{active: select === 'tv'}">tv</button>
            ...
            
        <div class="wrap" v-if="select === 'tv'">
            <tag v-for="tv in ad_data.tv" :xxx="tv" :key="tv.title" @yyy="choice"></tag>  # v-for指令需要给循环的标签或组件添加key属性设定主键索引缓存
        </div>
        ...
        
        <div class="nav"><h2>{{selectContent}}</h2></div>
        
        
        let tag = {
            props: ['xxx'],
            template: `
          <div class="box" @click="fn(xxx.title)">
                <img :src="xxx.img" alt="">
                <h2>{{xxx.title}}</h2>
            </div>
          `,
            methods: {
                fn(m) {
                    this.$emit('yyy', m);
                },
            }
    
        };
        
        
        new Vue({
            ...
            components: {
                tag,
            },
            data: {
                ad_data,
                select: 'tv',
                selectContent: '未选中任何广告'
            },
            methods: {
                choice(a) {
                    if (a) {
                        this.selectContent = `${a}被选中`  # js语法中的模板字符串
                    }
                },
            },
        });
    '''
    

    js原型补充

    '''
        function A() {
        }
    
        let a1 = new A();
        console.log(a1.num);  // undefined
    
        A.prototype.num = 100;  // 为A类添加原型
        console.log(a1.num);  // 100
        
        // ES6定义类的语法
    	class B {
            constructor(name) {  // 构造器自定义对象属性
                this.name = name
            }
        }
        
    	let b1 = new B('蔡启龙');
    	console.log(b1.name);  // 蔡启龙
    	
    	// 推导
    	Vue.prototype.$ajax = ...  // 为所有Vue对象添加$ajax属性
    '''
    

    Vue项目环境搭建

    • vue: 类似于django
    • node: 类似于python
    • npm: 类似于pip
    '''
    let a = 1;
    undefined
    
    console.log(a);
    1
    undefined  // console.log函数无返回值, 所以多出一个undefined结果
    '''
    
    • 在系统环境中敲npm|pip可以查看npm|pip指令, 敲npm list|pip list可以查看npm或pip已安装过的包
    • 安装cnpm: 在系统环境中敲npm install -g cnpm --registry=https://registry.npm.taobao.org, cnpm是国内安装源
    • 安装脚手架: 在系统环境中敲cnpm install -g @vue/cli
    • 创建项目: 在系统环境中敲vue project my-projectvue u
    • 在创建选项中, 选择安装babel插件, 作用: JavaScript编译器, 将es6转成es5

    vue根据配置重新构建依赖

    1. 新建文件夹-->存放public文件夹, src文件夹, package.json文件

    2. 打开cmd, 输入执行: cnpm install, 会根据package.json文件重新构建依赖

    3. 如果后期缺少某个依赖, cd到项目所在目录手动安装, 例如cnpm install ajax

    4. 运行项目: cd到项目所在目录, 执行cnpm run serve

    5. src-->router-->index.js, 修改内容:

      '''
      ...
      import About from '../views/About.vue'
      
      ...
      
      const routes = [
        ...
        {
          ...
          component: () => About
        }
      ]
      
      ...
      '''
      

    pycharm管理vue项目

    Edit Configurations-->npm-->Scripts-->serve

    Vue项目目录介绍

    node_modules:

    • 当前项目所有依赖, 一般不可移植给其他电脑

    public:

    • favicon.ico: 图标
    • index.html: 项目唯一主页

    src:

    • assets: 资源文件夹, 一般建三个子文件夹: img, css, js
    • components: 小组件, 打开视图组件文件xxx.vue需要下载vue.js
    • views: 页面视图组件
    • router: 路由脚本
    • store: 仓库脚本
    • App.vue: 根视图组件
    • main.js: 全局脚本文件

    package.json: 主要的配置文件

    Vue项目生命周期

    资源导入说明

    main.js是整个项目的入口

    vue语法中的 import App from './App' , 类似于python中的 from './App' import xxx as App

    v-projsrcmain.js

    • import 别名 from 资源
      • 资源直接写名字时, 资源在node_modules文件夹中
      • 资源写路径时, 例如: './App.vue' , . 表示当前文件所在文件夹的路径,
      • 按路径导入资源时可以省略后缀, 例如:'./App.vue', 等价于 './App'

    生命周期流程

    1. 启动项目, 加载主脚本文件main.js
      • 加载vue环境, 创建根组件完成渲染
      • 加载系统已有的第三方环境: router, store
      • 加载自定义的第三方环境与自己配置的环境
    2. router被加载, 就会解析router文件夹下的index.js脚本文件, 完成路由---组件的映射关系
    3. 新建视图组件: v-projsrcviews-->xxx.vue,
    4. 在v-projsrc outerindex.js中配置视图组件,
    5. 设置路由跳转: <router-link to="/about">About</router-link>

    代码

    '''
    # v-projpublicindex.html
    ...
    <html lang="en">
      ...
      <body>
        ...
        <div id="my_app"></div>
        ...
      </body>
    </html>
    
    
    # v-projsrcmain.js
    import Vue from 'vue'  # 导入node_modules文件夹中的资源
    import App from './App'
    import router from './router'
    import store from './store'
    
    // 简写:
        new Vue({
          router,
          store,
          render: h => h(App)
        }).$mount('#my_app');  # 将根视图组件对应的数据渲染到publicindex.html对应的挂载点
    
    // 完整写法:  
        // new Vue({
        //     el: '#my_app',
        //     router: router,
        //     store: store,
        //     render: function (handle) {
        //         return handle(App);
        //     }
        // });
        
    
    # 在v-projsrcviews中新建User.vue视图组件
    <template>  # 视图组件通过routerindex.js中对应配置渲染到根视图组件中的<router-view/>时的标识
        <span>User页面</span>
    </template>
    ...
    
    
    # v-projsrc
    outerindex.js
    import Vue from 'vue'
    import VueRouter from 'vue-router'
    ...
    import User from '../views/User.vue'
    
    Vue.use(VueRouter);
    
    const routes = [
        ...,
        {
            path: '/user',
            ...
            ...
            component: User
        },
    
    ];
    
    const router = new VueRouter({
        routes
    });
    
    export default router
    
    
    # v-projsrcApp.vue
    <template>  # main.js中对应函数读取根视图数据并渲染到挂载点的标识
      <div id="xxx">  # 根视图组件必须有且仅有一个块级根标签
        ...
          <router-link to="/user">User</router-link>  # 设置路由跳转
        ...
        <router-view/>  # 页面视图组件在根组件中的渲染占位符, 通常为一个, 也可以为多个
      </div>
    </template>
    
    ...
    '''
    

    小组件的使用

    template标签负责组件的html结构, 有且只能有一个根标签

    script标签负责组件的js逻辑,

    • 组件需要要在script标签中通过vue语法导出外界才能导入使用该组件
    • 如果没有在script标签中通过vue语法导出, 则默认只加载页面HTML结构

    style标签负责组件的css样式, scoped参数控制样式的组件化, 使样式只在对应的组件内部起作用

    '''
    # v-projsrccomponentscomponent1.vue
    <template>
        <div><h1>小组件</h1></div>
    </template>
    
    <script>
        export default {
            data() {
                return {};
            },
            methods: {},
        }
    </script>
    
    <style scoped>
        h1 {
            color: red;
        }
    </style>
    
    
    # v-projsrcviewsHome2.vue
    <template>
        <div>
            <h1>Home页面组件</h1>
            <component1></component1>  # 页面组件中渲染小组件
        </div>
    </template>
    
    <script>
        import component1 from '../components/component1'  # 页面组件中导入小组件
    
        export default {
            components: {
                component1,  # 页面组件中注册小组件
            },
        }
    </script>
    
    <style scoped>
        h1 {
            color: aqua;
        }
    </style>
    '''
    

    配置自定义全局样式

    1. 在v-projsrcassets文件夹中新建css文件夹并新建css文件, 然后在该css文件中书写自定义的全局css样式
    2. 在main.js文件中导入全局css样式文件
    '''
    # v-projsrcassetscssglobal.css
    ul {
        list-style: none; /*去除无序列表项的小圆点*/
    }
    
    
    # day68v-projsrcmain.js
    
    // 配置全局样式
    import './assets/css/global.css'  // 只需加载文件时的导入方式
    
    // 其他配置方式:
    // import xxx from './assets/css/global.css'  // 要使用文件内容时的导入方式
    // import '@/assets/css/global.css'  // @代表src文件夹的绝对路径
    // require('@/assets/css/global.css');  // 官方推荐加载静态文件的方式, 可以用变量接收结果
    '''
    

    路由逻辑跳转

    导航栏组件及其样式: copy

    • <router-link> 通过 to 属性指定目标地址, 默认渲染成带有正确链接的 <a> 标签, 例如
      • <router-link to="/course">课程页</router-link>: <a href="#/course" class="">课程页</a>
    • 当目标路由成功激活时, 链接元素自动设置一个表示激活的 CSS 类名
      • class="router-link-exact-active router-link-active": router-link-exact-active是精确匹配规则, router-link-active是全包含匹配规则
    '''
    # Nav.vue
                    <li class="logo" @click="goHome"><img src="@/assets/img/lufei.svg" alt=""></li>
                    
                    <li class="route">
                        # <router-link to="/course">课程页</router-link>
                        <router-link :to="{name: 'course'}">课程页</router-link>  <!--类似于前端的反向解析-->
                    </li>
                    
    <script>
        export default {
            name: "Nav",  // 组件的名字
            methods: {
                goHome() {
                    // console.log(this.$router);  // VueRouter {…}, 控制路由跳转
                    // console.log(this.$route);  // {name: "home", ..., path: "/", ...}, 控制路由数据
                    if (this.$route.path !== '/') {  // 判断当前路由是否为home路由, 避免跳转重复路由报错
                        // this.$router.push('/');  
                        // this.$router.go(-1)  // go是历史记录前进后退, 正为前进, 负为后退, 数字为步数
                        this.$router.push({name: 'home'})
                    }
                },
            }
        }
    </script>
    
    
    # v-projsrc
    outerindex.js
    ...
    
    const routes = [
        {
            path: '/',
            name: 'home',  // 类似于反向解析中url的别名
            component: Home
        },
        ...
    ];
    
    ...
    '''
    

    路由重定向

    '''
    # v-projsrc
    outerindex.js
    ...
    
    const routes = [
        ...,
        {
            path: '/xxx',
            redirect: '/'
        },
    ];
    
    ...
    '''
    

    组件的生命周期钩子

    1. 一个组件从创建到销毁的过程中, 几个特殊的时间节点回调的方法
    2. 这些方法都是vue组件实例的成员
    '''
    # v-projsrcviewsHome.vue
    <script>
        export default {
            data() {
                return {
                    back_data: 'Owen',
                };
            },
            beforeCreate() {
                console.log('Home组件要被创建了...');
                console.log(this.back_data)  // undefined
            },
            created() {  // 在该钩子中完成前端对后端数据的请求
                console.log('Home组件创建成功!');
                console.log(this.back_data)  // Owen
            },
            beforeMount() {
                console.log('Home组件准备挂载...');
            },
            mounted() {  // 对于特别耗时的数据请求, 可以延后到组件初步加载成功后, 在该钩子中继续请求
                console.log('Home组件挂载完成!');
            },
            destroyed() {  // 应用场景: 离开页面时可以在该钩子中进行二次确认
                console.log('Home组件销毁成功了!');
            },
        }
    </script>
    '''
    

    路由传参

    Course.vue

    • 在created钩子中前端对后端数据的请求
    • 如果组件加载静态数据并将其当做参数传给其他组件使用, 需要用require方法
    '''
    # v-projsrcviewsCourse.vue
    <template>
        <div class="course">
            ...
                <CourseTag v-for="course in courses" :course="course"></CourseTag>
            ...
        </div>
    </template>
    
    <script>
        ...
        import CourseTag from '../components/CourseTag'
    
        export default {
            ...
            components: {
                ...
                CourseTag,
            },
            data() {
                return {
                    courses: [],
                };
            },
            created() {  // 在该钩子中完成前端对后端数据的请求
                // 前后端开发时从后端获取数据
                this.courses = [
                    {
                        id: 1,
                        title: '西游记',
    
                        // 如果组件加载静态数据并将其当做参数传给其他组件使用, 需要用require方法
                        img: require('../assets/img/111.jpg'),  // 实际项目中为后端图片链接
                        // img: '../assets/img/111.jpg'  // 直接写路径无法加载图片
                    },
                    ...                    
                ]
            },
            mounted() {  // 如果是特别耗时的数据请求, 可以延后到组件初步加载成功后, 再慢慢请求
                console.log('Course组件挂载完成!');
            },
            destroyed() {  // 应用场景: 例如二次确认是否离开页面
                console.log('Course组件销毁成功了!');
            },
        }
    </script>
    '''
    

    CourseTag.vue

    • 第一种路由传参: 在url后面通过?拼接参数
    • 第二种路由传参: 在url中通过模板字符串传递参数变量
    • this.$router.push: 控制路由跳转
    '''
    # v-projsrccomponentsCourseTag.vue
    <template>
        <div class="box">
            <img :src="course.img" alt="" @click="goDetail(course.id)">
    
            # 第一种路由传参: 在url后面通过?拼接参数
            # <router-link :to="`/course/detail?pk=${course.id}`"><h2>{{course.title}}</h2></router-link>
            """
            <router-link :to="{
                name: 'course-detail',
                query: {pk: course.id}
            }">
                <h2>{{course.title}}</h2>
            </router-link>
            """
    		
    		# 第二种路由传参: 在url中通过模板字符串传递参数变量
            <router-link :to="`/course/${course.id}/detail`"><h2>{{course.title}}</h2></router-link>
        </div>
    </template>
    
    <script>
        export default {
            props: ['course',],  
            methods: {
                goDetail(pk) {
                    // this.$router.push(`/course/detail?pk=${pk}`);
                    this.$router.push({
                        // path: '/course/detail',
                        name: 'course-detail',  // 控制点击后跳转的url
                        query: {pk: pk}  // 控制跳转的url?后拼接的参数
                    })
                }
            }
        };
    </script>
    '''
    

    index.js

    '''
    ...
    import CourseDetail from '../views/CourseDetail.vue'
    
    ...
    
    const routes = [
        ...
        {
            // 第一种路由传参对应的配置
            // path: '/course/detail',
    
            // 第二种路由传参对应的配置
            path: '/course/:pk/detail',  // :pk为vue语法中的有名分组
    
            name: 'course-detail',
            component: CourseDetail
        },
    ];
    
    ...
    '''
    

    CourseDetail.vue

    • 在标签中获取当前组件中的数据可以直接通过变量名获取, 而不需要使用this.的形式
    • this.$route存放当前页的url信息
    '''
    # v-projsrcviewsCourseDetail.vue
    <template>
        <div class="course-detail">
            <button @click="$router.go(-1)">返回课程页</button>  <!--在标签中不需要通过this.获取-->
            ...
        </div>
    </template>
    
    <script>
        export default {
            data() {
                return {
                    pk: 0
                };
            },
            created() {
                // 获取路由传递的参数: 课程id
                // console.log(this.$route);  // {..., path: "/course/detail", ..., query: {pk: "3"}, …}
                // this.pk = this.$route.query.pk;  // query接收路径?后面传递过来的参数
                this.pk = this.$route.params.pk || this.$route.query.pk;  // params接收根据有名分组从路径字符串匹配到的参数
            },
        }
    </script>
    '''
    
  • 相关阅读:
    深入理解JS中的变量及变量作用域
    浏览器加载、解析、渲染的过程
    gerrit和git
    宽高等比缩放
    常见的网站性能优化手段
    JS实现数组去重(重复的元素只保留一个)
    重构与回流
    APP开放接口API安全性——Token令牌Sign签名的设计与实现
    索引原理-btree索引与hash索引的区别
    从四个维度谈谈如何做好团队管理
  • 原文地址:https://www.cnblogs.com/-406454833/p/12118189.html
Copyright © 2011-2022 走看看