个人自学前端32-Vue9-路由组件通信,动态路由

一.路由组件通信

路由组件间通信,用bus通信会变得和麻烦
因为目标路由组件默认情况下没有创建

路由组件通信 => 路由参数.

  1. 通过params传参.只能通过name跳转. 获取参数: $route.params.参数名
  2. 通过query传参.可以是name或者path跳转. 获取参数: $route.query.参数名

params传参和query传参区别

  1. query传参通过url传递,params不是.
  2. query只应该传递字符串和数字的参数,params可以传递任何类型的参数.
  3. query的参数长度不能超过2000字符.(受url长度限制).params没有长度限制.
  4. query传递的参数刷新后还存在.params的参数刷新后丢失.
<script>
    const Home = {
        template: `
            <div>
                <h3>首页--{{msg}}</h3>
                <input type='text' v-model='msg' />
                <button @click='toNews'>到新闻页</button>
                <p>首页的内容..<span>2018-07-22</span></p>
            </div>
        `,
        data() {
          return { msg: '' }
        },
        methods: {
          toNews() {
            this.$router.push({
              name: 'news',
              // params书写需要通信的数据
              params: {
                msg: this.msg
              }
            });
            // this.$router.push({
            //   name: 'news',
            //   // query书写需要通信的数据
            //   query: {
            //     msg: this.msg
            //   }
            // });
            // this.$router.push({
            //   path: '/news',
            //   // query书写需要通信的数据
            //   query: {
            //     msg: this.msg,
            //     abc: 'wwwww'
            //   }
            // });
          }
        }
    }
    const News = {
        template: `
            <div>
                <!--<h3>新闻---{{ $route.params.msg }}</h3>-->
                <h3>新闻---{{ $route.params.msg }}</h3>
                <p>新闻的内容..<span>2018-07-23</span></p>
            </div>
        `,
        data() {
          return { msg: '' }
        },
    }
    const Guide = {
        template: `
            <div>
                <h3>攻略</h3>
                <p>攻略的内容..<span>2018-07-24</span></p>
            </div>
        `
    }
    const router = new VueRouter({
        routes: [
            {
                path: '/home',
                component: Home,
                name: 'home'
            }, {
                path: '/news',
                component: News,
                name: 'news'
            }, {
                path: '/guide',
                component: Guide,
                name: 'guide'
            }, {
                path: '/',
                redirect: '/home'
            }
        ]
    });
    const App = {
        template: `
            <div>
                <keep-alive>
                  <router-view />
                </keep-alive>
            </div>
        `
    }
    new Vue({
        render: h => h(App),
        router
    }).$mount('#app');
</script>

1. $route对象

this.$route => 任何组件都可以访问.可以获取路由路径,路由参数等数据

区别:
$route => 路由选项对象.(每次路由切换时,它内部的属性都会改变)
$router => 路由实例.(跳转路由时用这个对象)
routes => 路由配置表 (实例化路由时写的)

2.params刷新丢失

$route.params.msg => 刷新后变成undefined
只有在Home跳到News时.$route.params.msg才是我们希望传递的参数.
只要不是Home到News的路由跳转,都无法获取这个msg数据
刷新相对于是从News到News.因此无法获取msg.

缓存组件时,刷新网页,也会导致组件重新创建的.

二. 动态路由

基本路由 => 一个路径对应一个组件(页面有限).
动态路由 => 多个路径对应一个组件(重复页面)(组件根据不同的路径显示不同的内容).

动态路由 => 切换视图时,组件的updated触发,created不触发.
动态路由 => 切换视图时,created不会重复触发.就算缓存后,activated也不会重复触发.

如何实现组件根据不同的路径显示不同的内容?
工作中是通过不同的接口来完成的.例如根据不同的路径请求不同接口,请求到数据后渲染即可.

动态路径 => 意味着所有的路径都匹配.
path: '/:path' => path => 是一个变量,是一个动态的路径.
path的值如何确定? => 当前的路径是什么,它就会自动变成什么.

如何获取这个参数?
$route.params.动态路径名获取.(不带/)

如果用了动态路径,一定需要注意路由选项的顺序问题.
每次路径变化,都会遍历routes数组,看当前的路径和routes内的那个路径一致,
如果有匹配的路径,就显示对应的组件.
从上往下匹配,如果前面的path匹配了,后面的path就不检查了.

多个动态的路径字段,都可以通过params来获取.

