最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Vue3官网实现(总结)

    正文概述 掘金(全世界我最酷)   2021-03-19   1310

    一、技术细节

    • 使用Vue3 Components API 和Typescript制作了四个组件 。
    • 官网代码支持高亮显示。
    • 展示折叠组件封装。
    • 使用 Vite 的 dev 命令和 build 命令进行开发与部署
    • 尝试使用rollup进行项目库打包,并发布npm包。
    • 尝试使用shell脚本实现自动化部署

    二、成果展示

    此处为GitHub源码地址

    点击此处效果预览

    1.首页 Vue3官网实现(总结)

    2.介绍 Vue3官网实现(总结)

    3.switch Vue3官网实现(总结)

    4.button Vue3官网实现(总结)

    Vue3官网实现(总结)

    5.modal

    Vue3官网实现(总结)

    6.tab Vue3官网实现(总结)

    三:学后总结

    1.setup(compoents ApI)完成一次传值

    //子组件
    <script lang="ts">
    export default {
      props: {
        value: Boolean, //接收父组件的值
      },
      setup(props, context) {
        const toggle = () => {
          context.emit("update:value", !props.value); //触发事件后值会返回给父组件
        };
        return { toggle };//必须return 不然组件无法拿到toggle
      }
    };
    </script>
    
    //父组件
    <script lang="ts">
    import Switch from '../lib/Switch.vue' //导入组件
    import { ref} from 'vue'
    export default {
      components: {Switch},//接收组件
      setup() {
        const bool = ref(false)//父组件要传给子组件的值,默认为false
        return {
          bool //将默认值Return
        }
      }
    }
    </script>
    

    2.ref(使变量另行具备响应式)

    import {ref} from 'vue'
    const value = ref<boolean>(false)
    return {
        value
    }
    
    

    3.v-model

    <switch :value='x' @update:value="x=$event"/>
      
    <switch v-model:value="y"/>
    

    4.vue-router

    //全局安装vue-router后,在router.ts这个入口文件里面创建 history和router
    import {createRouter, createWebHashHistory} from 'vue-router';
    
    const history = createWebHashHistory() //创建 history
    export const router = createRouter({ //创建 router
      history: history,
      routes: [
        {path: '/', component: Home},
        {path: '/doc', component: Doc,children:[//嵌套路由
            {path:'',redirect:'/doc/Intro'},
            {path:'intro',component:Intro},
          ]}
      ]
    })
    
    添加<router-view>//要告诉app组件,路由的组件内容在哪里显示
    添加<router-link>//跳转页面
    

    5.用 provide 和 inject 实现切换功能

    //父组件做标记
    import {ref,provide} from 'vue'
    export default {
      name: 'App',
      setup(){
        const width = document.documentElement.clientWidth;//获取当前屏幕宽度
        const menuVisible = ref(width > 500);
        provide('menuVisible',menuVisible)//父组件做标记
      }
    }
    </script>
    
    //子组件获取数据
    import {inject,Ref} from 'vue'
    setup(){
       const menuVisible = inject<Ref<boolean>>('menuVisible')// inject接收值
     }
    

    6.inheritAttrs:false(组件内部不在继承调用时传来的属性)

    属性继承(继承到根元素): 父组件button的属性会直接继承在子组件的button上的最外层div,就意味你在父组件上面写的事件也直接会直接继承在子组件的最外层

    //如何继承到子组件的button上(批量绑定属性)
    //子组件里面写上继承属性false(inheritAttrs:false)
    <script lang="ts">
    export default {
        inheritAttrs:false
    }  
    </script>
    
    //让div里的button(子组件)绑定$attrs(这个绑定的属性是写在父组件里面的所有属性)
    <div>
    <button v-bind = "$attrs"></button>
    </div>
    
    //如何分两部分继承呢?(一部分属性继承在div上,一部分继承在button上)
    //子组件
    <template>
      <div :size="size">//继承在div
        <Button v-bind="rest"></Button>//继承在button
      </div>
    </template>
    
    <script lang="ts">
    export default {
       inheritAttrs:false,
       setup(props,context){
       const {size,...rest} = context.attrs//从context.attrs里面拿到两部份值
       return {size,rest}//return出去
       }
    }
    </script>
    

    7.具名插槽

    //父组件
    <template v-slot:context>
    <div>
    哈喽 我是你爸爸
    </div>
    </template>
    
    
    <template v-slot:title>
    <strong>
    我是一个标题
    </strong>
    </template>
    
    //子组件
    <slot name="title"/>
    
    <main>
    <slot name="context"/>
    </main>
    

    8.Teleport

    (任意传送门Teleport 是一种能够将我们的模板移动到 DOM 中 Vue app 之外的其他位置的技术)

    //直接将这一块传送到Dom节点里面的body
    <Teleport to = "body">
    <div>
    一大块代码
    </div>
    </Teleport>
    

    9.createApp

    使用createApp这个 API返回一个应用实例,并且可以通过链条的方式继续调用其他的方法)

    Vue3官网实现(总结)

    10.如何确认子组件类型(防御性编程)检查context.slots.default()数组

    Vue3官网实现(总结)

    Vue3官网实现(总结)

    Vue3官网实现(总结)

    11.ui库不能使用scoped ,每一个class 必须添加前缀,css最小影响原则

    12.一些用到的钩子

    onMounted  //挂载后做的操作,只会在第一次挂载渲染
    onUpdated  //第一次渲染后的每次更新做的操作
    watchEffect //上面两个的结合,相当于监听,只要有变化就运行
    

    13.TypeScript泛型

    const indicator = ref<HTMLDivElement>(null) //null类型
    

    14.获取宽高和位置的API(el.getBoundingClientRect())

    const {width,height,top,left} = el.getBoundingClientRect()//获取el元素的宽高等
    

    15.ES6析构赋值的重命名语法

    const {left:left1} = x.getBoundingClientRect()
    const {left:left2} = y.getBoundingClientRect()
    

    16.引入Github的Markdown

    markdown GITHub地址

    yarn add github-markdown-css //安装
    import 'github-markdown-css' //在mian.ts引入,就可以直接使用
    
    <template>
      <article class="markdown-body" >//加入class="markdown-body"就可以
       <h1>安装</h1>
       <p>打开终端运行下面命令</P>
      </article>
    </template>
    
    

    效果:

    Vue3官网实现(总结)

    17.如何显示源码 使用vue-loader的Custom Blocks

    <1>.在vite.config.ts文件里面添加一些配置

    <2>.抽离用户需要拷贝的代码(子组件),并且在子组件里面写入一个<dem>标签,比如(<dem>支持隐藏</dem>)

    <3>.然后在父组件里面引用,作为组件在components:{}引用一次,还得作为变量在setup(){}里面return出来一次,然后在父组件的<pre>标签里面使用。

    比如:<pre>{{Switch1Demo.__demo}}</pre>

    就可以显示出子组件里面除了<dem>的所有源代码

    //vite.config.ts文件里面添加一些配置
    
    // @ts-nocheck
    
    
    import { md } from "./plugins/md";
    import fs from 'fs'
    import {baseParse} from '@vue/compiler-core'
    
    export default {
      base:'./',
      assetsDir:'assets',
      plugins: [md()],
      vueCustomBlockTransforms: {
        demo: (options) => { //组件含有demo标签的话会做以下操作
          const { code, path } = options
          const file = fs.readFileSync(path).toString()
          const parsed = baseParse(file).children.find(n => n.tag === 'demo')
          const title = parsed.children[0].content
          const main = file.split(parsed.loc.source).join('').trim()
          return `export default function (Component) {
            Component.__sourceCode = ${//将组件除了<dem>标签外的所有源代码放在组件的__sourceCode里面 (下划线是为了隐藏起来)
            JSON.stringify(main) //源代码
          }
            Component.__sourceCodeTitle = ${JSON.stringify(title)}
          }`.trim()
        }
      }
    };
    
    

    18.如何高亮源码 使用 prismjs库 和 vue的 v-html

    1.prismjs官网

    2.我使用的是node.js,所以使用文档中node的方法

    3.准备工作

    yarn add prismjs //安装这个库
    import  'prismjs' //在使用源码的地方引入
    import  'prismjs/themes/prism.css'  //引入css,跟prism.css同级的CSS是其他主体,也可以试试,比如prism.css改成prism-okaidia.css等
    console.log(window.Prism) //可以log出啦,但是会webstorm会在Prism下面报错,解决方法往下
    
    const Prism = (window as any).Prism //这样Prism就是any类型,就可以随意使用,临时方法,有更好的可以自己使用
    
    //记得在setup() {return Prism }
    
    
    1. 看文档如何使用

    Vue3官网实现(总结)

    //使用例子
    <pre class="language-html" 
    v-html="Prism.highlight(props.component.__sourceCode, Prism.languages.html, 'html'" /> 
    
    //class="language-html"是代码的背景
    
    

    题外话:

    Vue3官网实现(总结)

    19.用到的一些网页链接

    借鉴Web布局的网址

    调节渐变色生成css代码

    Fonts.css -- 跨平台中文字体解决方案


    起源地下载网 » Vue3官网实现(总结)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元