vue2-2笔记

19.使用 vue-cli脚手架创建模板项目
    /**
     *  脚手架2:
     *  安装脚手架命令  脚手架2的命令
     *  npm install -g vue-cli    
     *  下载模版命令
     *  vue init webpack my-project   配置中除了eslint为y,其它都为n
     * 
     *  npm run dev 或  npm start 运行项目命令---不会自动打开浏览器
             在config目录中的index.js文件中的第18行代码:autoOpenBrowser: true 修改为true,自动打开浏览器
               在build目录中的webpack.base.conf.js文件中第25行: app: './src/main.js' 是整个项目的入口文件
     *  npm run build 打包 产生dist目录
     *  serve dist 运行打包文件
     * 
     *  如果你用的是yarn 下载的,那么运行项目的时候  yarn 是不需要写run的
     * 
     * node_modules 依赖包目录
     * eslint检查的问题
     * build目录是webpack的相关的设置
     * config目录配置文件,里面的index.js中可以设置是否让浏览器自动打开
     * dist目录---打包后的目录文件
     * node-modules--依赖包---相关的文件
     * static---存放的是静态资源,css样式,图片,字体
     * babelrc---文件--babel的相关配置----mint-ui中配置
     * .eslintignore---->可以直接用 *.vue 或者*.js 的方式全局的忽略检查
     * .eslintrc.js 文件中 rules---一项一项的配置eslint的相关检查----看我操作
     * index.html----项目主入口html文件
     * package.json配置文件
     * src目录
     * main.js程序的主入口的js文件
     * App.vue父级组件文件
     * assets目录---图片---直接干掉----不用
     * components目录-------里面放的都是组件文件(.vue后缀的文件,叫组件文件)
     * 组件:html+css+js----形成的一个.vue文件---组件
     * 组件:具有一定功能效果的集合,里面包含html+css+js
     * 抽取了多个的组件,就形成了组件化
     * 源码的分析:
     * scoped:有可能会影响父子级组件之间的样式
           脚手架3:  
               脚手架3的下载命令
                     npm install -g @vue/cli
                       注意:如果电脑中安装了脚手架2了,不能直接安装脚手架3,必须要先干掉电脑中脚手架2,然后再安装脚手架3
                  npm uninstall vue-cli -g  干掉脚手架2
                通过脚手架3下载模版的命令
                     vue create app-client3
                 脚手架3 启动 的命令和 打包  打包命令
                  npm run serve(开发环境)
                  npm run build(生产环境)
                  serve dist
                 脚手架3中浏览器自动打开的设置,package.json 中 进行设置 
                 "scripts": {
                  "serve": "vue-cli-service serve --open",//添加--open
                },
              脚手架3main.js文件
                  new Vue({
                  render: h => h(App),//在内存中渲染App组件
                }).$mount('#app') // 获取id为app的html容器通过$mount进行挂载
             脚手架3关闭eslint检测
                 1.在package.json文件中的"rules": {}关闭相关的eslint语法检查
                 2.或者在vue.config.js文件中进行配置的方式关闭eslint语法检查
                     module.exports = {
                          lintOnSave:false
                      } 
                  3.或者在package.json文件中删掉eslint依赖和eslintConfig配置
     */
                        
20.main.js和App.vue模板
    1)main.js
        import Vue from 'vue'
        import App from './App.vue'//1.引入组件
        
        new Vue({
          el: '#app',
          components: {App}, // 2.注册组件标签
          template: '<App/>' // 3.使用组件模板
        })
    2)在App根主组件引入其他组件
        <template>
          <div>
            //3.使用组件模板
            <HelloWorld/>
          </div>
        </template>        
        
        <script>
          //1.引入组件
          import HelloWorld from './components/HelloWorld.vue'        
          export default {
              name:'App',// 当前组件名字
            //2.注册组件标签
            components: {
              HelloWorld
            }
          }
        </script>    
                
!!        //     scoped让组件样式独立存在,不会受其它组件样式影响    
        <style scoped>
          .logo {
            width: 100px;
            height: 100px;
          }
        </style>
        

            