<script>
    const Login = {
      template: `
        <div>
          <input type='text' />
          <input type='password' />
          <button @click='$router.push("/home")'>登录</button>
        </div>
      `
    }
    const Home = {
        template: `
          <div>
            <router-link to='/home'>首页</router-link>
            <router-link to='/news'>新闻</router-link>
            <router-link to='/sport'>体育</router-link>
            <h3>{{data[$route.params.path]}}--{{$route.params.path}}</h3>
            <p>{{data[$route.params.path]}}的内容..<span>2018-07-22</span></p>
          </div>
        `,
        data() {
          return {
            data: {
              'home': '首页',
              'news': '新闻',
              'sport': '体育'
            }
          }
        },
        updated() {
          console.log(this.$route)
        }
    }
    const router = new VueRouter({
        routes: [
            {
              path: '/login',
              component: Login,
            }, {
              path: '/:path',
              component: Home,
              name: 'home'
            }, {
              path: '/',
              redirect: '/login'
            }
        ]
    });
    const App = {
        template: `
          <div>
            <router-view />
          </div>
        `
    }
    new Vue({
        render: h => h(App),
        router
    }).$mount('#app');
</script>

三. 路由选项的props

路由选项的props => 用于进行组件和路由的解耦

props 的作用 => $route.params.abc 映射成组件的 props数据abc

props的三种模式:

1. 布尔模式 (值是布尔值)

布尔模式 => 把$route.params.msg 映射成 组件的props

<script>
    const Home = {
        template: `
            <div>
                <h3>首页--{{msg}}</h3>
                <input type='text' v-model='msg' />
                <button @click='toNews'>到新闻页</button>
                <p>首页的内容..<span>2018-07-22</span></p>
            </div>
        `,
        data() {
          return { msg: '' }
        },
        methods: {
          toNews() {
            this.$router.push({
              name: 'news',
              // params书写需要通信的数据
              params: {
                msg: this.msg
              }
            });
          }
        }
    }
    const News = {
        template: `
            <div>
                <h3>新闻---{{ msg }}</h3>
                <p>新闻的内容..<span>2018-07-23</span></p>
            </div>
        `,
        props: ['msg']
    }
    const router = new VueRouter({
        routes: [
            {
                path: '/home',
                component: Home,
                name: 'home'
            }, {
                path: '/news',
                component: News,
                name: 'news',
                // 布尔模式
                props: true
            }, {
                path: '/',
                redirect: '/home'
            }
        ]
    });

2. 对象模式 (值是纯对象)

对象模式 => 把对象是属性映射成组件的props.

如果props是一个对象,
则可以把对象内的属性,映射成组件的props数据

<script>
    const Home = {
        template: `
          <div>
            <h3>{{data}}</h3>
            <p>{{data}}的内容..<span>2018-07-22</span></p>
          </div>
        `,
        props: ['data']
    }
    const router = new VueRouter({
        routes: [
            {
              path: '/:path',
              component: Home,
              name: 'home',
              props: {
                data: {
                  home: '首页',
                  news: '新闻',
                  sport: '体育'
                }
              }
            }, {
              path: '/',
              redirect: '/home'
            }
        ]
    });
    const App = {
        template: `
          <div>
            <router-link to='/home'>首页</router-link>
            <router-link to='/news'>新闻</router-link>
            <router-link to='/sport'>体育</router-link>
            <router-view />
          </div>
        `
    }
</script>

3. 函数模式 (值是函数)

函数模式 => 万能模式.可以映射任何的数据.

函数模式 => 函数需要return一个对象.这个对象的属性就是组件props的数据
函数的参数就是当前路由选项的$route对象.

<script>
    const Home = {
        template: `
          <div>
            <h3>{{data[path]}}</h3>
            <p>{{data[path]}}的内容..<span>2018-07-22</span></p>
          </div>
        `,
        props: ['data', 'path']
    }
    const router = new VueRouter({
        routes: [
            {
              path: '/:path',
              component: Home,
              name: 'home',
              props: (route) => {
                return {
                  path: route.params.path,
                  data: {
                    home: '首页',
                    news: '新闻',
                    sport: '体育'
                  }
                }
              }
            }, {
              path: '/',
              redirect: '/home'
            }
        ]
    });
    const App = {
        template: `
          <div>
            <router-link to='/home'>首页</router-link>
            <router-link to='/news'>新闻</router-link>
            <router-link to='/sport'>体育</router-link>
            <router-view />
          </div>
        `
    }
</script>

函数模式映射query

