input v-model="msg" type="text"> input :value="msg" @input="msg=$event.target.valu..."/>

第三部分 Vue讲解(22-25)(代码版)

7,464次阅读
没有评论

共计 15232 个字符,预计需要花费 39 分钟才能阅读完成。

22. 自定义指令

22.1 自定义指令基本语法

22.1.2 自定义指令.vue

template>
  div id="app">
    
    input v-model="msg" type="text">
    input :value="msg" @input="msg=$event.target.value" type="text">
  div>
template>



script>
export default {}
script>


style scoped>

style>

22.1.2 App.vue

template>
  div>
    h1 v-color="color1">自定义指令 1 h1>
    h1 v-color="color2">自定义指令 2 h1>
    input v-focus ref="inp" type="text">

  div>
template>

script>
export default {
  
  


  directives:{
    
    focus:{
      inserted(el){
        el.focus()
      }
    },
    color:{
      
      inserted(el,binding){
        
        
        el.style.color=binding.value
      },
    
      update(el,binding){
        console.log("指令的值修改了")
        el.style.color=binding.value
      }
    }
  },
  data(){
    return{
      color1:"red",
      color2:"orange"
    }
  }
}
script>

style>
style>

22.2 自定义指令(v-loading 指令封装)

22.2.1 自定义指令

template>
  div id="app">
    
    input v-model="msg" type="text">
    input :value="msg" @input="msg=$event.target.value" type="text">
  div>
template>

script>
export default {}
script>


style scoped>

style>

22.2.2 App.vue

template>
  div class="box" v-loading="isloading">
    ul>
      li v-for="item in list" :key="item.id" class="news">
        div class="left">
          div class="title">{{item.title}}div>
          div class="info">
            span>{{item.source}}span>
            span>{{item.time}}span>
          div>
        div>
        div class="right">
          img :src="item.img" alt="">
        div>
      li>
    ul>
  div>
template>

script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js">script>

script>

export default {
  data() {
    return {
      list: [],
      isloading: true
    }
  },
  async created() {
    
    const res = await axios.get("http://hmajax.itheima.net/api/news")
    setTimeout(() => {
      
      this.list = res.data.data
      this.isLoading = false
    }, 2000)
  },
  directives: {
    loading: {
      inserted(el, binding) {
        binding.value ? el.classList.add("loading") : el.classList.remove('loading')
      },
      update(el, binding) {
        binding.value ? el.classList.add("loading") : el.classList.remove('loading')
      }
    }
  }

}
script>

style>
.loading:before {
  content: "";
  position: absolute;
  left: 0;
  width: 100%;
  height: 100%;
  background: #fff url("./img/loading.gif") no-repeat;
}
style>

23. 插槽

23.1 默认插槽

23.1.1 默认插槽

template>
  div id="app">
    
    input v-model="msg" type="text">
    input :value="msg" @input="msg=$event.target.value" type="text">
  div>
template>

script>
export default {}
script>


style scoped>

style>

23.1.2 App.vue

template>
  div>


    MyDialog>确定要删除吗?MyDialog>
    MyDialog>确定要退出系统吗?MyDialog>
  div>
template>



script>
import MyDialog from "./components/MyDialog"


export default {
  data() {
    return {}
  },
  components: {
    MyDialog
  }

}
script>

style>
.loading:before {
  content: "";
  position: absolute;
  left: 0;
  width: 100%;
  height: 100%;
}
style>

23.1.3 MyDialog.vue

template>
div class="dialog">

  div class="dialog-header">
    h3>友情提示h3>
    span class="close">Xspan>
  div>


  div class="dialog-content">
    

    slot>slot>

  div>


  div class="dialog-footer">
    button>取消button>
    button>确认button>
  div>
div>
template>

script>
export default {
  name: "MyDialog"
}
script>

style scoped>

style>

23.2 后备内容(插槽默认的内容)

23.2.1 后备内容

template>
  div id="app">
    
    input v-model="msg" type="text">
    input :value="msg" @input="msg=$event.target.value" type="text">
  div>
template>

script>
export default {}
script>


style scoped>

style>

23.2.2 App.vue

template>
  div>


    MyDialog>确定要删除吗?MyDialog>
    MyDialog>确定要退出系统吗?MyDialog>
    MyDialog>MyDialog>   
  div>
template>



script>
import MyDialog from "./components/MyDialog"


export default {
  data() {
    return {}
  },
  components: {
    MyDialog
  }

}
script>

style>
.loading:before {
  content: "";
  position: absolute;
  left: 0;
  width: 100%;
  height: 100%;
}
style>