21.组件间的通信    
    1)props(父-->子)
        1.父组件传输属性给子组件
            //comments是data属性
            <List :comments="comments"/>
        2.子组件接收父组件属性
            方法1:
                export default {
                  // 接收属性,指定属性名
                  props:['comments']
                }
            方法2:
                export default {
                  // 接收属性,指定属性名、属性值的类型
                  props:{
                      comments:Object
                  }
                }
            方法3(完整版):
                export default {
                  // 接收属性,指定属性名、属性值得类型和必要性
                  props:{
                      comments:{
                          type:Object,
                          required:true,
                          default:{} 指定comments的默认值
                      }
                  }
                }
    2)自定义事件 (事件父-->子,属性子-->父)
        1. 绑定事件监听 (父)
            通过 v-on 绑定 :@delete_todo="deleteTodo" 
                delete_todo是自定义事件名称,deleteTodo是自定义事件触发的回调函数
        2. 触发事件 (子)
            //eventName是触发自定义事件名称,data是传递给事件回调函数数据
            this.$emit(eventName, data) 
        3. 解绑事件(子)
            this.$off(eventName) // 取消对应的事件
            this.$off() // 取消全部的事件
    3)vue 插槽
            设置在自组件内部的插槽像一个盒子,位置由子组件决定,放什么内容由父组件决定。
        实现了内容分发,提高了组件自定义的程度,让组件变的更加灵活
            1)默认插槽:无需name属性,取子组件肚子里第一个元素节点作为默认插槽。
            <!-- 子组件,组件名:child-component -->
        <div class="child-page">
                <h1>子页面</h1>
                <slot></slot> <!-- 替换为 <p>hello,world!</p> -->
        </div>

        <!-- 父组件 -->
        <div class="parent-page">
                <child-component>
                        <p>hello,world!</p>
                </child-component>
        </div>

        <!-- 渲染结果 -->
        <div class="parent-page">
                <div class="child-page">
                        <h1>子页面</h1>
                        <p>hello,world!</p>
                </div>
        </div>
        2.具名插槽:
        在多个插槽的情况下使用,利用name标识插槽。
        <!-- 子组件,组件名:child-component -->
        <div class="child-page">
                <h1>子页面</h1>
                <slot name="header"></slot>
                <slot></slot>  <!-- 等价于 <slot name="default"></slot> -->
                <slot name="footer"></slot>
        </div>

        <!-- 父组件 -->
        <div class="parent-page">
                <child-component>
                        <template v-slot:header>
                            <p>头部</p>  
                        </template>
                        <template v-slot:footer>
                            <p>脚部</p>
                        </template>
                        <p>身体</p>
                </child-component>
        </div>

        <!-- 渲染结果 -->
        <div class="parent-page">
                <div class="child-page">
                        <h1>子页面</h1>
                        <p>头部</p>
                        <p>身体</p>
                        <p>脚部</p>
                </div>
        </div>
        3.作用域插槽:
        子组件给父组件传递数据。
        <!-- 子组件,组件名:child-component -->
        <div class="child-page">
                <h1>子页面</h1>
                <slot name="header" data="data from child-component."></slot>
        </div>

        <!-- 父组件 -->
        <div class="parent-page">
                <child-component>
                        <template v-slot:header="slotProps">
                            <p>头部: {{ slotProps.data }}</p>
                        </template>
                </child-component>
        </div>

        <!-- 渲染结果 -->
        <div class="parent-page">
                <div class="child-page">
                        <h1>子页面</h1>
                        <p>头部: data from child-component.</p>
                </div>
        </div>
    4) ref(子-->父)
        <Footer ref="Footer"></Footer>
        // 获取子组件进行一系列操作
        this.$refs.Footer.innerHTML
    5)事件总线(任意组件)
        通过在Vue原型上添加一个$bus实例对象,这样不同组件通过this.$bus.$on()绑定的事件就是同一个事件,
        不同组件就可以通过this.$bus.$emit()去触发
        1.定义事件总线
            Vue.prototype.$bus=new Vue()
        2.绑定事件
            // delete_todo是自定义事件名称,data是触发事件是传递过来的数据
            this.$bus.$on('delete_todo', function (data) {})
        3.触发事件
            //eventName是触发自定义事件名称,data是传递给事件回调函数数据
            this.$bus.$emit(eventName, data) 
        4.解绑事件
            this.$off(eventName) // 取消对应的事件
            this.$off() // 取消全部的事件 
    6)订阅消息与发布消息(任意组件间通信)
        1.下载pubsub 库
            npm i pubsub-js
            import PubSub from 'pubsub-js'
        2.订阅消息(相当于绑定事件)
            //前后msg都是订阅消息名称,data需要的数据
            this.token=PubSub.subscribe('msg', function(msg, data){}) 
        3.发布消息 
            //data传递过去的数据
            PubSub.publish('msg', data) 
        4.取消订阅消息
            // 参数不传就取消所有订阅的消息
            PubSub.unsubscribe(this.token)
    7) vuex(后面单独讲)
    7) Vue.observable({count:0,name:'李四'})
        让一个对象可响应,实现多个组件共享数据状态
        //首先创建一个 store.js,包含一个 store和一个 mutations,分别用来指定共享的数据和改变数据的方法。
        //store.js
        import Vue from 'vue';        
        //store={count:0,name:'李四'},并且该对象可响应
        export let store =Vue.observable({count:0,name:'李四'});
        export let mutations={
            setCount(count){
                store.count=count;
            },
            changeName(name){
                store.name=name;
            }
        }
        export let getters={
            getCount(){
                return store.count
            }
        }
        //使用
        import HomeHeader from '../components/HomeHeader'   
        import {store,mutations,getters} from '@/store'
        export default {  
            data () {  
                return {  
                    name1:'主页的name'
                }  
            },  
            components: {  
                HomeHeader 
            },  
            computed:{
                //获取store中的状态数据
                count(){
                    return store.count
                },
                name(){
                    return store.name
                },
                getCount(){
                    return getters.getCount()
                    
                }
            },
            methods:{
                //获取改变store中状态数据的方法
                setCount:mutations.setCount,
                changeName:mutations.changeName    
            }
        }  
    8) 组件通信高级部分
        1.v-model深入(父传给子属性和修改父级属性的方法)
            1)父级中
                // v-model的本质:使用value属性配合input事件来实现的
                // 相当于传递了一个value属性和更新value的@input事件,事件的第二个参数就是value的最新值
                <CustomInput v-model="msg3" />
                <CustomInput :value="msg3" @input="msg3=$event" />
            2)子组件中
                // value值父级中的msg3,父组件中的$event是子组件中的$event.target.value
                <input :value="value" @input="$emit('input',$event.target.value)" />
        2.属性修饰符sync(父传给子属性和修改父级属性的方法)
            1)父级中
                // 第一个和第二个是一样的,相当于父组件给子组件传递了money和更新money的update:money方法
                // 发布事件的第二个参数就是修改后的money
                <Child :money.sync="total" />
                <Child :money="total" @update:money="total=$event" />
            2)子组件中
                <button @click="$emit('update:money',money-100)">花钱</button>
        3.$attrs与$listeners(父传子)
            1)父级中
                <LinkButton title="添加" type="primary" icon="el-icon-plus" @click="add" />
            2)子组件中
                // v-bind="$attrs"相当于v-bind="{ type: primary, icon: el-icon-plus }"
                // title属性在props中接收,所以$attrs对象中不包含title属性
                // $attrs属性也是对象,该对象内部包含标签(组件)上传递的所有的属性(不包括prop,class,style)
                // $listeners属性也是对象,该对象内部包含标签(组件)上传递的所有事件
                // v-on="$listeners"相当于v-on="{ click: add}
                <el-button v-bind="$attrs" v-on="$listeners"></el-button>
        4.$children与$parent(父修改子,子修改父)
            1)父级中
                // 获取当前父级组件中的所有的子级组件,进行遍历操作
                this.$children.forEach(child => {
                    child.pullMoney(500)
                    this.money += 1000
                  })
            2)子组件中
                // 可以操作父级组件的属性
                this.$parent.money += money
