Vue3基础2

1.Hooks

就是进行数据的封装,同一种类型的 数据 方法 计算属性 ,放在一起

命名规范 use+'功能名称'.ts 或.js

创建一个文件夹 hooks

1.useDog.ts

import { reactive,onMounted } from "vue";
import axios from "axios";


export default function () {
    //数据
    let dogList = reactive([
        "https://images.dog.ceo/breeds/pembroke/n02113023_14262.jpg",
    ]);
    //方法
    async function addDog() {
        try {
            let result = await axios.get("https://dog.ceo/api/breeds/image/random");

            dogList.unshift(result.data.message);
        } catch (error) {
            alert(error.message);
        }
    }


    onMounted(()=>{
        addDog();
    })
    
    return { dogList, addDog };
}

 2.useSum.ts

import { ref ,onMounted,computed} from "vue";

export default function () {
    //数据
    let sum = ref(0);
    let bigSum = computed(()=>{
        return sum.value*10;
    })
    
    //方法
    function changeSUM() {
        sum.value++;
    }



    onMounted(()=>{
        sum.value+=10;
    })
    

    //向外部提供东西
    return {
        sum,
        changeSUM,
        bigSum
    }

}

3.person.vue

<template>
  <div class="person">
    <h2>求和为:{{ sum }}  计算出十倍后的数:{{ bigSum }}</h2>
    <button @click="changeSUM">点我sum+1</button>

    <hr />
    <img v-for="item in dogList" :key="item" :src="item" alt="" />
    <br />
    <button @click="addDog">再来一只小狗</button>
  </div>
</template>



<!-- 会自动暴露出去 -->
<script  lang="ts" setup  name="Person">
    import useSum from '@/hooks/useSum';
    import useDog from '@/hooks/useDog';

    let {sum,changeSUM,bigSum} = useSum();
    let {dogList,addDog} = useDog();

</script>



<style scoped>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin: 0 5px;
}

img {
  height: 100px;
  margin-right: 10px;
}
</style>

2.Vue3 的路由

1.安装路由器

npm i vue-router

2.创建文件

3.router.ts

//创建一个路由器,并暴露出去

// 第一步:引入createRouter
import {createRouter,createWebHistory} from 'vue-router'

//引入一个一个可能要呈现的组件
import Home from '@/components/Home.vue'
import News from '@/components/News.vue'
import About from '@/components/About.vue'

//第二步: 创建路由器
const router = createRouter({
    history:createWebHistory(),//路由器的工作模式(稍后讲解)
    routes:[
        {
            path:'/home',
            component: Home
        },
        {
            path:'/news',
            component: News
        },
        {
            path:'/about',
            component: About
        }
    ]
})

//暴露出去
export default router

4.app.vue

<template>
  <div class="app">
    <h2 class="title">Vue 路由测试</h2>
    <!-- 导航区 -->
    <div class="navigate">
      <RouterLink to="/home" active-class="xiaozhupeiqi">首页</RouterLink>
      <RouterLink  to="/news" active-class="xiaozhupeiqi">新闻</RouterLink>
      <RouterLink to="/about" active-class="xiaozhupeiqi">关于</RouterLink>
    </div>

    <!-- 展示区 -->
     <div class="main-content">
          <RouterView></RouterView>
     </div>
  </div>
</template>

<script lang="ts" setup name="App">
import { RouterView,RouterLink } from 'vue-router';




</script>

<style scoped>

  /* App */
  .title {
    text-align: center;
    word-spacing: 5px;
    margin: 30px 0;
    height: 70px;
    line-height: 70px;
    background-image: linear-gradient(45deg, gray, white);
    border-radius: 10px;
    box-shadow: 0 0 2px;
    font-size: 30px;
  }
  .navigate {
    display: flex;
    justify-content: space-around;
    margin: 0 100px;
  }
  .navigate a {
    display: block;
    text-align: center;
    width: 90px;
    height: 40px;
    line-height: 40px;
    border-radius: 10px;
    background-color: gray;
    text-decoration: none;
    color: white;
    font-size: 18px;
    letter-spacing: 5px;
  }
  .navigate a.xiaozhupeiqi {
    background-color: #64967E;
    color: #ffc268;
    font-weight: 900;
    text-shadow: 0 0 1px black;
    font-family: 微软雅黑;
  }
  .main-content {
    margin: 0 auto;
    margin-top: 30px;
    border-radius: 10px;
    width: 90%;
    height: 400px;
    border: 1px solid;
  }

  .active{
     background-color: #ffc268;
  }
</style>

5.main.ts

//引入 createApp用于创建应用
import {createApp} from 'vue';
//引入 App 根组件
import App from './App.vue';