23.2.3 MyDialog.vue

template>
div class="dialog">

  div class="dialog-header">
    h3>友情提示h3>
    span class="close">Xspan>
  div>


  div class="dialog-content">
    

    slot>后备内容slot>

  div>


  div class="dialog-footer">
    button>取消button>
    button>确认button>
  div>
div>
template>

script>
export default {
  name: "MyDialog"
}
script>

style scoped>

style>

23.3 具名插槽

23.3.1 具名插槽

template>
  div id="app">
    
    input v-model="msg" type="text">
    input :value="msg" @input="msg=$event.target.value" type="text">
  div>
template>


script>
export default {}
script>


style scoped>

style>

23.3.2 App.vue

template>
  div>
    
    
       
    MyDialog>
      
      template #head>
        div>大标题div>
      template>

      template #content>
        div>内容文本div>
      template>

      template #footer>
        template>
          button>确认button>
          button>取消button>
        template>
      template>
    MyDialog>
  div>
template>



script>
import MyDialog from "./components/MyDialog"


export default {
  data() {
    return {}
  },
  components: {
    MyDialog
  }

}
script>

style>
.loading:before {
  content: "";
  position: absolute;
  left: 0;
  width: 100%;
  height: 100%;
}
style>

23.3.3 MyDialog.vue

template>
  div class="dialog">
    
    div class="dialog-header">
      slot>slot>
    div>

    
    div class="dialog-content">
        slot name="content">slot>
    div>

    
    div class="dialog-footer">
      slot name="footer">slot>
    div>
  div>
template>

script>
export default {
  name: "MyDialog"
}
script>

style scoped>

style>

23.4 作用域插槽

23.4.1 作用域插槽

template>
  div id="app">
    
    input v-model="msg" type="text">
    input :value="msg" @input="msg=$event.target.value" type="text">
  div>
template>




script>
export default {}
script>


style scoped>

style>

23.4.2 App.vue

template>
  div>
    MyTable :data="list">


      template #default="obj">
        {{obj}}
        button @click="del(obj.row.id)">删除button>
      template>
    MyTable>

    MyTabe :data="list2">
      template #default="{row}">

        button @click="show(row)">查看button>
      template>
    MyTabe>
  div>
template>



script>
import MyTable from "./components/MyTable"
export default {
  data() {
    return {
      list: [
        {id: 1, name: "yuer", age : 18},
        {id: 2, name: "yuer2", age : 19},
        {id: 3, name:"yuer3", bag :17},
      ],
      list2: [
        {id: 1, name: "yuer", age : 18},
        {id: 2, name: "yuer2", age : 19},
        {id: 3, name:"yuer3", bag :17},
      ]
    }
  },
  methods:{
    del(id){
      this.list=this.list.filter(item=>item)
    },
    show(row){
      console.log(row);
    }
  },
  components: {
    MyTable
  }

}
script>

style>
.loading:before {
  content: "";
  position: absolute;
  left: 0;
  width: 100%;
  height: 100%;
}
style>

23.4.3 MyTable.vue

template>
  div>
    tr v-for="(item,index) in data" :key="item.id">
      td>{{index + 1}}td>
      td>{{item.name}}td>
      td>{{item.age}}td>
      td>

        slot :row="item" msg="测试数据">slot>



      td>
    tr>
  div>
template>

script>
export default {
  name: "MyDialog"
}
script>

style scoped>
style>

24. 路由

24.1 单页应用程序 & 路由简单介绍

template>
  div id="app">
    
    input v-model="msg" type="text">
    input :value="msg" @input="msg=$event.target.value" type="text">
  div>
template>










script>
export default {}
script>


style scoped>

style>

24.2 VueRouter 的介绍

template>
  div id="app">
    
    input v-model="msg" type="text">
    input :value="msg" @input="msg=$event.target.value" type="text">
  div>
template>



script>
export default {}
script>


style scoped>

style>

24.3 组件存放目录问题

template>
  div id="app">
    
    input v-model="msg" type="text">
    input :value="msg" @input="msg=$event.target.value" type="text">
  div>
template>

script>
export default {}
script>


style scoped>
style>

24.4 VueRouter 的完整实现步骤

24.4.1 main.js

import Vue from 'vue'
import App from './App.vue'






import VueRouter from "vue-router";

import Find from "./views/Find.vue"
import My from "./views/My.vue"
import Friend from "./views/Friend.vue"


Vue.use(VueRouter)   