22.vue 常用UI 组件库
    1) Mint UI (用于移动端)
        主页: http://mint-ui.github.io/#!/zh-cn 
        说明: 饿了么开源的基于 vue 的移动端 UI 组件库
        1.下载:
            npm install --save mint-ui
!!        2. 实现按需打包 :这样就可以不用引入样式了,用到什么样式会自动引入
            1. 下载 npm install --save-dev babel-plugin-component 
            2. 修改 babel 配置 
                "plugins": ["transform-runtime",["component", [ 
                    { 
                    "libraryName": "mint-ui", "style": true 
                    } 
                ]]]
            3) 在main.js文件中编程 
                import {Button} from 'mint-ui' 
                // 将组件映射成全局标签,这样所有组件就可以使用这个组件了,Button.name是框架提供的组件标签mt-button
!!                Vue.component(Button.name, Button) 

!!                补充:还可可以在要使用的组件当中引入,这样只有该组件可以使用
                    import { MessageBox } from 'mint-ui';
                    编程App.vue 
                    <template> 
                        <mt-button @click="handleClick" type="primary" style="width: 100%">Test</mt-button> 
                    </template> 
                    <script> 
                    import {Toast} from 'mint-ui' 
                        export default { 
                            methods: { 
                                handleClick () { Toast('点击了测试'); } 
                            } 
                        } 
                    </script>
    2) Element (用于PC端)
        1.button按钮属性
            1)icon:图标
            2)size:大小
            3)type:类型
            4)loading:为true加载状态不能点击按钮,false相反
        2.table表格属性
            1):data:展示的数据
            2)stripe:斑马纹
            3)border:边框
            4)selection-change:单选框选项发生改变触发的回调
            5)height:高度
        3.table-column表格列属性
            1)prop:展示的列数据(列标签中方内容,prop就没效果了)
            2)type="index":展示的列数据为下标,优先级高于prop
            3)align:对齐方式
            4)v-loading:值为true显示加载效果,值为false不显示加载效果
            5)label:标题
            6)type=selection:出现单选框
            7)width:宽度
            8)fixed="right":当前列固定
            9)sortable:上下排序标识
            补充:<template slot-scope="scope"></template>:scope里面包含$index和row的属性的对象
                $index:当前的下标,row:当前这一行的数据对象(trademark)
        4.message信息框属性
            1)error():错误信息
            2)success():成功信息
            3)warning():警告信息
        5.pagination分页属性
            1)current-page:默认第几页被选中
            2)page-sizes="[3, 6, 9, 12]":可以设置每页显示的条数
            3)page-size:默认每页条数
            4)total:总的条数
            5)layout:代表的是页面中分页布局的显示顺序
            6)background:背景颜色
            7)@current-change:页码发生变化触发的回调
            8)@size-change:设置每页显示的条数触发的回调
        6.dialog对话框属性
            1)title:标题
            2)visible.sync:控制对话框的显示与隐藏
            3)before-close:对话框关闭前的回调
            4)show-close="false":不显示叉号
            5)close-on-click-modal="false":点击灰色地方对话框不消失
        7.form表单属性
            1)rules:表单验证
            2)inline:表单项成行排列
            3)model:表单内使用到的数据
            4)label-width:所有表单前面文字宽度,一般用来对齐表单项
        8.form-item表单项属性
            1)label:表单项前面显示的标题
            2)label-width:表单前面文字宽度
            3)prop:表单验证项添加prop属性
        9.input框属性
            1)autocomplete:是否显示输入过的内容       off/on
            2)readonly:只读
        10.autocomplete远程搜索
            1)fetch-suggestions:搜索时触发的回调,参数一:搜索内容,参数二:一个回调函数,接收一个要展示的数组
            2)select:点击提示内容触发
        10.input-number计数器
            1)min:最小值
            2)max:最大值
        10.select下拉框属性
            1)@change:下拉框内容发送变化触发的回调,组件会自动把下拉框的值作为参数传给回调函数
            2)placeholder:提示信息
        11.option下拉框属性
            1)label:显示给用户看的选择项
            2)value:下拉框真正的值
            3)key:每项下拉框的唯一标识
        12.upload属性
            1)action:文件上传地址
            2)on-success:图片上传成功的回调
            3)before-upload:图片上传成功前的回调
            4)multiple:支持一次性选择多张图片
            5)file-list:展示的图片
            6)on-preview:预览图片触发的回调
            7)on-remove:删除图片触发的回调
            8)list-type="picture-card":图片成照片墙形式
        13.confirm框
            // 参数一:提示内容,参数二:标题,参数三:配置对象,then按确定按钮执行,catch按取消按钮执行
            this.$confirm(`确定删除${trademark.tmName}吗?`, '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
              })
                .then(() => {})
                .catch(() => {})
        14.card卡片属性
        15.Tag标签属性
            1)type:类型
            2)closable:显示x号
            3)@close:点击x号触发的回调
        16.Popconfirm气泡确认框属性
            1)title:提示标题
            2)slot="reference":给那个标签按钮加上这个属性,在点击标签按钮的时候就会出现气泡确认框属性
        17.drawer抽屉属性
            1)visible:是否显示
            2)before-close:关前回调
            3)direction:打开方向
            4)withHeader:是否带头部标题
        18.layout布局,<el-row></el-row>:行, <el-col :span="24"></el-col>:行里面的一项,一行总共24分,特殊点5分的话字体加粗靠右
        19.Carousel 走马灯(轮播图)属性
            1)trigger:轮播图的触发方式
            2)autoplay:是否自动播放
            3)arrow:切换箭头的显示时机
            4)height:高度
        20.carousel-item轮播图一项
        21.dropdown:下拉菜单
            1)command:点击下拉菜单项触发,点击项作为事件参数
        22.dropdown-item:下拉菜单项
            1)command:下拉菜单项,作为点击回调的参数
            2)divided:给下拉菜单项添加分割线
        23.breadcrumb:面包屑
            1)separator="/":用斜杆分割面包屑每项
        24.breadcrumb-item:面包屑每项
            1)to:点击面包屑要跳转的路由地址
        25.scrollbar:滚动栏,内容超出生成滚动条
        26.menu:菜单栏
            router:检测menu-item的index属性,跳转到相应的路由地址
            default-active:当前展示的路由路径
        27.menu-item:菜单栏每一项
            index:绑定路由地址,点击时router会监视index值,跳转到对应的路由页面
        28.submenu:含有多个子元素的菜单栏每一项
            index:绑定路由地址,点击时router会监视index值,跳转到对应的路由页面
        29.date-picker:时间选择器
            type="date":类型为时间选择器
            value-format:时间格式
            v-model:时间
        30.radio-group:一组单选框
            1)v-model:选择项
        31.radio:每项单选框
            1)label:展示内容
            2)name:名字
        32.tabs:选项卡
            1)type="border-card":加边框
            2)v-model="tabPosition":默认选中项
        33.tab-pane:选项卡每项
            1)label:显示在选项卡上的标题
            2)name:名字
        