//引入路由器
import router from './router';


//创建一个应用
const app = createApp(App);


//使用一个插件
app.use(router);

//挂载整个应用到app容器中
app.mount('#app');

6.两个注意点

7.路由器的工作模式

 解决history模式404问题

 

8.to的两种写法

9.嵌套路由

1.Detail.vue

//创建一个路由器,并暴露出去

// 第一步:引入createRouter
import {createRouter,createWebHistory,createWebHashHistory} from 'vue-router'

//引入一个一个可能要呈现的组件
import Home from '@/pages/Home.vue'
import News from '@/pages/News.vue'
import About from '@/pages/About.vue'
import Detail from '@/pages/Detail.vue'

//第二步: 创建路由器
const router = createRouter({
    history:createWebHistory(),//History模式
    // history:createWebHashHistory(),//Hash模式
    routes:[
        {
            name: 'zhuye',
            path:'/home',
            component: Home
        },
        {
            name:'xinwen',
            path:'/news',
            component: News,
            children:[
                {
                    path:'detail',
                    component:Detail

                }
            ]
        },
        {
            name:'guanyu',
            path:'/about',
            component: About
        }
    ]
})

//暴露出去
export default router

 2.News.vue

<template>
    <div class="news">
      <!-- 导航区 -->
      <ul>
        <li v-for="news in newsList" :key="news.id"><RouterLink :to="{path:'/news/detail'}">{{ news.title }}</RouterLink></li>
      </ul>
        <!-- 展示取 -->
     <div class="news-content">
      <RouterView></RouterView>
     </div>
    </div>
  
  </template>
  
  <script setup lang="ts" name="News">
    import { nanoid } from 'nanoid';
    import { reactive } from 'vue';
    import { RouterView } from 'vue-router';

    const newsList = reactive([
      {id:nanoid(),title:'一种游戏',content:'西兰花'},
      {id:nanoid(),title:'一种水果',content:'学IT'},
      {id:nanoid(),title:'如何一夜暴富',content:'明天是周一'},
      {id:nanoid(),title:'震惊,玩玩没想到',content:'快过年了'},
    ]);
    


  </script>
  
  <style scoped>
  /* 新闻 */
  .news {
    padding: 0 20px;
    display: flex;
    justify-content: space-between;
    height: 100%;
  }
  .news ul {
    margin-top: 30px;
    list-style: none;
    padding-left: 10px;
  }
  .news li>a {
    font-size: 18px;
    line-height: 40px;
    text-decoration: none;
    color: #64967E;
    text-shadow: 0 0 1px rgb(0, 84, 0);
  }
  .news-content {
    width: 70%;
    height: 90%;
    border: 1px solid;
    margin-top: 20px;
    border-radius: 10px;
  }
  </style>

10.query参数

<template>
  <div class="news">
    <!-- 导航区 -->
    <ul>
      <li v-for="news in newsList" :key="news.id">
        <!-- 第一种写法 -->
        <!-- <RouterLink :to="`/news/detail?id=${news.id}&title=${news.title}&content=${news.content}`">{{ news.title }}</RouterLink> -->
         <!-- 第二种写法 -->
        <RouterLink :to="{
          // path: '/news/detail',
          name: 'xiangqing',
          query: {
            id: news.id,
            title: news.title,
            content: news.content
          }
        }">{{ news.title }}</RouterLink>
      </li>
    </ul>
    <!-- 展示取 -->
    <div class="news-content">
      <RouterView></RouterView>
    </div>
  </div>
</template>
  
  <script setup lang="ts" name="News">
import { nanoid } from "nanoid";
import { reactive } from "vue";
import { RouterView } from "vue-router";

const newsList = reactive([
  { id: nanoid(), title: "一种游戏", content: "西兰花" },
  { id: nanoid(), title: "一种水果", content: "学IT" },
  { id: nanoid(), title: "如何一夜暴富", content: "明天是周一" },
  { id: nanoid(), title: "震惊,玩玩没想到", content: "快过年了" },
]);
</script>
  
  <style scoped>
/* 新闻 */
.news {
  padding: 0 20px;
  display: flex;
  justify-content: space-between;
  height: 100%;
}
.news ul {
  margin-top: 30px;
  /* list-style: none; */
  padding-left: 10px;
}


.news li::marker {
    color: #64967E;
  }
.news li > a {
  font-size: 18px;
  line-height: 40px;
  text-decoration: none;
  color: #64967e;
  text-shadow: 0 0 1px rgb(0, 84, 0);
}
.news-content {
  width: 70%;
  height: 90%;
  border: 1px solid;
  margin-top: 20px;
  border-radius: 10px;
}
</style>
<template>
  <ul class="news-list">
    <li>编号:{{ query.id }}</li>
    <li>标题:{{ query.title }}</li>
    <li>内容:{{ query.content }}</li>
  </ul>