const r = new VueRouter({
        
        
        
        routes: [
            {path: "/find", component: Find},  
            {path: "/my", component: My},
            {path: "/friend", component: Friend},
        ]
    }
)



Vue.config.productionTip = false

new Vue({
    render: h => h(App),
    
    router: r   
}).$mount('#app')

24.4.2 App.vue

template>
  div>
    div class="footer_wrap">
      a href="#/find">发现音乐a>
      a href="#/my">我的音乐a>
      a href="#/friend">朋友a>
    div>

    div class="top">
      
      
      router-view>router-view>
    div>
  div>
template>

script>
export default {}
script>

style>
.footer_wrap {
  position: fixed;
  left: 0;
  top: 0;
  display: flex;
  width: 100%;
  height: 100%;
}
style>

24.4.3 Find.vue

template>
  div>
    p>发现音乐p>
    p>发现音乐p>
    p>发现音乐p>
  div>
template>

script>
export default {
  name: "FindMusic"   
}
script>

style scoped>

style>

24.4.4 My.vue

template>
div>
  p>我的歌单p>
  p>我的歌单p>
  p>我的歌单p>
div>
template>

script>
export default {
  name: "MyMusic"  
}
script>

style scoped>

style>

24.4.5 Friend.vue

template>
div>
  p>朋友歌单p>
  p>朋友歌单p>
  p>朋友歌单p>
div>
template>

script>
export default {
  name: "FriendMusic"  
}
script>

style scoped>

style>

总结:
路由的使用步骤(5+2)
5 步基础步骤:
(1)项目终端中下载
(2)(3)(4)(5)在 main.js 文件中实现
2 步核心步骤:
(1)创建子组件 vue 文件,在 main.js 文件中导入,并将这些文件和路径地址进行匹配;
(2)在根组件中使用这些子组件,App.js 文件

25. 路由进阶

25.1 路由的封装抽离

template>
  div id="app">
    
    input v-model="msg" type="text">
    input :value="msg" @input="msg=$event.target.value" type="text">
  div>
template>

script>
export default {}
script>


style scoped>

style>

25.1.1 router 目录—index.js(路由的封装)











import Vue from 'vue'
import VueRouter from "vue-router";






import Find from "@/views/Find"
import My from "@/views/My"
import Friend from "@/views/Friend"



Vue.use(VueRouter)   


const router = new VueRouter({
        
        
        
        routes: [
            {path: "/find", component: Find},  
            {path: "/my", component: My},
            {path: "/friend", component: Friend},
        ]
    }
)


export default router

25.1.2 main.js 导入封装路由

import Vue from 'vue'
import App from './App.vue'


import router from './router/index'

Vue.config.productionTip = false

new Vue({
    render: h => h(App),
    router   
    
}).$mount('#app')

25.1.3 App.vue

template>
  div>
    div class="footer_wrap">
      a href="#/find">发现音乐a>
      a href="#/my">我的音乐a>
      a href="#/friend">朋友a>
    div>

    div class="top">
      
      
      router-view>router-view>
    div>
  div>
template>

script>
export default {}
script>

style>
.footer_wrap {
  position: fixed;
  left: 0;
  top: 0;
  display: flex;
  width: 100%;
  height: 100%;
}
style>

25.1.4 Find.vue

template>
  div>
    p>发现音乐p>
    p>发现音乐p>
    p>发现音乐p>
  div>
template>

script>
export default {
  name: "FindMusic"   
}
script>

style scoped>

style>

25.1.5 Friend.vue

template>
div>
  p>朋友歌单p>
  p>朋友歌单p>
  p>朋友歌单p>
div>
template>

script>
export default {
  name: "FriendMusic"  
}
script>

style scoped>

style>

25.1.6 My.vue

template>
div>
  p>我的歌单p>
  p>我的歌单p>
  p>我的歌单p>
div>
template>

script>
export default {
  name: "MyMusic"  
}
script>

style scoped>

style>

25.2 使用 router-link 替代 a 标签实现高亮

25.2.1 使用 router-link 替代高亮

template>
  div id="app">
    
    input v-model="msg" type="text">
    input :value="msg" @input="msg=$event.target.value" type="text">
  div>
template>





script>
export default {}
script>


style scoped>

style>

25.2.2 index.js











import Vue from 'vue'
import VueRouter from "vue-router";






import Find from "@/views/Find"
import My from "@/views/My"
import Friend from "@/views/Friend"



Vue.use(VueRouter)   