23.vue 项目中常用的 2 个 ajax 库
    1)vue-resource(在主js文件引入使用,少用) 
        vue 插件, 非官方库, vue1.x 使用广泛
        1.下载
            npm install vue-resource --save
        2.使用
!!            // 在main.js文件中引入模块 
            import VueResource from 'vue-resource' 
            // 使用插件,内部会给vm对象和组件对象添加一个属性$http,$http有get()和post()方法
            Vue.use(VueResource) 
            // 通过 vue组件对象发送 ajax 请求
            this.$http
                .get('/someUrl')
                .then((response) => { 
                    console.log(response.data) //返回结果数据 
                    }, 
                    (response) => { 
                    console.log(response.statusText) //错误信息 
                    })
    2)axios(那个组件使用在哪里引入)
        1.下载
            npm install axios --save
        2.使用
            // 引入模块 
            import axios from 'axios' 
            // 发送 ajax 请求 
            axios
                .get(url) 
                .then(response => {
                    console.log(response.data) // 得到返回结果数据 
                })
                .catch(error => {
                    console.log(error.message) 
                })

24.vue-router(路由)
    1) 路由:一种映射关系:地址和组件的关系,路由链接(相当于a标签)和路由视图(组件页面)的一种关系,专门用来实现单页面应用程序(SPA)
    2) github: https://github.com/vuejs/vue-router 
    3) 中文文档: http://router.vuejs.org/zh-cn/ 
    4) 下载: npm install vue-router --save
    
    5) 使用路由3步
        1.创建一个router的目录,内部有一个index.js文件,在index.js文件中创建、配置并暴露路由
            // 引入Vue
            import Vue from 'vue'
            // 引入vue-router
            import VueRouter from 'vue-router'
            // 声明使用插件
            Vue.use(VueRouter)
            // 创建、配置并暴露路由器
            export default    new VueRouter({ 
                            mode:'history' ,  // 路由方式:history---地址栏中没有#  hash ----地址栏中有#(默认)
                            // 配置路由
                            routes: [ 
                                { path: '/about', component: About },
                                { // 路由重定向,页面开始默认显示的路由组件
                                    path: '/', 
                                    redirect: '/about',
                                },    
                                { // 嵌套路由
                                    path: '/about', 
                                    component: About,
!!                                    // 子路由可以是/about/news也可以是news
                                    children: [ { path: '/about/news', component: News } } ]
                                },    
                                {//*号代表所有路由都没有匹配到,重定向到错误页面
                                    path: '*',
                                    redirect: '/404'
                                },        
                                scrollBehavior (to, from, savedPosition) {//路由跳转页面停留的位置
                                    return {//顶部
                                      x:0,
                                      y:0
                                    }
                                  }    
                            })
        2. 在main.js文件中让路由和实例对象建立联系
            import router from './router' 
            new Vue({ router })
        3. 使用路由
            1) <router-link>: 用来生成路由链接 
                <router-link to="/xxx"></router-link> 
            2) <router-view>: 用来显示当前路由组件界面 
                <router-view></router-view>
        4. 如何向路由组件传递参数
            1)声明式路由传参
                1.params方式传参
                    //用:id占位
                    routes: [ 
!!                        {
                         name: 'about',//使用对象name方式传参添加name属性(命名路由)
                         path: '/about/:id?',//添加?代表传不传参数都会跳转路由
                         component: About 
                        }
                    ]                    
                    //传参
                    <router-link :to="`/about/${message.id}`"></router-link> //字符串
                    或者
                    <router-link :to="{ name: 'about' ,params:{id:message.id}"></router-link> //对象
                    // 接收参数(在传递和接收路由组件上都可以通过此方式获取参数)
                    this.$route.params.id
                2.query方式传参
                    {
                       name: 'about',//使用对象name方式传参添加name属性(命名路由)
                       path: '/about',
                       component: About
                    }
                    //传参
                    <router-link to="/about?age=18&name='joke'">About</router-link> //字符串
                    或者
                    <router-link :to="{path:'/about',query:{id:message.id}}"></router-link> //对象
                    或者
                    <router-link :to="{name:'about',query:{id:message.id}}"></router-link> //对象
                    //获取参数
                    this.$route.query.id
                3.meta方式传参
                    {
                       path: '/about',
                       component: About,
                       meta: {//传参
                         isShow: true
                       }
                    }
                    <router-link to="/about">About</router-link>
                    //获取参数
                    this.$route.meta.isShow
                4.props方式传参
                    1)布尔模式
                        //用:id占位
                        {
                           path: '/about/:id',
                           component: About,
                           props:true
                        }
                        //传参
                        <router-link to="/about/12345">About</router-link>
                        //接收参数
                        props:['id']
                    2.对象模式
                        {
                           path: '/about',
                           component: About,
                           props:{
                             msg:'脑瓜疼'
                           }
                        }
                        <router-link to="/about">About</router-link>
                        props:['msg']:接收参数
                    3.函数模式
                        //用:id占位
                        routes: [ 
                            {
                                path: '/about/:id',
                                component: About,
                                props: (route) => ({ id: route.params.id } 
                            },
                            ]
                            
                        //传参
                        <router-link :to="`/about/${message.id}`"></router-link>
                        //接收参数
                        props:['id']
            2)编程式路由传参
                1.params传参
                    //用:id占位
                    routes: [ 
                            {
                            name: 'search' ,//使用对象name方式传参添加name属性(命名路由)
                            path: '/about/:id', 
                            component: About 
                            }
                        ]
                    //传参
                    this.$router.push('/search/123')
                    或者:
                    this.$router.push({ name: 'search' ,params:{keyword:this.keyword}})
                    //接收参数
                    this.$route.params.id:获取路由参数(在传递和接收路由组件上都可以通过此方式获取参数)
                2.query传参
                    routes: [ 
                            {
                            name: 'search' ,//使用对象name方式传参添加name属性
                            path: '/about', 
                            component: About 
                            }
                        ]
                    //传参
                    this.$router.push(`/search?keyword=${this.keyword}`)
                    或者
                    this.$router.push({ name: 'search' ,query:{keyword:this.keyword}})
                    或者
                    this.$router.push({ path: '/search' ,query:{keyword:this.keyword}})
                    //接收参数
                    this.$route.params.keyword:获取路由参数
        5.路由属性
            1)$route(在实列中)
                1. this.$route.path:获取路由路径
                2. this.$route.params:获取路由参数
            2)$router(在实列中)
                1. this.$router.push(path): 相当于点击路由链接(可以返回到当前路由界面) 
                    相当于<router-link></router-link>
                2. this.$router.replace(path): 用新路由替换当前路由(不可以返回到当前路由界面) 
                    相当于<router-link replace ></router-link>
                3. this.$router.back(): 请求(返回)上一个记录路由 
                4. this.$router.go(-1): 请求(返回)上一个记录路由 
                5. this.$router.go(1): 请求下一个记录路由
    6)声明式路由和编程式路由
        1.声明式路由:利用router-link和router-view来实现路由跳转
        2.编程式路由:利用$router的API来实现路由跳转
    7)缓存路由组件
        默认情况下, 被切换的路由组件对象会死亡释放, 再次回来时是重新创建的 
        如果可以缓存路由组件对象, 可以提高用户体验
        1.缓存全部路由
            <keep-alive> 
                <router-view></router-view> 
            </keep-alive>    
        2.指定路由缓存
            <keep-alive include="该路由的name名称">
              <router-view></router-view>
            </keep-alive>
        3.缓存部分路由
            在路由中添加下面属性  
            meta: {keepAlive: true // 缓存}
            meta: {keepAlive:false // 不缓存 }
                然后在页面  
            <keep-alive >
                //当前进入的路由 meta里面 keepAlive为true时走这里
              <router-view v-if="$route.meta.keepAlive"></router-view>
            </keep-alive>
            //当前进入的路由 meta里面 keepAlive为false时走这里 下面 if 判断进行了取反处理
            <router-view v-if="!$route.meta.keepAlive"></router-view>
    8)路由守卫
        路由守卫可以监视路由地址的变化,一旦地址发送变化可以做一系列的事情
        应用: 在跳转到某个界面之前,进行用户的权限的限制(是否登录),离开这个界面前,做相关的收尾的一些操作
        1.全局路由守卫:全局中只要发生路由跳转就会拦截下来做判断进而做一系列事情,包含全局前置守卫(常用)和全局后置守卫(在router目录的index.js文件下)
            router.beforeEach((to, from, next) => {
                to:目标的路由route对象
                from:当前的路由route对象
                next:用来控制路由跳转的函数      next()同意跳转      next(地址)跳转到指定的path的路由
            }
            export default router
        2.路由独享守卫:只要跳转到指定路由就会拦截下来做判断进而做一系列事情,包含前置守卫和后置守卫(在router目录的routes.js文件下)
            {
                path: '/addcartsuccess',
                component: AddCartSuccess,
                beforeEnter: (to, from, next) => {}
            }
        3.组件内守卫:只要跳转到指定路由就会拦截下来做判断进而做一系列事情(和路由独享守卫差不多,就是写的地方不一样而已),包含前置守卫和后置守卫(组件内使用,方法和methods同级)
            beforeRouteEnter(to, from, next) {
                // 在渲染该组件的对应路由被 confirm 前调用
                // 不!能!获取组件实例 `this`
                // 因为当守卫执行前,组件实例还没被创建
                // vm为实例对象 
                next(vm => {})
            }
    9)给点击的路由组件添加样式
        .router-link-active {
          color: red !important;
        }
!!    注意:在路由中引入样式要用绝对路径代替相对路径
        //     /代表从项目运行根目录开始查找
        <link rel="stylesheet" href="/static/css/bootstrap.css">
        代替:
        <link rel="stylesheet" href="./static/css/bootstrap.css">
    10)<router-link></router-link>属性
        1.<router-link replace></router-link>:路由的跳转采用replace的方式
        2.<router-link tag='li'></router-link>:路由连接变成li标签