</template>
  
  <script setup lang="ts" name="Detail">
// 这是一个hooks,向这个组件实例暴露了一个函数
import { useRoute } from "vue-router";
import { toRefs } from "vue";

const route = useRoute();

const {query} = toRefs(route);
// console.log(route.query);



</script>
  
  <style scoped>
.news-list {
  list-style: none;
  padding-left: 20px;
}

.news-list > li {
  line-height: 30px;
}
</style>

11.params参数

<template>
  <div class="news">
    <!-- 导航区 -->
    <ul>
      <li v-for="news in newsList" :key="news.id">
        <!-- 第一种写法 纯字符串  -->
        <!-- <RouterLink :to="`/news/detail/${news.id}/${news.title}/${news.content}`">{{ news.title }}</RouterLink> -->
        <!-- 第二种写法 -->
        <RouterLink
          :to="{
            name: 'xiangqing',//params不允许path传参,只能用name  而且参数只能是基本类型
            params: {
              id: news.id,
              title: news.title,
              // content: news.content,
            },
          }"
          >{{ news.title }}</RouterLink
        >
      </li>
    </ul>
    <!-- 展示取 -->
    <div class="news-content">
      <RouterView></RouterView>
    </div>
  </div>
</template>
  
  <script setup lang="ts" name="News">
import { nanoid } from "nanoid";
import { reactive } from "vue";
import { RouterView } from "vue-router";

const newsList = reactive([
  { id: nanoid(), title: "一种游戏", content: "西兰花" },
  { id: nanoid(), title: "一种水果", content: "学IT" },
  { id: nanoid(), title: "如何一夜暴富", content: "明天是周一" },
  { id: nanoid(), title: "震惊,玩玩没想到", content: "快过年了" },
]);
</script>
  
  <style scoped>
/* 新闻 */
.news {
  padding: 0 20px;
  display: flex;
  justify-content: space-between;
  height: 100%;
}
.news ul {
  margin-top: 30px;
  /* list-style: none; */
  padding-left: 10px;
}

.news li::marker {
  color: #64967e;
}
.news li > a {
  font-size: 18px;
  line-height: 40px;
  text-decoration: none;
  color: #64967e;
  text-shadow: 0 0 1px rgb(0, 84, 0);
}
.news-content {
  width: 70%;
  height: 90%;
  border: 1px solid;
  margin-top: 20px;
  border-radius: 10px;
}
</style>
<template>
  <div class="news">
    <!-- 导航区 -->
    <ul>
      <li v-for="news in newsList" :key="news.id">
        <!-- 第一种写法 纯字符串  -->
        <!-- <RouterLink :to="`/news/detail/${news.id}/${news.title}/${news.content}`">{{ news.title }}</RouterLink> -->
        <!-- 第二种写法 -->
        <RouterLink
          :to="{
            name: 'xiangqing',//params不允许path传参,只能用name  而且参数只能是基本类型
            params: {
              id: news.id,
              title: news.title,
              // content: news.content,
            },
          }"
          >{{ news.title }}</RouterLink
        >
      </li>
    </ul>
    <!-- 展示取 -->
    <div class="news-content">
      <RouterView></RouterView>
    </div>
  </div>
</template>
  
  <script setup lang="ts" name="News">
import { nanoid } from "nanoid";
import { reactive } from "vue";
import { RouterView } from "vue-router";

const newsList = reactive([
  { id: nanoid(), title: "一种游戏", content: "西兰花" },
  { id: nanoid(), title: "一种水果", content: "学IT" },
  { id: nanoid(), title: "如何一夜暴富", content: "明天是周一" },
  { id: nanoid(), title: "震惊,玩玩没想到", content: "快过年了" },
]);
</script>
  
  <style scoped>
/* 新闻 */
.news {
  padding: 0 20px;
  display: flex;
  justify-content: space-between;
  height: 100%;
}
.news ul {
  margin-top: 30px;
  /* list-style: none; */
  padding-left: 10px;
}

.news li::marker {
  color: #64967e;
}
.news li > a {
  font-size: 18px;
  line-height: 40px;
  text-decoration: none;
  color: #64967e;
  text-shadow: 0 0 1px rgb(0, 84, 0);
}
.news-content {
  width: 70%;
  height: 90%;
  border: 1px solid;
  margin-top: 20px;
  border-radius: 10px;
}
</style>

12.Props路由配置