const router = new VueRouter({
        
        
        
        routes: [
            {path: "/find", component: Find},  
            {path: "/my", component: My},
            {path: "/friend", component: Friend},
        ],
    
    linkActiveClass: 'active',  
    linkExactActiveClass:'exact-active'   
    }
)


export default router

25.2.3 main.js

import Vue from 'vue'
import App from './App.vue'


import router from './router/index'

Vue.config.productionTip = false

new Vue({
    render: h => h(App),
    router   
    
}).$mount('#app')

25.2.4 App.vue

template>
  div>
    div class="footer_wrap">
      router-link to="/find">发现音乐歌单router-link>
      router-link to="/my">我的歌单router-link>
      router-link to="/friend">朋友的歌单router-link>
    div>

    div class="top">


      router-view>router-view>
    div>
  div>
template>

script>
export default {}
script>

style>
body{
  margin:0;
  padding:0;
}
.footer_wrap {
  position: relative;
  left: 0;
  top: 0;
  display: flex;
  width: 100%;
  text-align:center;
  background-color: #333;
  color: #ccc;
}
.footer_wrap a{
  flex:1;
  text-decoration: none;
  padding:20px 0;
  line-height: 20px;
  background-color: #333;
  color:#ccc;
  border:1px solid black;
}



.footer_wrap a.active{
  background-color: purple;
}







.footer_wrap a:hover{
  background-color: #555;
}
style>

子组件与上节相同

25.3 声明式导航 - 跳转传参

25.3.1 声明式导航 - 跳转传参

template>
  div id="app">
    
    input v-model="msg" type="text">
    input :value="msg" @input="msg=$event.target.value" type="text">
  div>
template>









script>
export default {}
script>


style scoped>

style>

25.3.2 router—index.js

import Vue from 'vue'
import VueRouter from "vue-router";

import Home from "@/views/Home"
import Search from "@/views/Search"

Vue.use(VueRouter)   
const router = new VueRouter({
        routes: [
            {path:"/home",component:Home},
            {path:"/search/:words",component:Search}
        ],
    }
)


export default router

25.3.3 main.js

import Vue from 'vue'
import App from './App.vue'

import router from './router/index'

Vue.config.productionTip = false

new Vue({
    render: h => h(App),
    router   
    
}).$mount('#app')

25.3.4 App.vue

template>
  div id="app">
    div class="link">
      router-link to="/find">首页router-link>
      router-link to="/my">搜索页router-link>
    div>
    
    router-view>router-view>
  div>
template>

script>
export default {}
script>

style>
.link{
  height:50px;
  line-height:50px;
  background-color: #495150;
  display:flex;
  margin:-8px -8px 0 -8px;
  margin-bottom: 50px;
}

.footer_wrap {
  position: relative;
  left: 0;
  top: 0;
  display: flex;
  width: 100%;
  text-align: center;
  background-color: #333;
  color: #ccc;
}

.footer_wrap a {
  flex: 1;
  text-decoration: none;
  padding: 20px 0;
  line-height: 20px;
  background-color: #333;
  color: #ccc;
  border: 1px solid black;
}




.footer_wrap a.active {
  background-color: purple;
}








.footer_wrap a:hover {
  background-color: #555;
}
style>

25.3.5 Home.vue

template>
  div class="home">
    div class="logo-box">div>
    div class="search-box">
      input type="text">
      button>搜索一下button>
    div>

    div class="hot-link">
      热门搜索:router-link to="/search/ 发现歌单 "> 发现歌单router-link>
      router-link to="/search/ 我的歌单 "> 我的歌单router-link>
      router-link to="/search/ 朋友歌单 "> 朋友歌单router-link>

    div>
  div>
template>

script>
export default {
  name: "HomeComponent"
}
script>

style scoped>
.logo-box{

}
style>

25.3.6 Search.vue

template>
  div class="search">
    
    
    
    p>搜索关键字:{{$route.params.words}}p>
    p>搜索结果:p>
    ul>
      li>..............li>
      li>..............li>
      li>..............li>
      li>..............li>
      li>..............li>
      li>..............li>
    ul>
  div>
template>

script>
export default {
  name: "SearchComponent",
  created() {
    
    
    

    
    
    console.log(this.$route.params.words)
  }
}
script>

style scoped>
.search {
  width: 400px;
  height: 240px;
  padding: 0 20px;
}
style>

25.4 Vue 路由 - 重定向

25.4.1 Vue 路由 - 重定向

template>
  div id="app">
    
    input v-model="msg" type="text">
    input :value="msg" @input="msg=$event.target.value" type="text">
  div>
template>




script>
export default {}
script>


style scoped>

style>

25.4.2 router—index.js