<script>
    const Home = {
        template: `
            <div>
                <h3>首页--{{msg}}</h3>
                <input type='text' v-model='msg' />
                <button @click='toNews'>到新闻页</button>
                <p>首页的内容..<span>2018-07-22</span></p>
            </div>
        `,
        data() {
          return { msg: '' }
        },
        methods: {
          toNews() {
            this.$router.push({
              name: 'news',
              query: {
                msg: this.msg
              }
            });
          }
        }
    }
    const News = {
        template: `
            <div>
              <h3>新闻---{{ msg }}</h3>
              <p>新闻的内容..<span>2018-07-23</span></p>
            </div>
        `,
        props: ['msg']
    }
    const Guide = {
        template: `
            <div>
                <h3>攻略</h3>
                <p>攻略的内容..<span>2018-07-24</span></p>
            </div>
        `
    }
    const router = new VueRouter({
        routes: [
            {
                path: '/home',
                component: Home,
                name: 'home'
            }, {
                path: '/news',
                component: News,
                name: 'news',
                // 函数模式,手动让msg等于route.query.msg
                props: (route) => ({ msg: route.query.msg })
            }, {
                path: '/guide',
                component: Guide,
                name: 'guide'
            }, {
                path: '/',
                redirect: '/home'
            }
        ]
    });
    const App = {
        template: `
            <div>
                <keep-alive>
                  <router-view />
                </keep-alive>
            </div>
        `
    }
</script>

四. 路由选项meta

meta => 可以用于定义一些路由组件的视图表现字段.(自定义字段)

<script>
    const Home = {
        template: `
            <div>
                <h3>首页</h3>
                <p>首页的内容..<span>2018-07-22</span></p>
            </div>
        `,
        created() {
          // 设置网页标题
          document.title = this.$route.meta.title;
        }
    }
    const News = {
        template: `
            <div>
                <h3>新闻</h3>
                <p>新闻的内容..<span>2018-07-23</span></p>
            </div>
        `,
        created() {
          // 设置网页的标题。
          document.title =this.$route.meta.title;
          // 获取link标签设置图片。
          const [oLink] = document.querySelectorAll('link');
          oLink.href = this.$route.meta.icon;
        }
    }
    const Guide = {
        template: `
          <div>
            <h3>攻略</h3>
            <p>攻略的内容..<span>2018-07-24</span></p>
          </div>
        `,
        created() {
          document.title = this.$route.meta.title;
        }
    }
    const router = new VueRouter({
        routes: [
            {
              path: '/news',
              component: News,
              meta: {
                title: '新闻',
                icon: '222.jpg',
              }
            }, {
              path: '/home',
              component: Home,
              meta: {
                title: '首页'
              }
            }, {
              path: '/guide',
              component: Guide,
              meta: {
                title: '攻略'
              }
            }, {
              path: '/',
              redirect: '/home',
            }
        ]
    });
    const App = {
      template: `
        <div>
          <router-link to='/home'>首页</router-link>
          <router-link to='/news'>新闻</router-link>
          <router-link to='/guide'>攻略</router-link>
          <router-view />
        </div>
      `
    }
</script>

五. 总结

1.路由传参,接收

    $router.push({
      name: 'home',
      params: { 数据1, 数据2,..... }
    });

    $router.push({
      name: 'home',
      query: { 数据1, 数据2,..... }
    })

    $router.push({
      path: '/home',
      query: { 数据1, 数据2,..... }
    })

接收:
$route.params.数据名
$route.query.数据名

2.params和query的区别

  1. query是通过url传递的参数.params不是
  2. query可以用name和path,params只能用name
  3. query只能传递字符串和数字,最多2000字符.params传递的数据类型和长度没有限制.
  4. query刷新还在.params刷新数据丢失.

3.props

props => 让组件和路由解耦.

  1. 布尔模式 => 让$route.params映射成组件的props.
  2. 对象模式 => 让指定对象的属性映射成组件的props.
    props: {
    数据1,
    数据2,
    数据3,
    }
    props: [数据1, 数据2, 数据3]
  3. 函数模式 => 可以指定任何的映射形式
    函数模式映射query => props: (route) => ({ msg: route.query.msg });

4.动态路由

动态路由 => 多个路径对应一个组件,组件根据不同的路径渲染不同的内容.
:path => 动态路径(路由参数) => 会自动变成当前url的路径.
routes匹配顺序是自上而下的,上面的选项匹配了,后面的就不匹配了.

    routes:[
      {
        path: '/:path',
        component: Home
      }
    ];
posted @ 2021-10-07 19:31  暗鸦08  阅读(126)  评论(0)    收藏  举报