5.30号,记录一下本次课设学到的一些知识点:

  1. vue无法检测到对象内部数据的变化,即便使用了deep:true标签,也只能检测到对象中第一层属性对应的值的变化,而对于对象内的对象,他就无法检测到他的变化了,只能通过this.$set(1,2,3)来改变对象的属性对应的值。数组则通过数组的四个方法来进行修改,不通过直接获取其index来改变。这样子才能被检测到改变。
  2. 如何使用iconpark(字节跳动的矢量图标库)
    首先现在vue中导入他的组件
    1
    2
    3
    4
    //vue2
    npm i @icon-park/vue
    //vue3
    npm i @icon-park/vue-next
    通过上述导入整个组件后,再在每个使用的地方专门做引用。
    使用方法:在具体的组件内,导入你所需要的图标。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    /**
    * 引入时使用驼峰式命名
    * import {Alarm} from '@icon-park/vue';
    * components: { Alarm }
    *
    * 使用时使用小写
    *<alarm theme="outline" size="24" fill="#f60" />
    */
    import {Alarm} from '@icon-park/vue';
    image
  3. 在vue中获取获取图片有两种方式。
  • 在 JavaScript 被导入或在 template/CSS 中通过相对路径被引用。这类引用会被 webpack 处理。
  • 放置在 public 目录下或通过绝对路径被引用。这类资源将会直接被拷贝,而不会经过 webpack 的处理。
    而经过webpack处理后的图片将会被隐匿,也就是他在项目中的位置会被添加字符串隐藏掉。因此多采用require的方式去引入图片。
    例如:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <img :src="logo" />

    export default {
    data(){
    return {
    //相对路径不一定都是./,也可能是../,按照图片存放位置来决定
    logo: require("./imgs/logo.png")
    }
    }
    }
    这中是通过require的方式引入。而这中引入都是静态的,也就是他的路径已经写死,引入后他的编码方式也会被webpack修改。所以无法通过改变路径或者文件名来引入新的,动态的图片。
    因此,在这里介绍两种方法,可以动态的引入图片,甚至包括更多的文件:
  • 使用require.context()
    1
    2
    3
    4
    5
    6
    7
    8
    // require.context(directory,useSubdirectories,regExp)
    // directory:表示检索的目录
    // useSubdirectories:表示是否检索子文件夹
    // regExp:匹配文件的正则表达式,一般是文件名
    const requireContext = require.context('../assets/QQpng', false, /\.(png|jpe?g|gif|svg)$/);

    // 获取images文件夹下的所有图片的base64文件文件名
    const images = requireContext.keys().map(requireContext);
    在上述代码中,他将会访问assets/QQpng下的所有文件,并通过正则表达式来获取其文件内容并保存到requireContext中,然后.map()是ES6的语法,可以获取数组中某个属性对应的值并将其重新组成数组。最后生成的images就是包含了所有base64编码的图片的原文件。
  • 使用public路径来保存内容,
    在public路径下的文件他不会经由webpack处理,可以直接通过访问路径来获取。因此可以通过简单的修改路径来完成文件的动态存储和使用。而要让vue使用到public文件夹下的内容。一般的操作可以通过public下,index.html种的一种写法来获取
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <!DOCTYPE html>
    <html lang="">
    <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>chat.svg">
    <title><%= htmlWebpackPlugin.options.title %></title>
    </head>
    <body>
    <noscript>
    <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
    </body>
    </html>
    其中的<%= BASE_URL %>就代表了public的路径,通过这个标签可以达到引入public路径下文件的效果。还有另一种。就是将public路径放到Vue的原型链上。这般便可以通过Vue示例来获取
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    import Vue from 'vue'
    import App from './App.vue'
    import VueRouter from 'vue-router'
    import router from './router'
    import axios from "axios";
    Vue.prototype.axios = axios
    Vue.config.productionTip = false
    //这里将public的路径保存使用
    Vue.prototype.publicPath = process.env.BASE_URL
    Vue.use(VueRouter)
    new Vue({
    router,
    render: h => h(App),
    beforeCreate() {
    Vue.prototype.$bus = this//安装全局事件总线
    }
    }).$mount('#app')
    然后直接通过Vue.prototype.publicPath搭配上具体的地址就可以直接跳过webpack动态使用图片了
  1. 有些事件只有在全部元素渲染完成后才能执行,所以引入该方法。
    1
    2
    3
    4
    5
    this.$nextTick(() => {
    // 可以使用回调函数的写法
    // 这个函数中DOM必定渲染完成
    this.$refs["input-box"].focus()
    })
  2. 关于光标的一些操作方法,这里只做示例演示,不细讲
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    //处理表情包的发送
    sendEmotion(index){
    if(this.chatPartnerName!=='请选择聊天对象'){
    //额外需要操作,需要获取光标的位置并且添加完图片后光标保持在表情后面。

    //获取光标选中的内容(如果光标有选中的内容,即删除掉)
    let content = getSelection()
    content.deleteFromDocument()
    //控制光标位置并添加表情
    let position = getSelection().getRangeAt(0)
    //如果没有光标
    if(position==""){
    //强制获取光标
    var div = this.$refs["input-box"]
    div.focus()
    position = getSelection().getRangeAt(0)
    }
    var img = document.createElement("img")
    img.style="width: 35px;"
    img.src=this.emotions[index]
    //在光标后添加表情
    position.insertNode(img)
    //将光标重新定位到表情后面
    position.setStartAfter(img)
    this.handleInput()
    }
    },