//创建一个路由器,并暴露出去

// 第一步:引入createRouter
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'

//引入一个一个可能要呈现的组件
import Home from '@/pages/Home.vue'
import News from '@/pages/News.vue'
import About from '@/pages/About.vue'
import Detail from '@/pages/Detail.vue'

//第二步: 创建路由器
const router = createRouter({
    history: createWebHistory(),//History模式
    // history:createWebHashHistory(),//Hash模式
    routes: [
        {
            name: 'zhuye',
            path: '/home',
            component: Home
        },
        {
            name: 'xinwen',
            path: '/news',
            component: News,
            children: [
                {
                    name: 'xiangqing',
                    path: 'detail',//问号代表可传可不传
                    component: Detail,
                    //第一种写法,将路由收到的所有params参数作为props传给路由组件
                    // props:true //params参数全部变成 params 

                    //第二种写法 函数写法 可以自己决定将什么作为props给路由组件
                    props(route){
                        // console.log(route)
                        return route.query
                    }

                    //第三种写法 写死了 
                    // props: {
                    //     a: 100,
                    //     b: 200
                    // }
                }
            ]
        },
        {
            name: 'guanyu',
            path: '/about',
            component: About
        }
    ]
})

//暴露出去
export default router
<template>
  <div class="news">
    <!-- 导航区 -->
    <ul>
      <li v-for="news in newsList" :key="news.id">
        <!-- 第一种写法 纯字符串  -->
        <!-- <RouterLink :to="`/news/detail/${news.id}/${news.title}/${news.content}`">{{ news.title }}</RouterLink> -->
        <!-- 第二种写法 -->
        <RouterLink
          :to="{
            name: 'xiangqing',//params不允许path传参,只能用name  而且参数只能是基本类型
            query: {
              id: news.id,
              title: news.title,
              content: news.content,
            },
          }"
          >{{ news.title }}</RouterLink
        >
      </li>
    </ul>
    <!-- 展示取 -->
    <div class="news-content">
      <RouterView></RouterView>
    </div>
  </div>
</template>
  
  <script setup lang="ts" name="News">
import { nanoid } from "nanoid";
import { reactive } from "vue";
import { RouterView } from "vue-router";

const newsList = reactive([
  { id: nanoid(), title: "一种游戏", content: "西兰花" },
  { id: nanoid(), title: "一种水果", content: "学IT" },
  { id: nanoid(), title: "如何一夜暴富", content: "明天是周一" },
  { id: nanoid(), title: "震惊,玩玩没想到", content: "快过年了" },
]);
</script>
  
  <style scoped>
/* 新闻 */
.news {
  padding: 0 20px;
  display: flex;
  justify-content: space-between;
  height: 100%;
}
.news ul {
  margin-top: 30px;
  /* list-style: none; */
  padding-left: 10px;
}

.news li::marker {
  color: #64967e;
}
.news li > a {
  font-size: 18px;
  line-height: 40px;
  text-decoration: none;
  color: #64967e;
  text-shadow: 0 0 1px rgb(0, 84, 0);
}
.news-content {
  width: 70%;
  height: 90%;
  border: 1px solid;
  margin-top: 20px;
  border-radius: 10px;
}
</style>
<template>
  <ul class="news-list">
    <li>编号:{{ id }}</li>
    <li>标题:{{ title }}</li>
    <li>内容:{{ content }}</li>
  </ul>
</template>
  
  <script setup lang="ts" name="Detail">
// import { useRoute } from 'vue-router';
// import { toRefs } from 'vue';
// const route = useRoute();
// const {params} =toRefs(route);

defineProps(["id", "title", "content"]);
</script>
  
  <style scoped>
.news-list {
  list-style: none;
  padding-left: 20px;
}

.news-list > li {
  line-height: 30px;
}
</style>

13.replace属性

<template>
  <div class="app">
    <h2 class="title">Vue 路由测试</h2>
    <!-- 导航区 -->
    <div class="navigate">
      <!-- 对象写法 路径跳转 -->
      <RouterLink :to="{path:'/home'}" active-class="active" replace>首页</RouterLink>
      <!-- 对象写法 名字跳转 --> 
      <RouterLink  :to="{name:'xinwen'}" active-class="active" replace>新闻</RouterLink>
      <!-- 字符串写法 -->
      <RouterLink to="/about" active-class="active" replace>关于</RouterLink>
    </div>

    <!-- 展示区 -->
     <div class="main-content">
          <RouterView></RouterView>
     </div>
  </div>
</template>

<script lang="ts" setup name="App">
import { RouterView,RouterLink } from 'vue-router';




</script>