25.vuex(vue插件)
    1) 对 vue 应用中多个组件的共享状态进行集中式的管理(读/写)            
    2) github 站点: https://github.com/vuejs/vuex 
    3) 在线文档: https://vuex.vuejs.org/zh-cn/ 
    4) vuex核心对象store
        1.定义、配置并暴露store对象(在vuex文件夹下的store.js文件或在store文件夹的index.js文件下)
            import Vue from 'vue'
            import Vuex from 'vuex'
            Vue.use(Vuex)
            
            export default new Vuex.Store({
              state,
              getters,
              actions,
              mutations
            })
            
            1) state:包含了多个状态数据的对象
                const state = {
                  count: 0  
                }
            2) getters:包含多个状态数据的计算属性的get()方法的对象
                const getters = { 
                    evenOrOdd (state) { 
                        return state.count%2===0 ? '偶数' : '奇数'
                    }
                }
                第一个参数:state状态数据
            3) actions:包含多个间接改变状态数据的方法
                1.同步代码 
                    const actions = { 
                        increment ({commit, state,dispatch,getters},data) {
                            //第一个参数INCREMENT通知mutations执行那个回调函数
                            //第二个参数是传递给mutations的数据
                             commit('INCREMENT',data) 
                        }
                     }
                    第一个参数:context相当于store对象,解构{commit, state}
                    第二个参数:组件中dispatch  actions函数的第二个参数(传递过来的值)
                2. 异步代码(定时器, ajax) 
                    const actions = { 
                        setTimeout(()=>{
                            increment ({commit, state}) {
                                 commit('INCREMENT') 
                            }
                        },1000)
                     }
                    补充:如何根据提交的异步action的成功或者失败做不同的处理?(在项目把商品加入购物车有用到)
                       * 方式1:
                       *   使用callback回调处理
                       *     在组件内部,分发异步action的时候,使用dispatch()方法的时候,传入一个回调函数callback
                       *     在异步action中,在请求处理成功或者失败的时候,调用这个回调函数callback,如果成功就向callback中传入空字符串,失败就传入错误的信息
                       *     在callback回调函数内部,判断传入的是空串还是错误信息,根据空串或者错误信息来进行跳转处理
                       * 方式2:
                       *   在组件中,普通的方式分发action, this.$store.dispatch('action的名字',参数)
                       *   在异步action中,请求处理成功或者失败后,返回相关的错误消息
                       *   在组件中,通过await得到当前的action返回的错误消息(可能是空串,也可能是有值错误消息),根据判断来处理对应的问题
            4) mutations:包含多个直接改变状态数据的方法 
                    const mutations = { 
                        // state是状态数据
                        // data是actions传递过来的数据
                        INCREMENT (state,data) {
                            state.count++
                    } }
                                                            
        2.在main.js中让store和实例对象建立联系(实列对象上多了个$store属性)
            import store from './store' 
            new Vue({ store })
        3.组件中读写store属性方式 
            1.方式1
                读(获取或计算属性):
                    this.$store.state.count
                    this.$store.getters.add
                写(操作属性):
                    this.$store.dispatch("delete",data)    触发actions函数的调用,data是传递过去的数据
                    this.$store.commit("delete",data)      直接触发mutations函数的调用,data是传递过去的数据
            2.方式2(Vuex的辅助函数)
            // mapState, mapGetters, mapActions,mapMutations
            // 分别可以映射调用store对象上state/getters/actions/mutations上的属性
            import {mapState, mapGetters, mapActions,mapMutations} from 'vuex' 
            export default { 
                读(获取或计算属性):
                    computed: { 
                        ...mapState(['count']), 
                        ...mapGetters(['evenOrOdd']), 
                    }
                写(操作属性):
                    methods: {
                        ...mapActions(['increment']),
                        ...mapMutations({increment:'INCREMENT'}),
                    }
            }
        4. modules(store对象的第五大属性对象) 
            1) 包含多个 module 
            2) 一个 module是一个 store 的配置对象 
            3) 与一个组件对应(包含有共享数据)
            4) 读写状态数据
                1.方式1(可以传递data)
                    读(获取或计算属性):
                        this.$store.state.home.count //需要加上home模块
                        this.$store.getters.add
                    写(操作属性):
                        this.$store.dispatch("delete",data)    触发actions函数的调用,data是传递过去的数据
                        this.$store.commit("delete",data)      直接触发mutations函数的调用,data是传递过去的数据
                2.方式2(Vuex的辅助函数) (不可以传递data)
                // mapState, mapGetters, mapActions,mapMutations
                // 分别可以映射调用store对象上state/getters/actions/mutations上的属性
                import {mapState, mapGetters, mapActions,mapMutations} from 'vuex' 
                export default { 
                    读(获取或计算属性):
                        computed: { 
                            ...mapState({count:state=>state.home.count}), //需要加上home模块,用对象的方式
                            ...mapGetters(["evenOrOdd"])
                        }
                    写(操作属性):
                        methods: {
                            ...mapActions(['increment']),
                            ...mapMutations({increment:'INCREMENT'}),
                        }
                }
        5.命名空间namespaced:true
            加上命名空间后再组件中调用dispatch和commit只会调用根模块的actions和mutations,想要触发其它模块下的dispatch和commit
            可以这样用this.$store.dispatch('模块名/action名')
        6.subscribe()和replaceState()方法
            1)mutation调用后执行subscribe()方法
                store.subscribe((mutation, state) => {})
            2)替换state属性
                store.replaceState(state);
        
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值