Reaccionar al applet WeChat: mecanismo de plantilla dual, React.template proporciona datos para el applet

Este es el último artículo de esta serie, porque se mantendrá en secreto en el futuro. Pero este artículo revelará algunas ideas muy útiles. El applet bloquea la posibilidad de manipular el DOM y no nos permite manipular la vista. No se puede tocar todo lo relacionado con la vista. Y su componente personalizado es muy desagradable, básicamente no merece ser llamado componente, y no puede heredar lo que se llama componente. Por lo tanto, utilizamos su tecnología de plantilla dinámica anterior, plantilla.

Mi idea es la siguiente: al compilar el método de representación del componente, el componente personalizado dentro se convierte en la clase de plantilla y luego se inicializa en la clase de plantilla para obtener accesorios, estados y luego pasarlo a la plantilla original. En otras palabras, hay dos conjuntos de plantillas.

//源码
import { Page } from "../wechat";
import "./page.css";
import Dog from "../components/dog/dog";
const e = "e";
class P extends Page {
  constructor(props) {
    super(props);
    this.state = {
      name: 'hehe',
      array: [
        {name: "dog1",text: "text1"},
        {name: "dog2",text: "text2"},
        {name: "dog3",text: "text3"},
      ]
    };
  }

  onClick() {
    console.log("test click1" + e);
  }
  render() {
    return (
      <div>
        <div>
          {this.state.array.map(function(el) {
            return <Dog name={el.name}>{el.text}</Dog>;
          })}
        </div>
        <Dog name={this.state.name} />
      </div>
    );
  }
}
export default P;

No nos importa cómo se ve el componente Perro primero.
Para que sea compatible con los applets y la función de procesamiento de React, necesitamos transformar el procesamiento. Transforme Dog, div, etc. en un tipo que los programas pequeños puedan reconocer, como

 <view>
    <view>
      {this.state.array.map(function(el) {
        return <template is={Dog} name={el.name}>{el.text}</template>;
      })}
    </view>
    <template is="Dog" name={this.state.name} />
  </view>

Cómo lograr esta traducción, podemos pasar una sintaxis de complemento-jsx, atravesará las etiquetas abiertas JSX, etiquetas cerradas, atributos y {}contenedores en el visitante .

clipboard.png

Pero React no puede reconocer la etiqueta de la plantilla, por lo que debe modificarse

//React专用
 <view>
    <view>
      {this.state.array.map(function(el) {
        return <React.template is={Dog} name={el.name}>{el.text}</React.template>;
      })}
    </view>
    <React.template is={Dog} name={this.state.name} />
  </view>

Ahora mirando el applet, el
applet no puede reconocer {}, y necesita ser cambiado a wx: para instrucciones

//小程序专用
 <view>
    <view>
      <block wx:for="{{this.state.array}}" wx:for-item="el">
         <template is="Dog" name={el.name}>{el.text}</template>;
      </block>
    </view>
    <template is="Dog" name={this.state.name} />
  </view>

Hay una deficiencia en la plantilla del applet. No puede reconocer el atributo como nombre, por lo que necesitamos algo para contenerlo. Así que creemos una matriz dinámicamente, cambie el lado Reaccionar

//React专用
 <view>
    <view>
      {this.state.array.map(function(el) {
        return <React.template is={Dog} name={el.name} templatedata="data123124342">{el.text}</React.template>;
      })}
    </view>
    <React.template is={Dog} name={this.state.name} templatedata="data34343433" />
  </view>

Babel crea el atributo templatedata y su valor en tiempo de compilación. React.template agregará una matriz data123124342 a this.data.state en ese momento, y el contenido es un objeto. Composición del estado. La estructura es probablemente {props: {}, estado: {}}
por lo que la plantilla del pequeño programa se convierte en