import Vue from 'vue'
import VueRouter from "vue-router";

import Home from "@/views/Home"
import Search from "@/views/Search"
import NotFound from "@/views/NotFound"

Vue.use(VueRouter)   
const router = new VueRouter({
        
        
        mode: "history",  
        routes: [
            {path: "/", redirect: '/home'},
            {path: "/home", component: Home},
            {path: "/search/:words", component: Search},
            {path: "*", component: NotFound}  
        ],
    }
)


export default router

25.4.3 App.vue

template>
  div id="app">
    div class="link">
      router-link to="/find">首页router-link>
      router-link to="/my">搜索页router-link>
    div>
    
    router-view>router-view>
  div>
template>

script>
export default {}
script>

style>
.link{
  height:50px;
  line-height:50px;
  background-color: #495150;
  display:flex;
  margin:-8px -8px 0 -8px;
  margin-bottom: 50px;
}

.footer_wrap {
  position: relative;
  left: 0;
  top: 0;
  display: flex;
  width: 100%;
  text-align: center;
  background-color: #333;
  color: #ccc;
}

.footer_wrap a {
  flex: 1;
  text-decoration: none;
  padding: 20px 0;
  line-height: 20px;
  background-color: #333;
  color: #ccc;
  border: 1px solid black;
}




.footer_wrap a.active {
  background-color: purple;
}








.footer_wrap a:hover {
  background-color: #555;
}
style>

25.4.4 NotFound.vue

template>
div>
  404
div>
template>

script>
export default {
  name: "NotFound"
}
script>

style scoped>

style>

其他文件见 25.3

25.5 编程式导航

25.5.1 基本跳转

template>
  div id="app">
    
    input v-model="msg" type="text">
    input :value="msg" @input="msg=$event.target.value" type="text">
  div>
template>





script>
export default {}
script>


style scoped>

style>

25.5.2 路由传参

template>
  div id="app">
    
    input v-model="msg" type="text">
    input :value="msg" @input="msg=$event.target.value" type="text">
  div>
template>

script>
export default {}
script>


style scoped>

style>

25.5.3 index.js

import Vue from 'vue'
import VueRouter from "vue-router";

import Home from "@/views/Home"
import Search from "@/views/Search"
import NotFound from "@/views/NotFound"

Vue.use(VueRouter)   
const router = new VueRouter({
        
        
        mode: "history",  
        routes: [
            {path: "/", redirect: '/home'},
            {path: "/home", component: Home},
            {name:"search", path: "/search/:words?", component: Search},
            {path: "*", component: NotFound}  
        ],
    }
)


export default router

25.5.4 main.js

import Vue from 'vue'
import App from './App.vue'

import router from './router/index'

Vue.config.productionTip = false

new Vue({
    render: h => h(App),
    router   
    
}).$mount('#app')

25.5.5 Home.vue

template>
  div class="home">
    div class="logo-box">div>
    div class="search-box">
      input v-model="inpValue" type="text">
      button @click="goSearch">搜索一下button>
    div>

    div class="hot-link">
      热门搜索:router-link to="/search/ 发现歌单 "> 发现歌单router-link>
      router-link to="/search/ 我的歌单 "> 我的歌单router-link>
      router-link to="/search/ 朋友歌单 "> 朋友歌单router-link>

    div>
  div>
template>

script>
export default {
  name: "HomeComponent",
  data() {
    return {
      inpValue: ""
    }
  },
  methods: {
    goSearch() {
      
      
      
      
      

      
      
      
      
      
      
      
      

      
      
      this.$router.push({
        name: 'search',
        
        params: {
          words: this.inpValue
        }

      })
    }

  }

}
script>

style scoped>
.logo-box {
  height: 150px;
  background: url('@/assets/logo.jpg') no-repeat center;
}

.search-box {
  display: flex;
  justify-content: center;
}
style>

25.5.6 Search.vue

template>
  div class="search">
    
    
    
    p>搜索关键字:{{$route.params.words}}p>

    p>搜索结果:p>
    ul>
      li>..............li>
      li>..............li>
      li>..............li>
      li>..............li>
      li>..............li>
      li>..............li>
    ul>
  div>
template>

script>
export default {
  name: "SearchComponent",
  created() {
    
    
    

    
    
    console.log(this.$route.params.words)
  }
}
script>

style scoped>
.search {
  width: 400px;
  height: 240px;
  padding: 0 20px;
}
style>

原文地址: 第三部分 Vue 讲解(22-25)(代码版)

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于2024-10-03发表,共计15232字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)