<style scoped>

  /* App */
  .title {
    text-align: center;
    word-spacing: 5px;
    margin: 30px 0;
    height: 70px;
    line-height: 70px;
    background-image: linear-gradient(45deg, gray, white);
    border-radius: 10px;
    box-shadow: 0 0 2px;
    font-size: 30px;
  }
  .navigate {
    display: flex;
    justify-content: space-around;
    margin: 0 100px;
  }
  .navigate a {
    display: block;
    text-align: center;
    width: 90px;
    height: 40px;
    line-height: 40px;
    border-radius: 10px;
    background-color: gray;
    text-decoration: none;
    color: white;
    font-size: 18px;
    letter-spacing: 5px;
  }
  .navigate a.active {
    background-color: #64967E;
    color: #ffc268;
    font-weight: 900;
    text-shadow: 0 0 1px black;
    font-family: 微软雅黑;
  }
  .main-content {
    margin: 0 auto;
    margin-top: 30px;
    border-radius: 10px;
    width: 90%;
    height: 400px;
    border: 1px solid;
  }

  .active{
     background-color: #ffc268;
  }
</style>

14.编程式路由导航

脱离<RouterLink> 实现路由跳转

<template>
  <div class="news">
    <!-- 导航区 -->
    <ul>
      <li v-for="news in newsList" :key="news.id">
        <button @click="showNewsDetail(news)">查看新闻</button>
        <!-- 第二种写法 -->
        <RouterLink
          :to="{
            name: 'xiangqing',//params不允许path传参,只能用name  而且参数只能是基本类型
            query: {
              id: news.id,
              title: news.title,
              content: news.content,
            },
          }"
          
          >{{ news.title }}</RouterLink
        >
      </li>
    </ul>
    <!-- 展示取 -->
    <div class="news-content">
      <RouterView></RouterView>
    </div>
  </div>
</template>
  
  <script setup lang="ts" name="News">
import { nanoid } from "nanoid";
import { reactive } from "vue";
import { RouterView,useRouter } from "vue-router";

const newsList = reactive([
  { id: nanoid(), title: "一种游戏", content: "西兰花" },
  { id: nanoid(), title: "一种水果", content: "学IT" },
  { id: nanoid(), title: "如何一夜暴富", content: "明天是周一" },
  { id: nanoid(), title: "震惊,玩玩没想到", content: "快过年了" },
]);

const router = useRouter();

function showNewsDetail(news){
//对象写法 和 to同理
  router.push({
    name:'xiangqing',
    query:{
     ...news
    }
  })
  // router.replace({
  //   name:'xiangqing',
  //   query:{
  //    ...news
  //   }
  // })
}



</script>
  
  <style scoped>
/* 新闻 */
.news {
  padding: 0 20px;
  display: flex;
  justify-content: space-between;
  height: 100%;
}
.news ul {
  margin-top: 30px;
  /* list-style: none; */
  padding-left: 10px;
}

.news li::marker {
  color: #64967e;
}
.news li > a {
  font-size: 18px;
  line-height: 40px;
  text-decoration: none;
  color: #64967e;
  text-shadow: 0 0 1px rgb(0, 84, 0);
}
.news-content {
  width: 70%;
  height: 90%;
  border: 1px solid;
  margin-top: 20px;
  border-radius: 10px;
}
</style>

15.重定向

//创建一个路由器,并暴露出去

// 第一步:引入createRouter
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'

//引入一个一个可能要呈现的组件
import Home from '@/pages/Home.vue'
import News from '@/pages/News.vue'
import About from '@/pages/About.vue'
import Detail from '@/pages/Detail.vue'

//第二步: 创建路由器
const router = createRouter({
    history: createWebHistory(),//History模式
    // history:createWebHashHistory(),//Hash模式
    routes: [
        {
            name: 'zhuye',
            path: '/home',
            component: Home
        },
        {
            name: 'xinwen',
            path: '/news',
            component: News,
            children: [
                {
                    name: 'xiangqing',
                    path: 'detail',//问号代表可传可不传
                    component: Detail,
                    //第一种写法,将路由收到的所有params参数作为props传给路由组件
                    // props:true //params参数全部变成 params 

                    //第二种写法 函数写法 可以自己决定将什么作为props给路由组件
                    props(route){
                        // console.log(route)
                        return route.query
                    }

                    //第三种写法 写死了 
                    // props: {
                    //     a: 100,
                    //     b: 200
                    // }
                }
            ]
        },
        {
            name: 'guanyu',
            path: '/about',
            component: About
        },
        {
            path:'/',//重定向
            redirect:'/home'
        }
    ]
})

//暴露出去
export default router

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值