//小程序专用
<import src="../../components/dog/dog.wxml" />
 <view>
     <view>
      <block wx:for="{{this.state.array}}" wx:for-item="el">
         <template is="Dog" wx:for="data123124342" wx:for-item="data" data="{{...data}}"></template>;
      </block>
    </view>
    <template is="Dog" wx:for="data34343433" wx:for-item="data" data="{{...data}}" />
  </view>

Y nuestro renderizado se compila en ()

import { Page } from "../wechat";
import "./page.css";
import Dog from "../components/dog/dog";
const e = "e";
class P extends Page {
  constructor(props) {
    super(props);
    this.state = {
      name: 'hehe',
      array: [
        {name: "dog1",text: "text1"},
        {name: "dog2",text: "text2"},
        {name: "dog3",text: "text3"},
      ]
    };
  }

  onClick() {
    console.log("test click1" + e);
  }
  render() {
    return (
      React.createElement(
          "div",
          null,
          React.createElement(
            "div",
            null,
            this.state.array.map(function(el) {
              return React.createElement(React.template, {
                name: el.name,
                children: el.text,
                is: Dog,
                templatedata:"data34343433"
              });
            })
          ),
          React.createElement(React.template, {
            is: Dog,
            name: this.state.name,
            templatedata:"data34343433"
          })
        );
}
export default P;

El trabajo de traducción anterior se puede lograr a través del complemento transform-react-jsx babel

class P extends PageDe esta manera, es6 define las clases, los applets pueden no reconocerlo o es demasiado complicado después de ser compilado por Babel. Por ejemplo, taro convierte la clase Dog en esto:

clipboard.png

Por lo tanto, es mejor que proporcionemos un método para definir una clase en React, llamado miniCreateClass. De esta manera, podemos convertir al perro de manera muy concisa

var React = require("../../wechat");
var Component = React.Component
var miniCreatClass = React.miniCreatClass

function Dog() {}

let Dog = miniCreatClass(Dog, Component, {
  render: function () {
    return React.createElement("view", null, this.state.name )
  }
}, {});
module.exports.default = Dog;

Miremos la clase de la página nuevamente. La página de definición de applet se implementa a través de la fábrica de páginas, presumiblemente Page({data: {}}). El pequeño programa aquí es muy conveniente para que podamos hackear, porque solo habrá una instancia de una clase de Página.

Page(createPage(P))

Mire la implementación de createPage:

function createPage(PageClass) {
  var instance = ReactDOM.render(React.createElement(PageClass), {
    type: "div",
    root: true
  });
  var config = {
    data: {
      state: instance.state,
      props: instance.props
    },
    onLoad: function() {
      instance.$wxPage = this;
    },
    onUnload: function() {
      instance.componentWillUnmount && instance.componentWillUnmount();
    }
  };
  instance.allTemplateData.forEach(function(el) {
    if (config.data[el.templatedata]) {
      config.data[el.templatedata].push(el);
    }else{
      config.data[el.templatedata] = [el];
    }
  });
  return config;
}

Finalmente, la implementación de React.template, que se encarga de reunir los datos en la plantilla, esta plantilla es la etiqueta del applet.

React.template = function(props){
//这是一个无状态组件,负责劫持用户传导下来的类,修改它的原型
   var clazz = props.is;
   var a = classzz.prototype;
   var componentWillMount = a.componentWillMount;
   a.componentWillMount = function(){
    
     var ref = this._reactInternalRef;
     var arr = ref._owner.allTemplateData || (ref._owner.allTemplateData = []);
     arr.push({
       props: this.props,
       state: this.state,
       templatedata: props.templatedata
     })
     componentWillMount && componentWillMount.call(this)
   }
  var componentWillUpdate = a.componentWillUpdate;
   //...再上面一样
   return React.createElement(clazz, props)
}

Bueno, mi plan se presenta aquí. Si alguien está dispuesto a comenzar esto conmigo, búscame en github.

Supongo que te gusta

Origin www.cnblogs.com/baimeishaoxia/p/12707339.html
Recomendado
Clasificación